Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP's json_encode does not escape all JSON control characters

Tags:

json

php

Is there any reasons why PHP's json_encode function does not escape all JSON control characters in a string?

For example let's take a string which spans two rows and has control characters (\r \n " / \) in it:

<?php $s = <<<END First row. Second row w/ "double quotes" and backslash: \. END;  $s = json_encode($s); echo $s; // Will output: "First row.\r\nSecond row w\/ \"double quotes\" and backslash: \\." ?> 

Note that carriage return and newline chars are unescaped. Why?

I'm using jQuery as my JS library and it's $.getJSON() function will do fine when you fully, 100% trust incoming data. Otherwise I use JSON.org's library json2.js like everybody else. But if you try to parse that encoded string it throws an error:

<script type="text/javascript">  JSON.parse(<?php echo $s ?>);  // Will throw SyntaxError   </script> 

And you can't get the data! If you remove or escape \r \n " and \ in that string then JSON.parse() will not throw error.

Is there any existing, good PHP function for escaping control characters. Simple str_replace with search and replace arrays will not work.

like image 381
Gustav Avatar asked Jun 26 '09 10:06

Gustav


People also ask

How do I escape a character in JSON?

In JSON the only characters you must escape are \, ", and control codes. Thus in order to escape your structure, you'll need a JSON specific function. As you might know, all of the escapes can be written as \uXXXX where XXXX is the UTF-16 code unit¹ for that character.

How escape JSON PHP quotes?

To escape single quotes, use json_encode() to echo arrays in HTML5 data attributes.

What does the PHP function json_encode () do?

The json_encode() function is used to encode a value to JSON format.


2 Answers

function escapeJsonString($value) {     # list from www.json.org: (\b backspace, \f formfeed)         $escapers =     array("\\",     "/",   "\"",  "\n",  "\r",  "\t", "\x08", "\x0c");     $replacements = array("\\\\", "\\/", "\\\"", "\\n", "\\r", "\\t",  "\\f",  "\\b");     $result = str_replace($escapers, $replacements, $value);     return $result;   } 

I'm using the above function which escapes a backslash (must be first in the arrays) and should deal with formfeeds and backspaces (I don't think \f and \b are supported in PHP).

like image 107
Peter Whitefield Avatar answered Sep 19 '22 11:09

Peter Whitefield


D'oh - you need to double-encode: JSON.parse is expecting a string of course:

<script type="text/javascript">  JSON.parse(<?php echo json_encode($s) ?>);  </script> 
like image 28
Greg Avatar answered Sep 20 '22 11:09

Greg