drupal_query_string_encode() should not call drupal_urlencode()

fonant - September 18, 2008 - 09:01
Project:Drupal
Version:5.x-dev
Component:base system
Category:bug report
Priority:normal
Assigned:Unassigned
Status:patch (to be ported)
Issue tags:test case
Description

The query string should be encoded using rawurlencode() and not drupal_urlencode(). The latter causes double-encoding of the query string contents, which is not needed: the double-encoding is only needed for clean URLs due to issues with apache's mod_rewrite, and these issues don't affect the query string part of the page request.

Related issues:
http://drupal.org/node/178615 - includes the double-encoding problem, proposes a fix by making drupal_urlencode() more complex.
http://drupal.org/node/74070 - an old "fix" that I think was wrong, or is now wrong, and needs undoing.
http://drupal.org/node/301192 - workaround for the same bug, as found in the Printer module.

Note: the only place that drupal_urlencode() is called (correctly) from core is within the url() function. It might make sense to remove the drupal_urlencode() function and move its contents into url(). This would remove the temptation to call it from inappropriate places. Contributed modules should use url() to construct encoded URLs.

#1

fonant - September 18, 2008 - 09:09

Here's the very simple patch needed to fix the double-encoding problem.

AttachmentSize
query_string_encode.patch 882 bytes
Testbed results
query_string_encode.patchfailedFailed: Failed to apply patch. Detailed results

#2

fonant - September 18, 2008 - 09:16

Here's an improved patch, including a comment within the drupal_urlencode() description to warn that the function shouldn't be used for query strings.

(For some reason diff thinks the change is in drupal_json(), but it isn't).

AttachmentSize
query_string_encode.patch 1.29 KB
Testbed results
query_string_encode.patchfailedFailed: Failed to apply patch. Detailed results

#3

Damien Tournoud - September 18, 2008 - 09:47
Version:6.4» 7.x-dev
Status:active» needs work

Ok, please remove drupal_urlencode().

Also this will need to go to the current development branch (Drupal 7.x), and we will need to write a complete test case for this.

#4

fonant - September 18, 2008 - 20:06

Here's a patch for HEAD (1.797), not much different apart from the additional space in string concatenation on the second changed line. Hopefully I'm doing this correctly - I'm new to getting involved with Drupal core (I've been coding sites with Drupal 5 and 6 for a year or so now).

This just corrects query_string_encode(), leaving drupal_urlencode() as a callable function. I suspect there's a whole separate discussion needed as to whether drupal_urlencode() is redundant (and dangerous?) - unless by "please remove" you mean get rid of the function too?

Now I just need to investigate writing test cases! I found the problem with data in a query string and the standard Drupal sortable tables (which use drupal_query_string_encode() to generate the sort links in the headers).

AttachmentSize
query_string_encode.patch 1.28 KB
Testbed results
query_string_encode.patchfailedFailed: Invalid PHP syntax in includes/common.inc . Detailed results

#5

fonant - September 19, 2008 - 13:00

Here's another patch, with fixes for some other places where drupal_urlencode() is called on query strings.

I've also improved the function documentation for url() to make it clear when the query optional argument should be urlencoded or not. [I've a feeling the argument should never be encoded, but that would seem to be a fairly big task to change everywhere that calls url() with a pre-encoded and non-array query option.]

Not sure about the two remaining places where this sort of thing happens:

1) misc/drupal.js has a copy of drupal_urlencode(). We might also need to investigate usage of encodeURIComponent() in javascript code, to check it isn't being used on query strings.

2) modules/search/search.test uses drupal_urlencode(), but I don't know if drupalGet() also does encoding...

AttachmentSize
drupal_urlencode_usage.patch 3.71 KB
Testbed results
drupal_urlencode_usage.patchfailedFailed: Failed to install HEAD. Detailed results

#6

c960657 - September 19, 2008 - 21:56

Now that Drupal 7 requires PHP5, I think that drupal_query_string_encode() can be simplified a lot by using http_build_query().

#7

