mirror of https://github.com/qpdf/qpdf.git
In JSON::parse allow duplicate dictionary keys
If duplicate keys are encountered, overwrite earlier values with the latest value.
This commit is contained in:
parent
b1b789df42
commit
dd8023c077
|
@ -143,12 +143,6 @@ class JSON
|
|||
QPDF_DLL
|
||||
bool isDictionary() const;
|
||||
|
||||
// If the key is already in the dictionary, return true. Otherwise, mark it as seen and return
|
||||
// false. This is primarily intended to be used by the parser to detect duplicate keys when the
|
||||
// reactor blocks them from being added to the final dictionary.
|
||||
QPDF_DLL
|
||||
bool checkDictionaryKeySeen(std::string const& key);
|
||||
|
||||
// Accessors. Accessor behavior:
|
||||
//
|
||||
// - If argument is wrong type, including null, return false
|
||||
|
@ -324,7 +318,6 @@ class JSON
|
|||
~JSON_dictionary() override = default;
|
||||
void write(Pipeline*, size_t depth) const override;
|
||||
std::map<std::string, JSON> members;
|
||||
std::set<std::string> parsed_keys;
|
||||
};
|
||||
struct JSON_array;
|
||||
struct JSON_string: public JSON_value
|
||||
|
|
|
@ -285,16 +285,6 @@ JSON::addDictionaryMember(std::string const& key, JSON const& val)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
JSON::checkDictionaryKeySeen(std::string const& key)
|
||||
{
|
||||
if (auto* obj = m ? dynamic_cast<JSON_dictionary*>(m->value.get()) : nullptr) {
|
||||
return !obj->parsed_keys.insert(key).second;
|
||||
}
|
||||
throw std::logic_error("JSON::checkDictionaryKey called on non-dictionary");
|
||||
return false; // unreachable
|
||||
}
|
||||
|
||||
JSON
|
||||
JSON::makeArray()
|
||||
{
|
||||
|
@ -1264,11 +1254,6 @@ JSONParser::handleToken()
|
|||
break;
|
||||
|
||||
case ps_dict_after_colon:
|
||||
if (tos.checkDictionaryKeySeen(dict_key)) {
|
||||
QTC::TC("libtests", "JSON parse duplicate key");
|
||||
throw std::runtime_error(
|
||||
"JSON: offset " + std::to_string(dict_key_offset) + ": duplicated dictionary key");
|
||||
}
|
||||
if (!reactor || !reactor->dictionaryItem(dict_key, item)) {
|
||||
tos.addDictionaryMember(dict_key, item);
|
||||
}
|
||||
|
|
|
@ -161,11 +161,6 @@ test_main()
|
|||
assert(jarr.addArrayElement(uninitialized).isNull());
|
||||
assert(!uninitialized.isArray());
|
||||
assert(!uninitialized.isDictionary());
|
||||
try {
|
||||
uninitialized.checkDictionaryKeySeen("key");
|
||||
assert(false);
|
||||
} catch (std::logic_error&) {
|
||||
}
|
||||
std::string st_out = "unchanged";
|
||||
assert(!uninitialized.getString(st_out));
|
||||
assert(!uninitialized.getNumber(st_out));
|
||||
|
|
|
@ -90,6 +90,5 @@ JSON optional key 0
|
|||
JSON 16 high high 0
|
||||
JSON 16 low not after high 0
|
||||
JSON 16 dangling high 0
|
||||
JSON parse duplicate key 0
|
||||
JSON schema array for single item 0
|
||||
JSON schema array length mismatch 0
|
||||
|
|
|
@ -32,7 +32,7 @@ if ($^O ne 'msys')
|
|||
|
||||
cleanup();
|
||||
|
||||
my $good = 11;
|
||||
my $good = 12;
|
||||
|
||||
for (my $i = 1; $i <= $good; ++$i)
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ my @bad = (
|
|||
"stray low surrogate", # 37
|
||||
"high high surrogate", # 38
|
||||
"dangling high surrogate", # 39
|
||||
"duplicate dictionary key", # 40
|
||||
"bs char in string", # 40
|
||||
"decimal point after minus",# 41
|
||||
"e after minus", # 42
|
||||
"missing digit after e", # 43
|
||||
|
@ -128,7 +128,7 @@ my @bad = (
|
|||
"tab char in string", # 45
|
||||
"cr char in string", # 46
|
||||
"lf char in string", # 47
|
||||
"bs char in string", # 48
|
||||
#"bs char in string", # 40
|
||||
);
|
||||
|
||||
my $i = 0;
|
||||
|
|
|
@ -1,6 +1 @@
|
|||
{
|
||||
"one": 1,
|
||||
"two": 2,
|
||||
"one": 3,
|
||||
"four": 4
|
||||
}
|
||||
"bs in string"
|
|
@ -1 +1 @@
|
|||
exception: bad-40.json: JSON: offset 28: duplicated dictionary key
|
||||
exception: bad-40.json: JSON: control or null character at offset 10
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
"bs in string"
|
|
@ -1 +0,0 @@
|
|||
exception: bad-48.json: JSON: control or null character at offset 10
|
|
@ -0,0 +1,7 @@
|
|||
dictionary start
|
||||
dictionary item: one -> [11, 12): 1
|
||||
dictionary item: two -> [23, 24): 2
|
||||
dictionary item: one -> [35, 36): 3
|
||||
dictionary item: four -> [48, 49): 4
|
||||
container end: [0, 51): {}
|
||||
{}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"one": 1,
|
||||
"two": 2,
|
||||
"one": 3,
|
||||
"four": 4
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"four": 4,
|
||||
"one": 3,
|
||||
"two": 2
|
||||
}
|
Loading…
Reference in New Issue