Commit 8b1e307741d52a0c401296eaf790b18f98d67b6a
1 parent
5ce287d6
Warn for duplicated dictionary keys (fixes #345)
Showing
8 changed files
with
27 additions
and
2 deletions
ChangeLog
| 1 | +2019-09-19 Jay Berkenbilt <ejb@ql.org> | |
| 2 | + | |
| 3 | + * Warn when duplicated dictionary keys are found during parsing. | |
| 4 | + The behavior remains as before: later keys override earlier ones. | |
| 5 | + However, this generates a warning now rather than being silently | |
| 6 | + ignored. Fixes #345. | |
| 7 | + | |
| 1 | 8 | 2019-09-17 Jay Berkenbilt <ejb@ql.org> |
| 2 | 9 | |
| 3 | 10 | * QIntC tests: don't assume char is signed. Fixes #361. | ... | ... |
libqpdf/QPDFObjectHandle.cc
| ... | ... | @@ -2135,7 +2135,18 @@ QPDFObjectHandle::parseInternal(PointerHolder<InputSource> input, |
| 2135 | 2135 | { |
| 2136 | 2136 | val = olist.at(++i); |
| 2137 | 2137 | } |
| 2138 | - dict[key_obj.getName()] = val; | |
| 2138 | + std::string key = key_obj.getName(); | |
| 2139 | + if (dict.count(key) > 0) | |
| 2140 | + { | |
| 2141 | + QTC::TC("qpdf", "QPDFObjectHandle duplicate dict key"); | |
| 2142 | + warn(context, | |
| 2143 | + QPDFExc( | |
| 2144 | + qpdf_e_damaged_pdf, | |
| 2145 | + input->getName(), object_description, offset, | |
| 2146 | + "dictionary has duplicated key " + key + | |
| 2147 | + "; last occurrence overrides earlier ones")); | |
| 2148 | + } | |
| 2149 | + dict[key] = val; | |
| 2139 | 2150 | } |
| 2140 | 2151 | object = newDictionary(dict); |
| 2141 | 2152 | setObjectDescriptionFromInput( | ... | ... |
qpdf/qpdf.testcov
qpdf/qtest/qpdf.test
| ... | ... | @@ -2314,7 +2314,7 @@ my @badfiles = ("not a PDF file", # 1 |
| 2314 | 2314 | "bad }", # 14 |
| 2315 | 2315 | "bad ]", # 15 |
| 2316 | 2316 | "bad >>", # 16 |
| 2317 | - "odd number of dictionary items", # 17 | |
| 2317 | + "dictionary errors", # 17 | |
| 2318 | 2318 | "bad )", # 18 |
| 2319 | 2319 | "bad >", # 19 |
| 2320 | 2320 | "invalid hexstring character", # 20 | ... | ... |
qpdf/qtest/qpdf/bad17-recover.out
| 1 | +WARNING: bad17.pdf (trailer, offset 715): dictionary has duplicated key /K; last occurrence overrides earlier ones | |
| 1 | 2 | WARNING: bad17.pdf (trailer, offset 715): dictionary ended prematurely; using null as value for last key |
| 2 | 3 | /QTest is implicit |
| 3 | 4 | /QTest is direct and has type null (2) | ... | ... |
qpdf/qtest/qpdf/bad17.out
| 1 | +WARNING: bad17.pdf (trailer, offset 715): dictionary has duplicated key /K; last occurrence overrides earlier ones | |
| 1 | 2 | WARNING: bad17.pdf (trailer, offset 715): dictionary ended prematurely; using null as value for last key |
| 2 | 3 | /QTest is implicit |
| 3 | 4 | /QTest is direct and has type null (2) | ... | ... |
qpdf/qtest/qpdf/bad17.pdf
qpdf/qtest/qpdf/issue-51.out
| 1 | 1 | WARNING: issue-51.pdf: can't find PDF header |
| 2 | 2 | WARNING: issue-51.pdf: reported number of objects (0) is not one plus the highest object number (8) |
| 3 | +WARNING: issue-51.pdf (object 7 0, offset 476): dictionary has duplicated key /0000; last occurrence overrides earlier ones | |
| 3 | 4 | WARNING: issue-51.pdf (object 7 0, offset 553): expected endobj |
| 5 | +WARNING: issue-51.pdf (object 1 0, offset 236): dictionary has duplicated key /00000000; last occurrence overrides earlier ones | |
| 4 | 6 | WARNING: issue-51.pdf (object 1 0, offset 359): expected endobj |
| 5 | 7 | WARNING: issue-51.pdf (offset 70): loop detected resolving object 2 0 |
| 6 | 8 | WARNING: issue-51.pdf (object 2 0, offset 26): /Length key in stream dictionary is not an integer | ... | ... |