Page MenuHomePhabricator

D9627.diff
No OneTemporary

D9627.diff

diff --git a/externals/jsonlint/src/Seld/JsonLint/JsonParser.php b/externals/jsonlint/src/Seld/JsonLint/JsonParser.php
--- a/externals/jsonlint/src/Seld/JsonLint/JsonParser.php
+++ b/externals/jsonlint/src/Seld/JsonLint/JsonParser.php
@@ -380,11 +380,7 @@
$errStr .= "Duplicate key: ".$tokens[$len][0];
throw new JsonLintParsingException($errStr);
} elseif (($this->flags & self::ALLOW_DUPLICATE_KEYS) && array_key_exists($key, $tokens[$len-2])) {
- $duplicateCount = 1;
- do {
- $duplicateKey = $key . '.' . $duplicateCount++;
- } while (array_key_exists($duplicateKey, $tokens[$len-2]));
- $key = $duplicateKey;
+ // Forget about it...
}
$yyval->token[$key] = $tokens[$len][1];
break;
diff --git a/src/parser/PhutilJSONParser.php b/src/parser/PhutilJSONParser.php
--- a/src/parser/PhutilJSONParser.php
+++ b/src/parser/PhutilJSONParser.php
@@ -8,6 +8,13 @@
*/
final class PhutilJSONParser {
+ private $allowDuplicateKeys = false;
+
+ public function setAllowDuplicateKeys($allow_duplicate_keys) {
+ $this->allowDuplicateKeys = $allow_duplicate_keys;
+ return $this;
+ }
+
public function parse($json) {
$jsonlint_root = phutil_get_library_root('phutil').'/../externals/jsonlint';
require_once($jsonlint_root.'/src/Seld/JsonLint/JsonParser.php');
@@ -17,17 +24,17 @@
$parser = new JsonLintJsonParser();
try {
- $output = $parser->parse($json);
+ $output = $parser->parse($json, $this->getFlags());
} catch (JsonLintParsingException $ex) {
$details = $ex->getDetails();
$message = preg_replace("/^Parse error .*\\^\n/s", '', $ex->getMessage());
throw new PhutilJSONParserException(
$message,
- $details['loc']['last_line'],
- $details['loc']['last_column'],
- $details['token'],
- $details['expected']);
+ idx(idx($details, 'loc', array()), 'last_line'),
+ idx(idx($details, 'loc', array()), 'last_column'),
+ idx($details, 'token'),
+ idx($details, 'expected'));
}
if (!is_array($output)) {
@@ -40,4 +47,16 @@
return $output;
}
+ private function getFlags() {
+ $flags = 0;
+
+ if ($this->allowDuplicateKeys) {
+ $flags |= JsonLintJsonParser::ALLOW_DUPLICATE_KEYS;
+ } else {
+ $flags |= JsonLintJsonParser::DETECT_KEY_CONFLICTS;
+ }
+
+ return $flags;
+ }
+
}
diff --git a/src/parser/__tests__/PhutilJSONParserTestCase.php b/src/parser/__tests__/PhutilJSONParserTestCase.php
--- a/src/parser/__tests__/PhutilJSONParserTestCase.php
+++ b/src/parser/__tests__/PhutilJSONParserTestCase.php
@@ -86,4 +86,29 @@
}
}
+ public function testDuplicateKeys() {
+ $parser = new PhutilJSONParser();
+
+ $tests = array(
+ '{"foo": "bar", "foo": "baz"}' => array('foo' => 'baz'),
+ );
+
+ foreach ($tests as $input => $expect) {
+ $parser->setAllowDuplicateKeys(true);
+ $this->assertEqual(
+ $expect,
+ $parser->parse($input),
+ 'Parsing JSON: '.$input);
+
+ $parser->setAllowDuplicateKeys(false);
+ $caught = null;
+ try {
+ $parser->parse($input);
+ } catch (Exception $ex) {
+ $caught = $ex;
+ }
+ $this->assertTrue($caught instanceof PhutilJSONParserException);
+ }
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 22, 9:39 PM (20 h, 33 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6776034
Default Alt Text
D9627.diff (3 KB)

Event Timeline