c960657 - March 7, 2009 - 23:14
Status:needs work» needs review

The patch looks good.

You are right about both points in #5.
1) The problem with drupal.js can be seen on the page admin/settings/date-time: Select “Custom format” and add "//" to the text field. Note how the example date below the field looks wrong.
2) It's true that drupalGet() encodes the path (via url()), so the drupal_encode() call can simply be removed. Your can verify the problem by modifying drupal_web_test_case::drupalCreateNode() to include some special characters in the node title.

I fixed these two things.

AttachmentSize
drupal_urlencode-2.patch 9.69 KB
Testbed results
drupal_urlencode-2.patchfailedFailed: Failed to apply patch. Detailed results

#8

System Message - March 14, 2009 - 01:15
Status:needs review» needs work

The last submitted patch failed testing.

#9

c960657 - March 15, 2009 - 23:18
Status:needs work» needs review

Reroll.

AttachmentSize
drupal_urlencode-3.patch 10.09 KB
Testbed results
drupal_urlencode-3.patchfailedFailed: Failed to apply patch. Detailed results

#10

System Message - April 5, 2009 - 06:15
Status:needs review» needs work

The last submitted patch failed testing.

#11

c960657 - April 20, 2009 - 22:05
Status:needs work» needs review

Reroll.

AttachmentSize
drupal_urlencode-4.patch 9.68 KB
Testbed results
drupal_urlencode-4.patchfailedFailed: Failed to apply patch. Detailed results

#12

Gábor Hojtsy - April 22, 2009 - 06:46

Just marked the issue submitted at #298498: Drupal assumes mod_rewrite bugs which are not there a duplicate of this one. That involves the JS Drupal.encodeURIComponent() usage of which breaks URLs in l10n_client. Unfortunately when implementing the encoding code for l10n_client, I've followed the usage of Drupal.encodeURIComponent() from system.js, which turns out is bugos. This bugfix should also be backported to Drupal 6!

I'd also ask for a little doc update to Drupal.encodeURIComponent() to mention that it should not be used on URL components other then the path.

#13

Pedro Lozano - April 22, 2009 - 12:05

Subscribing, I found this today in a site, especial characters in query values encoded twice.

#14

c960657 - April 25, 2009 - 20:09

I renamed Drupal.encodeURIComponent() to Drupal.urlencode() to emphasize that it is closer related to drupal_urlencode() than to JavaScript's built-in encodeURIComponent(), and added a comment about its usage.

See also #284899: Drupal url problem with clean urls that suggests another workaround for the mod_rewrite limitation that eliminates the need to use different functions for encoding the path and the query string.

AttachmentSize
drupal_urlencode-5.patch 11.92 KB
Testbed results
drupal_urlencode-5.patchfailedFailed: Failed to apply patch. Detailed results

#15

System Message - April 26, 2009 - 21:40
Status:needs review» needs work

The last submitted patch failed testing.

#16

c960657 - April 26, 2009 - 22:35
Status:needs work» needs review

Reroll.

AttachmentSize
drupal_urlencode-6.patch 11.91 KB
Testbed results
drupal_urlencode-6.patchfailedFailed: Failed to apply patch. Detailed results

#17

fago - April 27, 2009 - 15:23

>The latter causes double-encoding of the query string content.

Have a look at the related issue #385918: destination parameter gets two times urlencoded.
As I've noted there I think it gets double-encoded because it calls drupal_url_encode/url_encode twice on it.

#18

c960657 - April 27, 2009 - 22:40
AttachmentSize
drupal_urlencode-7.patch 11.92 KB
Testbed results
drupal_urlencode-7.patchfailedFailed: Failed to apply patch. Detailed results

#19

Arancaytar - May 22, 2009 - 07:46
Status:needs review» needs work

The patch looks great. Now we just need a test case! :)

#20

c960657 - June 5, 2009 - 16:56
Status:needs work» needs review

I added a few tests. I added them to the class that already contains the tests for l(), as the functions seem related. Future tests for url() may be added to this class too.

