Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.870 diff -u -9 -p -r1.870 common.inc --- includes/common.inc 28 Feb 2009 07:36:06 -0000 1.870 +++ includes/common.inc 15 Mar 2009 23:17:06 -0000 @@ -232,32 +232,32 @@ function drupal_get_feeds($delimiter = " * @param $parent * Should not be passed, only used in recursive calls. * @return * An urlencoded string which can be appended to/as the URL query string. */ function drupal_query_string_encode($query, $exclude = array(), $parent = '') { $params = array(); foreach ($query as $key => $value) { - $key = drupal_urlencode($key); + $key = rawurlencode($key); if ($parent) { $key = $parent . '[' . $key . ']'; } if (in_array($key, $exclude)) { continue; } if (is_array($value)) { $params[] = drupal_query_string_encode($value, $exclude, $key); } else { - $params[] = $key . '=' . drupal_urlencode($value); + $params[] = $key . '=' . rawurlencode($value); } } return implode('&', $params); } /** * Prepare a destination query string for use in combination with drupal_goto(). * @@ -1609,20 +1609,20 @@ function format_date($timestamp, $type = * Generate a URL from a Drupal menu path. Will also pass-through existing URLs. * * @param $path * The Drupal path being linked to, such as "admin/content/node", or an * existing URL like "http://drupal.org/". The special path * '' may also be given and will generate the site's base URL. * @param $options * An associative array of additional options, with the following keys: * - 'query' - * A query string to append to the link, or an array of query key/value - * properties. + * A URL-encoded query string to append to the link, or an array of query + * key/value-pairs without any URL-encoding. * - 'fragment' * A fragment identifier (or named anchor) to append to the link. * Do not include the '#' character. * - 'absolute' (default FALSE) * Whether to force the output to be an absolute link (beginning with * http:). Useful for links that will be displayed outside the site, such * as in an RSS feed. * - 'alias' (default FALSE) * Whether the given path is an alias already. @@ -2833,18 +2833,20 @@ function drupal_json($var = NULL) { * * Notes: * - For esthetic reasons, we do not escape slashes. This also avoids a 'feature' * in Apache where it 404s on any path containing '%2F'. * - mod_rewrite unescapes %-encoded ampersands, hashes, and slashes when clean * URLs are used, which are interpreted as delimiters by PHP. These * characters are double escaped so PHP will still see the encoded version. * - With clean URLs, Apache changes '//' to '/', so every second slash is * double escaped. + * - This function should not be used on query strings or URLs that contain + * query strings, otherwise unwanted double encoding will occur. * * @param $text * String to encode */ function drupal_urlencode($text) { if (variable_get('clean_url', '0')) { return str_replace(array('%2F', '%26', '%23', '//'), array('/', '%2526', '%2523', '/%252F'), rawurlencode($text)); Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.698 diff -u -9 -p -r1.698 comment.module --- modules/comment/comment.module 14 Mar 2009 23:01:36 -0000 1.698 +++ modules/comment/comment.module 15 Mar 2009 23:17:07 -0000 @@ -1872,22 +1872,22 @@ function theme_comment_post_forbidden($n // We only output any link if we are certain, that users get permission // to post comments by logging in. We also locally cache this information. $authenticated_post_comments = array_key_exists(DRUPAL_AUTHENTICATED_RID, user_roles(TRUE, 'post comments') + user_roles(TRUE, 'post comments without approval')); } if ($authenticated_post_comments) { // We cannot use drupal_get_destination() because these links // sometimes appear on /node and taxonomy listing pages. if (variable_get('comment_form_location_' . $node->type, COMMENT_FORM_SEPARATE_PAGE) == COMMENT_FORM_SEPARATE_PAGE) { - $destination = 'destination=' . drupal_urlencode("comment/reply/$node->nid#comment-form"); + $destination = 'destination=' . rawurlencode("comment/reply/$node->nid#comment-form"); } else { - $destination = 'destination=' . drupal_urlencode("node/$node->nid#comment-form"); + $destination = 'destination=' . rawurlencode("node/$node->nid#comment-form"); } if (variable_get('user_register', 1)) { // Users can register themselves. return t('Login or register to post comments', array('@login' => url('user/login', array('query' => $destination)), '@register' => url('user/register', array('query' => $destination)))); } else { // Only admins can add new users, no public registration. return t('Login to post comments', array('@login' => url('user/login', array('query' => $destination)))); Index: modules/search/search.test =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.test,v retrieving revision 1.16 diff -u -9 -p -r1.16 search.test --- modules/search/search.test 8 Mar 2009 05:16:20 -0000 1.16 +++ modules/search/search.test 15 Mar 2009 23:17:07 -0000 @@ -260,23 +260,23 @@ class SearchAdvancedSearchForm extends D */ function testNodeType() { $this->assertTrue($this->node->type == 'page', t('Node type is page.')); // Assert that the dummy title doesn't equal the real title. $dummy_title = 'Lorem ipsum'; $this->assertNotEqual($dummy_title, $this->node->title, t("Dummy title doens't equal node title")); // Search for the dummy title with a GET query. - $this->drupalGet('search/node/' . drupal_urlencode($dummy_title)); + $this->drupalGet('search/node/' . $dummy_title); $this->assertNoText($this->node->title, t('Page node is not found with dummy title.')); // Search for the title of the node with a GET query. - $this->drupalGet('search/node/' . drupal_urlencode($this->node->title)); + $this->drupalGet('search/node/' . $this->node->title); $this->assertText($this->node->title, t('Page node is found with GET query.')); // Search for the title of the node with a POST query. $edit = array('or' => $this->node->title); $this->drupalPost('search/node', $edit, t('Advanced search')); $this->assertText($this->node->title, t('Page node is found with POST query.')); // Advanced search type option. $this->drupalPost('search/node', array_merge($edit, array('type[page]' => 'page')), t('Advanced search')); Index: modules/system/system.js =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.js,v retrieving revision 1.20 diff -u -9 -p -r1.20 system.js --- modules/system/system.js 13 Mar 2009 23:15:09 -0000 1.20 +++ modules/system/system.js 15 Mar 2009 23:17:07 -0000 @@ -105,19 +105,19 @@ Drupal.behaviors.dateTime = { attach: function(context, settings) { // Show/hide custom format depending on the select's value. $('select.date-format:not(.date-time-processed)', context).change(function() { $(this).addClass('date-time-processed').parents("div.date-container").children("div.custom-container")[$(this).val() == "custom" ? "show" : "hide"](); }); // Attach keyup handler to custom format inputs. $('input.custom-format:not(.date-time-processed)', context).addClass('date-time-processed').keyup(function() { var input = $(this); - var url = settings.dateTime.lookup +(settings.dateTime.lookup.match(/\?q=/) ? "&format=" : "?format=") + Drupal.encodeURIComponent(input.val()); + var url = settings.dateTime.lookup +(settings.dateTime.lookup.match(/\?q=/) ? "&format=" : "?format=") + encodeURIComponent(input.val()); $.getJSON(url, function(data) { $("div.description span", input.parent()).html(data); }); }); // Trigger the event handler to show the form input if necessary. $('select.date-format', context).trigger('change'); } }; @@ -128,10 +128,10 @@ Drupal.behaviors.dateTime = { Drupal.behaviors.poweredByPreview = { attach: function(context, settings) { $('#edit-color, #edit-size').change(function() { var path = settings.basePath + 'misc/' + $('#edit-color').val() + '-' + $('#edit-size').val() + '.png'; $('img.powered-by-preview').attr('src', path); }); } }; -})(jQuery); \ No newline at end of file +})(jQuery); Index: modules/update/update.fetch.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/update/update.fetch.inc,v retrieving revision 1.16 diff -u -9 -p -r1.16 update.fetch.inc --- modules/update/update.fetch.inc 14 Mar 2009 23:01:37 -0000 1.16 +++ modules/update/update.fetch.inc 15 Mar 2009 23:17:07 -0000 @@ -81,22 +81,22 @@ function _update_build_fetch_url($projec if (!isset($project['info']['project status url'])) { $project['info']['project status url'] = $default_url; } $name = $project['name']; $url = $project['info']['project status url']; $url .= '/' . $name . '/' . DRUPAL_CORE_COMPATIBILITY; if (!empty($site_key)) { $url .= (strpos($url, '?') === TRUE) ? '&' : '?'; $url .= 'site_key='; - $url .= drupal_urlencode($site_key); + $url .= rawurlencode($site_key); if (!empty($project['info']['version'])) { $url .= '&version='; - $url .= drupal_urlencode($project['info']['version']); + $url .= rawurlencode($project['info']['version']); } } return $url; } /** * Perform any notifications that should be done once cron fetches new data. * * This method checks the status of the site using the new data and depending