summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2012-12-28 18:21:11 +0100
committerJay Berkenbilt <ejb@ql.org>2012-12-31 16:32:31 +0100
commit16a23368e738be88669f4fbf4d3341dd473519c7 (patch)
tree4dbe3f137fe08e03e83d3e477069c6a4255b5dc2
parent8f5de08c2ae5d2c01488887f3141b6fe3eb67779 (diff)
downloadqpdf-16a23368e738be88669f4fbf4d3341dd473519c7.tar.zst
Fix infinite loop trimming passwords with ( in them
-rw-r--r--libqpdf/QPDF_encryption.cc14
-rw-r--r--qpdf/qpdf.testcov1
-rw-r--r--qpdf/test_driver.cc17
3 files changed, 28 insertions, 4 deletions
diff --git a/libqpdf/QPDF_encryption.cc b/libqpdf/QPDF_encryption.cc
index 43bc62ba..6ab51a03 100644
--- a/libqpdf/QPDF_encryption.cc
+++ b/libqpdf/QPDF_encryption.cc
@@ -141,14 +141,20 @@ QPDF::trim_user_password(std::string& user_password)
return;
}
- char const* p = 0;
- while ((p = strchr(cstr, '\x28')) != 0)
+ char const* p1 = cstr;
+ char const* p2 = 0;
+ while ((p2 = strchr(p1, '\x28')) != 0)
{
- if (memcmp(p, padding_string, len - (p - cstr)) == 0)
+ if (memcmp(p2, padding_string, len - (p2 - cstr)) == 0)
{
- user_password = user_password.substr(0, p - cstr);
+ user_password = user_password.substr(0, p2 - cstr);
return;
}
+ else
+ {
+ QTC::TC("qpdf", "QPDF_encryption skip 0x28");
+ p1 = p2 + 1;
+ }
}
}
diff --git a/qpdf/qpdf.testcov b/qpdf/qpdf.testcov
index 1f8238e0..cf9aed20 100644
--- a/qpdf/qpdf.testcov
+++ b/qpdf/qpdf.testcov
@@ -253,3 +253,4 @@ QPDFWriter skip ADBE 0
QPDFWriter remove existing Extensions 0
QPDFWriter skip Extensions 0
QPDFWriter preserve ADBE 0
+QPDF_encryption skip 0x28 0
diff --git a/qpdf/test_driver.cc b/qpdf/test_driver.cc
index f8294889..bd403345 100644
--- a/qpdf/test_driver.cc
+++ b/qpdf/test_driver.cc
@@ -88,6 +88,23 @@ void runtest(int n, char const* filename1, char const* filename2)
// the test suite to see how the test is invoked to find the file
// that the test is supposed to operate on.
+ if (n == 0)
+ {
+ // Throw in some random test cases that don't fit anywhere
+ // else. This is in addition to whatever else is going on in
+ // test 0.
+
+ // The code to trim user passwords looks for 0x28 (which is
+ // "(") since it marks the beginning of the padding. Exercise
+ // the code to make sure it skips over 0x28 characters that
+ // aren't part of padding.
+ std::string password(
+ "1234567890123456789012(45678\x28\xbf\x4e\x5e");
+ assert(password.length() == 32);
+ QPDF::trim_user_password(password);
+ assert(password == "1234567890123456789012(45678");
+ }
+
QPDF pdf;
PointerHolder<char> file_buf;
FILE* filep = 0;