Commit 16a23368e738be88669f4fbf4d3341dd473519c7

Authored by Jay Berkenbilt
1 parent 8f5de08c

Fix infinite loop trimming passwords with ( in them

libqpdf/QPDF_encryption.cc
@@ -141,14 +141,20 @@ QPDF::trim_user_password(std::string& user_password) @@ -141,14 +141,20 @@ QPDF::trim_user_password(std::string& user_password)
141 return; 141 return;
142 } 142 }
143 143
144 - char const* p = 0;  
145 - while ((p = strchr(cstr, '\x28')) != 0) 144 + char const* p1 = cstr;
  145 + char const* p2 = 0;
  146 + while ((p2 = strchr(p1, '\x28')) != 0)
146 { 147 {
147 - if (memcmp(p, padding_string, len - (p - cstr)) == 0) 148 + if (memcmp(p2, padding_string, len - (p2 - cstr)) == 0)
148 { 149 {
149 - user_password = user_password.substr(0, p - cstr); 150 + user_password = user_password.substr(0, p2 - cstr);
150 return; 151 return;
151 } 152 }
  153 + else
  154 + {
  155 + QTC::TC("qpdf", "QPDF_encryption skip 0x28");
  156 + p1 = p2 + 1;
  157 + }
152 } 158 }
153 } 159 }
154 160
qpdf/qpdf.testcov
@@ -253,3 +253,4 @@ QPDFWriter skip ADBE 0 @@ -253,3 +253,4 @@ QPDFWriter skip ADBE 0
253 QPDFWriter remove existing Extensions 0 253 QPDFWriter remove existing Extensions 0
254 QPDFWriter skip Extensions 0 254 QPDFWriter skip Extensions 0
255 QPDFWriter preserve ADBE 0 255 QPDFWriter preserve ADBE 0
  256 +QPDF_encryption skip 0x28 0
qpdf/test_driver.cc
@@ -88,6 +88,23 @@ void runtest(int n, char const* filename1, char const* filename2) @@ -88,6 +88,23 @@ void runtest(int n, char const* filename1, char const* filename2)
88 // the test suite to see how the test is invoked to find the file 88 // the test suite to see how the test is invoked to find the file
89 // that the test is supposed to operate on. 89 // that the test is supposed to operate on.
90 90
  91 + if (n == 0)
  92 + {
  93 + // Throw in some random test cases that don't fit anywhere
  94 + // else. This is in addition to whatever else is going on in
  95 + // test 0.
  96 +
  97 + // The code to trim user passwords looks for 0x28 (which is
  98 + // "(") since it marks the beginning of the padding. Exercise
  99 + // the code to make sure it skips over 0x28 characters that
  100 + // aren't part of padding.
  101 + std::string password(
  102 + "1234567890123456789012(45678\x28\xbf\x4e\x5e");
  103 + assert(password.length() == 32);
  104 + QPDF::trim_user_password(password);
  105 + assert(password == "1234567890123456789012(45678");
  106 + }
  107 +
91 QPDF pdf; 108 QPDF pdf;
92 PointerHolder<char> file_buf; 109 PointerHolder<char> file_buf;
93 FILE* filep = 0; 110 FILE* filep = 0;