How can I properly parse a string sent over GET through ajax that has been parsed through encodeURIComponent?

Here is it on the JS side

ajax('throb','save_file.php?f=<?=$_GET['f']?>&c=' + encodeURIComponent(editor.getValue()),"GET");

editor.getValue() in this case is a codemirror instantiation. I’m not sure if this complicates matters further. The reason for using encodeURIComponent was to properly send linebreaks over GET. This appears to work, but on the PHP side:

file_put_contents($_GET['f'],urldecode($_GET['c']));

unforunately this gives me a file that looks like this (example is my robots.txt file)

User-agent: *\nDisallow: /\n

When it should look like this:

User-agent: *
Disallow: /

Any ideas?

There’s a note on the documentation page for php urldecode() that says:

"Warning : The superglobals $_GET and $_REQUEST are already decoded. Using urldecode() on an element in $_GET or $_REQUEST could have unexpected and dangerous results. "

That suggests to me that you should drop the urldecode() from the code.

1 Like

Unfortunately it outputs the same thing with or without urldecode. It may have something to do with how codemirror is writing out line breaks.

As @droopsnoot mentioned, all input superglobals in PHP are already url decoded so you don’t have to do it yourself, however in most cases when you use urldecode() - that is decode the value twice - the string will be the same. Sometimes, depending on the contents, it can be different so you should definitely get rid of urldecode() in your PHP code.

Yes, this seems to be correct as you wrote you were getting this:

\n for line breaks is not url encoding, url encoding is done with the percent sign and a hexadecimal code value so urldecode() is not going to help you. This looks like javascript string escaping so you should be fine using a function that will simply replace the escaped sequences with actual characters:

$decoded = strtr($_GET['c'], [
    '\n' => "\n",
    '\r' => "\r",
    '\t' => "\t",
]);

or treating the input as JSON string might also work:

$decoded = json_decode('"'.$_GET['c'].'"');

Which method will be best depends on how other special characters might be encoded from the external source.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.