Skip to content

Commit

Permalink
Merge pull request zendframework#1837 from padraic/feature/zend_json-…
Browse files Browse the repository at this point in the history
…improvement

Zend\Json Improvements
  • Loading branch information
Freeaqingme committed Jul 11, 2012
2 parents eeb6c8a + d868171 commit ffb0188
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 10 deletions.
8 changes: 7 additions & 1 deletion library/Zend/Json/Decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,13 @@ public static function decodeUnicodeString($chrs)
// single, escaped unicode character
$utf16 = chr(hexdec(substr($chrs, ($i + 2), 2)))
. chr(hexdec(substr($chrs, ($i + 4), 2)));
$utf8 .= self::_utf162utf8($utf16);
$utf8char = self::_utf162utf8($utf16);
$search = array('\\', "\n", "\t", "\r", chr(0x08), chr(0x0C), '"', '\'', '/');
if (in_array($utf8char, $search)) {
$replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\\"', '\\\'', '\\/');
$utf8char = str_replace($search, $replace, $utf8char);
}
$utf8 .= $utf8char;
$i += 5;
break;
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
Expand Down
6 changes: 3 additions & 3 deletions library/Zend/Json/Encoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,10 @@ protected function _encodeDatum(&$value)
*/
protected function _encodeString(&$string)
{
// Escape these characters with a backslash:
// Escape these characters with a backslash or unicode escape:
// " \ / \n \r \t \b \f
$search = array('\\', "\n", "\t", "\r", "\b", "\f", '"', '/');
$replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"', '\\/');
$search = array('\\', "\n", "\t", "\r", "\b", "\f", '"', '\'', '&', '<', '>', '/');
$replace = array('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\\u0022', '\\u0027', '\\u0026', '\\u003C', '\\u003E', '\\/');
$string = str_replace($search, $replace, $string);

// Escape certain ASCII characters:
Expand Down
5 changes: 4 additions & 1 deletion library/Zend/Json/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,10 @@ public static function encode($valueToEncode, $cycleCheck = false, $options = ar

// Encoding
if (function_exists('json_encode') && self::$useBuiltinEncoderDecoder !== true) {
$encodedResult = json_encode($valueToEncode);
$encodedResult = json_encode(
$valueToEncode,
JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
);
} else {
$encodedResult = Encoder::encode($valueToEncode, $cycleCheck, $options);
}
Expand Down
65 changes: 60 additions & 5 deletions tests/Zend/Json/JsonTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,48 @@ public function testString4()
*/
public function testString5()
{
$expected = '"INFO: Path \"Some more\""';
$expected = '"INFO: Path \\u0022Some more\\u0022"';
$string = 'INFO: Path "Some more"';
$encoded = Json\Encoder::encode($string);
$this->assertEquals($expected, $encoded, 'Quote encoding incorrect: expected ' . serialize($expected) . '; received: ' . serialize($encoded) . "\n");
$this->assertEquals(
$expected,
$encoded,
'Quote encoding incorrect: expected ' . serialize($expected) . '; received: ' . serialize($encoded) . "\n"
);
$this->assertEquals($string, Json\Decoder::decode($encoded)); // Bug: does not accept \u0022 as token!
}

/**
* Test decoding of unicode escaped special characters
*/
public function testStringOfHtmlSpecialCharsEncodedToUnicodeEscapes()
{
Json\Json::$useBuiltinEncoderDecoder = false;
$expected = '"\\u003C\\u003E\\u0026\\u0027\\u0022"';
$string = '<>&\'"';
$encoded = Json\Encoder::encode($string);
$this->assertEquals(
$expected,
$encoded,
'Encoding error: expected ' . serialize($expected) . '; received: ' . serialize($encoded) . "\n"
);
$this->assertEquals($string, Json\Decoder::decode($encoded));
}

/**
* Test decoding of unicode escaped ASCII (non-HTML special) characters
*
* Note: covers chars that MUST be escaped. Does not test any other non-printables.
*/
public function testStringOfOtherSpecialCharsEncodedToUnicodeEscapes()
{
Json\Json::$useBuiltinEncoderDecoder = false;
$string = "\\ - \n - \t - \r - " .chr(0x08). " - " .chr(0x0C). " - / - \v";
$encoded = '"\u005C - \u000A - \u0009 - \u000D - \u0008 - \u000C - \u002F - \u000B"';
$this->assertEquals($string, Json\Decoder::decode($encoded));
}


/**
* test indexed array encoding/decoding
*/
Expand Down Expand Up @@ -704,7 +739,17 @@ public function testEncodeObjectImplementingIterator()
public function testNativeJSONEncoderWillProperlyEncodeSolidusInStringValues()
{
$source = "</foo><foo>bar</foo>";
$target = '"<\\/foo><foo>bar<\\/foo>"';
$target = '"\u003C\/foo\u003E\u003Cfoo\u003Ebar\u003C\/foo\u003E"';

// first test ext/json
Json\Json::$useBuiltinEncoderDecoder = false;
$this->assertEquals($target, Json\Json::encode($source));
}

public function testNativeJSONEncoderWillProperlyEncodeHtmlSpecialCharsInStringValues()
{
$source = "<>&'\"";
$target = '"\u003C\u003E\u0026\u0027\u0022"';

// first test ext/json
Json\Json::$useBuiltinEncoderDecoder = false;
Expand All @@ -717,7 +762,17 @@ public function testNativeJSONEncoderWillProperlyEncodeSolidusInStringValues()
public function testBuiltinJSONEncoderWillProperlyEncodeSolidusInStringValues()
{
$source = "</foo><foo>bar</foo>";
$target = '"<\\/foo><foo>bar<\\/foo>"';
$target = '"\u003C\/foo\u003E\u003Cfoo\u003Ebar\u003C\/foo\u003E"';

// first test ext/json
Json\Json::$useBuiltinEncoderDecoder = true;
$this->assertEquals($target, Json\Json::encode($source));
}

public function testBuiltinJSONEncoderWillProperlyEncodeHtmlSpecialCharsInStringValues()
{
$source = "<>&'\"";
$target = '"\u003C\u003E\u0026\u0027\u0022"';

// first test ext/json
Json\Json::$useBuiltinEncoderDecoder = true;
Expand Down Expand Up @@ -782,7 +837,7 @@ public function testJsonPrettyPrintWorksWithArrayNotationInStringLiteral()
$expected = <<<EOB
{
"simple":"simple test string",
"stringwithjsonchars":"\\\\\\"[1,2]",
"stringwithjsonchars":"\\\\\\u0022[1,2]",
"complex":{
"foo":"bar",
"far":"boo",
Expand Down

0 comments on commit ffb0188

Please sign in to comment.