Commit 8b1e307741d52a0c401296eaf790b18f98d67b6a

Authored by Jay Berkenbilt
1 parent 5ce287d6

Warn for duplicated dictionary keys (fixes #345)

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&lt;InputSource&gt; 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
... ... @@ -445,3 +445,4 @@ QPDF eof skipping spaces before xref 1
445 445 QPDF_encryption user matches owner V < 5 0
446 446 QPDF_encryption same password 1
447 447 QPDFWriter stream in ostream 0
  448 +QPDFObjectHandle duplicate dict key 0
... ...
qpdf/qtest/qpdf.test
... ... @@ -2314,7 +2314,7 @@ my @badfiles = (&quot;not a PDF file&quot;, # 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
... ... @@ -73,6 +73,8 @@ xref
73 73 trailer <<
74 74 /Size 7
75 75 /Root 1 0 R
  76 + /K 1
  77 + /K 2
76 78 /Something
77 79 >>
78 80 startxref
... ...
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
... ...