AttachmentSize
drupal_urlencode-8.patch 14.45 KB
Testbed results
drupal_urlencode-8.patchfailedFailed: Failed to apply patch. Detailed results

#21

System Message - June 6, 2009 - 18:20
Status:needs review» needs work

The last submitted patch failed testing.

#22

c960657 - June 6, 2009 - 18:29
Status:needs work» needs review

Reroll.

AttachmentSize
drupal_urlencode-9.patch 14.39 KB
Testbed results
drupal_urlencode-9.patchfailedFailed: Failed to apply patch. Detailed results

#23

System Message - June 13, 2009 - 13:01
Status:needs review» needs work

The last submitted patch failed testing.

#24

c960657 - June 14, 2009 - 09:01
Status:needs work» needs review

Reroll.

AttachmentSize
drupal_urlencode-10.patch 14.4 KB
Testbed results
drupal_urlencode-10.patchfailedFailed: Failed to apply patch. Detailed results

#25

Damien Tournoud - June 14, 2009 - 10:16
Status:needs review» needs work

Let's rename drupal_urlencode() to drupal_encode_path(), and stop the confusion. The patch itself looks good.

#26

c960657 - June 14, 2009 - 10:49

Renamed drupal_urlencode() to drupal_encode_path(), and the JS function Drupal.urlencode() to Drupal.encodePath().

This should be added to the upgrade docs before this bug is marked as fixed.

AttachmentSize
drupal_urlencode-11.patch 15.27 KB
Testbed results
drupal_urlencode-11.patchfailedFailed: Failed to apply patch. Detailed results

#27

c960657 - June 14, 2009 - 10:59
Status:needs work» needs review

#28

Damien Tournoud - June 14, 2009 - 11:24
Status:needs review» reviewed & tested by the community

Nice! Let's get this in.

#29

System Message - June 17, 2009 - 12:00
Status:reviewed & tested by the community» needs work

The last submitted patch failed testing.

#30

lilou - June 17, 2009 - 12:26
Status:needs work» reviewed & tested by the community

HEAD is broken : http://testing.drupal.org/node/35

#31

pwolanin - July 1, 2009 - 13:34

I'm ready to roll a D6 backport as soon as this goes in.

#32

System Message - July 1, 2009 - 14:00
Status:reviewed & tested by the community» needs work

The last submitted patch failed testing.

#33

pwolanin - July 1, 2009 - 17:45

testbot is right - patch does not apply. Re-rolling

#34

pwolanin - July 1, 2009 - 18:15
Status:needs work» needs review

re-rolled - must have just been whitespace changes.

AttachmentSize
drupal_urlencode-310139-34.patch 10.28 KB
Testbed results
drupal_urlencode-310139-34.patchpassedPassed: 11574 passes, 0 fails, 0 exceptions Detailed results

#35

Damien Tournoud - July 3, 2009 - 14:46
Status:needs review» reviewed & tested by the community

Makes complete sense, the test bot it happy, let's get this in.

#36

Dries - July 3, 2009 - 19:22
Status:reviewed & tested by the community» fixed

This makes sense indeed. Committed.

#37

pwolanin - July 10, 2009 - 02:21
Version:7.x-dev» 6.x-dev
Status:fixed» patch (to be ported)

getting ready to backport minus the function name changes.

#38

pwolanin - July 12, 2009 - 21:29
Status:patch (to be ported)» needs review
AttachmentSize
drupal_urlencode-310139-38-D6.patch 5.5 KB

#40

c960657 - July 18, 2009 - 12:20
Status:needs review» reviewed & tested by the community

Looks good.

#41

Gábor Hojtsy - July 21, 2009 - 08:59
Status:reviewed & tested by the community» fixed

Committed to Drupal 6, thanks!

#42

pwolanin - July 21, 2009 - 15:06
Version:6.x-dev» 5.x-dev
Status:fixed» patch (to be ported)

backport for D5?

http://api.drupal.org/api/function/drupal_query_string_encode/5

 
 

Drupal is a registered trademark of Dries Buytaert.