Commit 16a23368e738be88669f4fbf4d3341dd473519c7
1 parent
8f5de08c
Fix infinite loop trimming passwords with ( in them
Showing
3 changed files
with
28 additions
and
4 deletions
libqpdf/QPDF_encryption.cc
| ... | ... | @@ -141,14 +141,20 @@ QPDF::trim_user_password(std::string& user_password) |
| 141 | 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 | 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
qpdf/test_driver.cc
| ... | ... | @@ -88,6 +88,23 @@ void runtest(int n, char const* filename1, char const* filename2) |
| 88 | 88 | // the test suite to see how the test is invoked to find the file |
| 89 | 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 | 108 | QPDF pdf; |
| 92 | 109 | PointerHolder<char> file_buf; |
| 93 | 110 | FILE* filep = 0; | ... | ... |