*/
const ALL_OK = 3;
+ /**
+ * Regex that matches whitespace inside empty arrays and objects.
+ *
+ * This doesn't affect regular strings inside the JSON because those can't
+ * have a real line break (\n) in them, at this point they are already escaped
+ * as the string "\n" which this doesn't match.
+ *
+ * @private
+ */
+ const WS_CLEANUP_REGEX = '/(?<=[\[{])\n\s*+(?=[\]}])/';
+
/**
* Characters problematic in JavaScript.
*
if ( $json === false ) {
return false;
}
+
+ if ( $pretty ) {
+ // Remove whitespace inside empty arrays/objects; different JSON encoders
+ // vary on this, and we want our output to be consistent across implementations.
+ $json = preg_replace( self::WS_CLEANUP_REGEX, '', $json );
+ }
if ( $escaping & self::UTF8_OK ) {
$json = str_replace( self::$badChars, self::$badCharsEscaped, $json );
}
$buf .= substr( $json, $i, $skip );
}
}
- return str_replace( "\x01", '\"', preg_replace( '/ +$/m', '', $buf ) );
+ $buf = preg_replace( self::WS_CLEANUP_REGEX, '', $buf );
+ return str_replace( "\x01", '\"', $buf );
}
}
123,
456,
),
+ // Nested json works without problems
'"7":["8",{"9":"10"}]',
+ // Whitespace clean up doesn't touch strings that look alike
+ "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}",
),
);
// 4 space indent, no trailing whitespace, no trailing linefeed
$json = '{
- "emptyObject": {
- },
- "emptyArray": [
- ],
+ "emptyObject": {},
+ "emptyArray": [],
"string": "foobar\\\\",
"filledArray": [
[
123,
456
],
- "\"7\":[\"8\",{\"9\":\"10\"}]"
+ "\"7\":[\"8\",{\"9\":\"10\"}]",
+ "{\n\t\"emptyObject\": {\n\t},\n\t\"emptyArray\": [ ]\n}"
]
}';
$json = str_replace( "\r", '', $json ); // Windows compat
- $this->assertSame( $json, str_replace("\n\n", "\n", FormatJson::encode( $obj, true ) ));
+ $this->assertSame( $json, FormatJson::encode( $obj, true ) );
}
public static function provideEncodeDefault() {