Commit d02681af authored by Dries's avatar Dries

- Fixed problems with filter formats and problem with XML-RPC server.

parent e3260447
...@@ -66,12 +66,6 @@ ...@@ -66,12 +66,6 @@
$xmlrpcArray => 2, $xmlrpcArray => 2,
$xmlrpcStruct => 3); $xmlrpcStruct => 3);
$xmlEntities=array( "amp" => "&",
"quot" => '"',
"lt" => "<",
"gt" => ">",
"apos" => "'");
$xmlrpcerr["unknown_method"]=1; $xmlrpcerr["unknown_method"]=1;
$xmlrpcstr["unknown_method"]="Unknown method"; $xmlrpcstr["unknown_method"]="Unknown method";
$xmlrpcerr["invalid_return"]=2; $xmlrpcerr["invalid_return"]=2;
...@@ -97,9 +91,6 @@ ...@@ -97,9 +91,6 @@
// let XML parse errors start at 100 // let XML parse errors start at 100
$xmlrpcerrxml=100; $xmlrpcerrxml=100;
// formulate backslashes for escaping regexp
$xmlrpc_backslash=chr(92).chr(92);
// used to store state during parsing // used to store state during parsing
// quick explanation of components: // quick explanation of components:
// st - used to build up a string for evaluation // st - used to build up a string for evaluation
...@@ -114,36 +105,6 @@ ...@@ -114,36 +105,6 @@
$_xh=array(); $_xh=array();
function xmlrpc_entity_decode($string) {
$top=split("&", $string);
$op="";
$i=0;
while($i<sizeof($top)) {
if (ereg("^([#a-zA-Z0-9]+);", $top[$i], $regs)) {
$op.=ereg_replace("^[#a-zA-Z0-9]+;",
xmlrpc_lookup_entity($regs[1]),
$top[$i]);
} else {
if ($i==0)
$op=$top[$i];
else
$op.="&" . $top[$i];
}
$i++;
}
return $op;
}
function xmlrpc_lookup_entity($ent) {
global $xmlEntities;
if (isset($xmlEntities[strtolower($ent)]))
return $xmlEntities[strtolower($ent)];
if (ereg("^#([0-9]+)$", $ent, $regs))
return chr($regs[1]);
return "?";
}
function xmlrpc_se($parser, $name, $attrs) { function xmlrpc_se($parser, $name, $attrs) {
global $_xh, $xmlrpcDateTime, $xmlrpcString; global $_xh, $xmlrpcDateTime, $xmlrpcString;
...@@ -242,9 +203,9 @@ function xmlrpc_ee($parser, $name) { ...@@ -242,9 +203,9 @@ function xmlrpc_ee($parser, $name) {
case "BASE64": case "BASE64":
if ($_xh[$parser]['qt']==1) { if ($_xh[$parser]['qt']==1) {
// we use double quotes rather than single so backslashification works OK // we use double quotes rather than single so backslashification works OK
$_xh[$parser]['st'].="\"". $_xh[$parser]['ac'] . "\""; $_xh[$parser]['st'].="'". $_xh[$parser]['ac'] ."'";
} else if ($_xh[$parser]['qt']==2) { } else if ($_xh[$parser]['qt']==2) {
$_xh[$parser]['st'].="base64_decode('". $_xh[$parser]['ac'] . "')"; $_xh[$parser]['st'].="base64_decode('". $_xh[$parser]['ac'] ."')";
} else if ($name=="BOOLEAN") { } else if ($name=="BOOLEAN") {
$_xh[$parser]['st'].=$_xh[$parser]['ac']; $_xh[$parser]['st'].=$_xh[$parser]['ac'];
} else { } else {
...@@ -267,12 +228,12 @@ function xmlrpc_ee($parser, $name) { ...@@ -267,12 +228,12 @@ function xmlrpc_ee($parser, $name) {
// deal with a string value // deal with a string value
if (strlen($_xh[$parser]['ac'])>0 && if (strlen($_xh[$parser]['ac'])>0 &&
$_xh[$parser]['vt']==$xmlrpcString) { $_xh[$parser]['vt']==$xmlrpcString) {
$_xh[$parser]['st'].="\"". $_xh[$parser]['ac'] . "\""; $_xh[$parser]['st'].="'". $_xh[$parser]['ac'] . "'";
} }
// This if() detects if no scalar was inside <VALUE></VALUE> // This if() detects if no scalar was inside <VALUE></VALUE>
// and pads an empty "". // and pads an empty "".
if($_xh[$parser]['st'][strlen($_xh[$parser]['st'])-1] == '(') { if($_xh[$parser]['st'][strlen($_xh[$parser]['st'])-1] == '(') {
$_xh[$parser]['st'].= '""'; $_xh[$parser]['st'].= "''";
} }
$_xh[$parser]['st'].=", '" . $_xh[$parser]['vt'] . "')"; $_xh[$parser]['st'].=", '" . $_xh[$parser]['vt'] . "')";
if ($_xh[$parser]['cm']) $_xh[$parser]['st'].=","; if ($_xh[$parser]['cm']) $_xh[$parser]['st'].=",";
...@@ -311,7 +272,7 @@ function xmlrpc_ee($parser, $name) { ...@@ -311,7 +272,7 @@ function xmlrpc_ee($parser, $name) {
function xmlrpc_cd($parser, $data) function xmlrpc_cd($parser, $data)
{ {
global $_xh, $xmlrpc_backslash; global $_xh;
//if (ereg("^[\n\r \t]+$", $data)) return; //if (ereg("^[\n\r \t]+$", $data)) return;
// print "adding [${data}]\n"; // print "adding [${data}]\n";
...@@ -328,12 +289,23 @@ function xmlrpc_cd($parser, $data) ...@@ -328,12 +289,23 @@ function xmlrpc_cd($parser, $data)
} }
// replace characters that eval would // replace characters that eval would
// do special things with // do special things with
$_xh[$parser]['ac'].=str_replace('$', '\$', $_xh[$parser]['ac'].= xmlrpc_escape_php($data);
str_replace('"', '\"', str_replace(chr(92),
$xmlrpc_backslash, $data)));
} }
} }
/**
* Escapes a piece of text so it can be placed literally between single quotes
* as a string inside PHP code.
*
* A single slash is converted to a double slash, a single quote converted to
* a slash followed by a quote.
*/
function xmlrpc_escape_php($data) {
return str_replace(array('\\', "'"),
array('\\\\', "\\'"),
$data);
}
function xmlrpc_dh($parser, $data) function xmlrpc_dh($parser, $data)
{ {
global $_xh; global $_xh;
...@@ -342,9 +314,7 @@ function xmlrpc_dh($parser, $data) ...@@ -342,9 +314,7 @@ function xmlrpc_dh($parser, $data)
$_xh[$parser]['qt']=1; $_xh[$parser]['qt']=1;
$_xh[$parser]['lv']=2; $_xh[$parser]['lv']=2;
} }
$_xh[$parser]['ac'].=str_replace('$', '\$', $_xh[$parser]['ac'].= xmlrpc_escape_php($data);
str_replace('"', '\"', str_replace(chr(92),
$xmlrpc_backslash, $data)));
} }
} }
......
...@@ -246,7 +246,7 @@ function parseRequest($data="") { ...@@ -246,7 +246,7 @@ function parseRequest($data="") {
for($i=0; $i<sizeof($_xh[$parser]['params']); $i++) { for($i=0; $i<sizeof($_xh[$parser]['params']); $i++) {
//print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n"; //print "<!-- " . $_xh[$parser]['params'][$i]. "-->\n";
$plist.="$i - " . $_xh[$parser]['params'][$i]. " \n"; $plist.="$i - " . $_xh[$parser]['params'][$i]. " \n";
eval('$m->addParam(' . $_xh[$parser]['params'][$i]. ");"); $m->addParam(eval('return '. $_xh[$parser]['params'][$i] .';'));
} }
// uncomment this to really see what the server's getting! // uncomment this to really see what the server's getting!
// xmlrpc_debugmsg($plist); // xmlrpc_debugmsg($plist);
...@@ -265,13 +265,12 @@ function parseRequest($data="") { ...@@ -265,13 +265,12 @@ function parseRequest($data="") {
} }
if ( (!isset($dmap[$methName]['signature'])) if ( (!isset($dmap[$methName]['signature']))
|| $sr[0]) { || $sr[0]) {
$f = $dmap[$methName]['function'];
// if no signature or correct signature // if no signature or correct signature
if ($sysCall) { if ($sysCall) {
eval('$r=' . $dmap[$methName]['function'] . $r = $f($this, $m);
'($this, $m);');
} else { } else {
eval('$r=' . $dmap[$methName]['function'] . $r = $f($m);
'($m);');
} }
} else { } else {
$r=new xmlrpcresp(0, $r=new xmlrpcresp(0,
......
...@@ -503,8 +503,11 @@ function comment_preview($edit) { ...@@ -503,8 +503,11 @@ function comment_preview($edit) {
$comment->timestamp = time(); $comment->timestamp = time();
$comment->name = $user->name ? $user->name : $comment->name; $comment->name = $user->name ? $user->name : $comment->name;
// Preview the comment. // Preview the comment if there were no errors, including the 'The supplied input format is invalid.'
$output .= theme('comment_view', $comment, theme('links', module_invoke_all('link', 'comment', $comment, 1))); // error message, ie. this is a security check here.
if (!form_get_errors()) {
$output .= theme('comment_view', $comment, theme('links', module_invoke_all('link', 'comment', $comment, 1)));
}
$output .= theme('comment_form', $edit, t('Reply')); $output .= theme('comment_form', $edit, t('Reply'));
if ($edit['pid']) { if ($edit['pid']) {
...@@ -689,7 +692,7 @@ function comment_post($edit) { ...@@ -689,7 +692,7 @@ function comment_post($edit) {
} }
} }
else { else {
print theme('page', comment_preview($edit)); return comment_preview($edit);
} }
} }
else { else {
......
...@@ -553,13 +553,35 @@ function filter_list_format($format) { ...@@ -553,13 +553,35 @@ function filter_list_format($format) {
* @{ * @{
* Modules which need to have content filtered can use these functions to * Modules which need to have content filtered can use these functions to
* interact with the filter system. * interact with the filter system.
*
* For more info, see the hook_filter() documentation.
*
* Note: because filters can inject JavaScript or execute PHP code, security is
* vital here. When a user supplies a $format, you should validate it with
* filter_access($format) before accepting/using it. This is normally done in
* the validation stage of the node system. You should for example never make a
* preview of content in a disallowed format.
*/ */
/** /**
* Run all the enabled filters on a piece of text. * Run all the enabled filters on a piece of text.
*/ *
function check_output($text, $format = FILTER_FORMAT_DEFAULT) { * You can do a filter_access() check on $format automatically by passing
if (isset($text)) { * $check = TRUE. Note that this will check the permissions of the current user,
* so you should specify $check = FALSE when viewing other people's content.
*
* @param $text
* The text to be filtered.
* @param $format
* The format of the text to be filtered. Specify FILTER_FORMAT_DEFAULT for
* the default format.
* @param $check
* Whether to check the $format with filter_access() first. If set to false,
* make sure the check has performed at some point earlier.
*/
function check_output($text, $format = FILTER_FORMAT_DEFAULT, $check = FALSE) {
// When $check = true, do an access check on $format.
if (isset($text) && (!$check || filter_access($format))) {
if ($format == FILTER_FORMAT_DEFAULT) { if ($format == FILTER_FORMAT_DEFAULT) {
$format = variable_get('filter_default_format', 1); $format = variable_get('filter_default_format', 1);
} }
......
...@@ -472,6 +472,13 @@ function node_save($node) { ...@@ -472,6 +472,13 @@ function node_save($node) {
node_invoke($node, 'update'); node_invoke($node, 'update');
node_invoke_nodeapi($node, 'update'); node_invoke_nodeapi($node, 'update');
} }
// unset unused $node part so that a bad theme can not open a security hole
if ($teaser) {
unset($node->body);
}
else {
unset($node->teaser);
}
// Clear the cache so an anonymous poster can see the node being added or updated. // Clear the cache so an anonymous poster can see the node being added or updated.
cache_clear_all(); cache_clear_all();
...@@ -1330,15 +1337,17 @@ function node_preview($node) { ...@@ -1330,15 +1337,17 @@ function node_preview($node) {
} }
// Display a preview of the node: // Display a preview of the node:
if ($node->teaser && $node->teaser != $node->body) { if (!form_get_errors()) {
$output = '<h3>'. t('Preview trimmed version') .'</h3>'; if ($node->teaser && $node->teaser != $node->body) {
$output .= node_view($node, 1); $output = '<h3>'. t('Preview trimmed version') .'</h3>';
$output .= '<p><em>'. t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication. You can insert the delimiter "&lt;!--break--&gt;" (without the quotes) to fine-tune where your post gets split.') .'</em></p>'; $output .= node_view($node, 1);
$output .= '<h3>'. t('Preview full version') .'</h3>'; $output .= '<p><em>'. t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication. You can insert the delimiter "&lt;!--break--&gt;" (without the quotes) to fine-tune where your post gets split.') .'</em></p>';
$output .= node_view($node, 0); $output .= '<h3>'. t('Preview full version') .'</h3>';
} $output .= node_view($node, 0);
else { }
$output .= node_view($node, 0); else {
$output .= node_view($node, 0);
}
} }
$output .= node_form($node); $output .= node_form($node);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment