Commit 1868a10f8b06631362618bfc85ca8646da4b4b71

Authored by Jay Berkenbilt
1 parent 742190bd

Replace all atoi calls with QUtil::string_to_int

The latter catches underflow/overflow.
README-maintainer.md
@@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
17 * Test with clang. 17 * Test with clang.
18 * Check all open issues in the sourceforge trackers and on github. 18 * Check all open issues in the sourceforge trackers and on github.
19 * If any interfaces were added or changed, check C API to see whether changes are appropriate there as well. If necessary, review the casting policy in the manual, and ensure that integer types are properly handled. 19 * If any interfaces were added or changed, check C API to see whether changes are appropriate there as well. If necessary, review the casting policy in the manual, and ensure that integer types are properly handled.
  20 +* Avoid atoi. Use QUtil::string_to_int instead. It does overflow/underflow checking.
20 * Remember to avoid using `operator[]` with `std::string` or `std::vector`. Instead, use `at()`. See README-hardening.md for details. 21 * Remember to avoid using `operator[]` with `std::string` or `std::vector`. Instead, use `at()`. See README-hardening.md for details.
21 * Increment shared library version information as needed (`LT_*` in `configure.ac`) 22 * Increment shared library version information as needed (`LT_*` in `configure.ac`)
22 * Update release notes in manual. Look at diffs and ChangeLog. 23 * Update release notes in manual. Look at diffs and ChangeLog.
examples/pdf-parse-content.cc
@@ -62,7 +62,7 @@ int main(int argc, char* argv[]) @@ -62,7 +62,7 @@ int main(int argc, char* argv[])
62 usage(); 62 usage();
63 } 63 }
64 char const* filename = argv[1]; 64 char const* filename = argv[1];
65 - int pageno = atoi(argv[2]); 65 + int pageno = QUtil::string_to_int(argv[2]);
66 66
67 try 67 try
68 { 68 {
libqpdf/QPDF.cc
@@ -440,8 +440,8 @@ QPDF::reconstruct_xref(QPDFExc& e) @@ -440,8 +440,8 @@ QPDF::reconstruct_xref(QPDFExc& e)
440 (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj"))) 440 (t3 == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "obj")))
441 { 441 {
442 in_obj = true; 442 in_obj = true;
443 - int obj = atoi(t1.getValue().c_str());  
444 - int gen = atoi(t2.getValue().c_str()); 443 + int obj = QUtil::string_to_int(t1.getValue().c_str());
  444 + int gen = QUtil::string_to_int(t2.getValue().c_str());
445 insertXrefEntry(obj, 1, token_start, gen, true); 445 insertXrefEntry(obj, 1, token_start, gen, true);
446 } 446 }
447 } 447 }
@@ -610,8 +610,8 @@ QPDF::parse_xrefFirst(std::string const& line, @@ -610,8 +610,8 @@ QPDF::parse_xrefFirst(std::string const& line,
610 ++p; 610 ++p;
611 } 611 }
612 bytes = p - start; 612 bytes = p - start;
613 - obj = atoi(obj_str.c_str());  
614 - num = atoi(num_str.c_str()); 613 + obj = QUtil::string_to_int(obj_str.c_str());
  614 + num = QUtil::string_to_int(num_str.c_str());
615 return true; 615 return true;
616 } 616 }
617 617
@@ -706,7 +706,7 @@ QPDF::parse_xrefEntry(std::string const& line, @@ -706,7 +706,7 @@ QPDF::parse_xrefEntry(std::string const& line,
706 } 706 }
707 707
708 f1 = QUtil::string_to_ll(f1_str.c_str()); 708 f1 = QUtil::string_to_ll(f1_str.c_str());
709 - f2 = atoi(f2_str.c_str()); 709 + f2 = QUtil::string_to_int(f2_str.c_str());
710 710
711 return true; 711 return true;
712 } 712 }
@@ -1570,8 +1570,8 @@ QPDF::readObjectAtOffset(bool try_recovery, @@ -1570,8 +1570,8 @@ QPDF::readObjectAtOffset(bool try_recovery,
1570 this->m->last_object_description, offset, 1570 this->m->last_object_description, offset,
1571 "expected n n obj"); 1571 "expected n n obj");
1572 } 1572 }
1573 - objid = atoi(tobjid.getValue().c_str());  
1574 - generation = atoi(tgen.getValue().c_str()); 1573 + objid = QUtil::string_to_int(tobjid.getValue().c_str());
  1574 + generation = QUtil::string_to_int(tgen.getValue().c_str());
1575 1575
1576 if (objid == 0) 1576 if (objid == 0)
1577 { 1577 {
@@ -1855,7 +1855,7 @@ QPDF::resolveObjectsInStream(int obj_stream_number) @@ -1855,7 +1855,7 @@ QPDF::resolveObjectsInStream(int obj_stream_number)
1855 "expected integer in object stream header"); 1855 "expected integer in object stream header");
1856 } 1856 }
1857 1857
1858 - int num = atoi(tnum.getValue().c_str()); 1858 + int num = QUtil::string_to_int(tnum.getValue().c_str());
1859 int offset = QUtil::string_to_ll(toffset.getValue().c_str()); 1859 int offset = QUtil::string_to_ll(toffset.getValue().c_str());
1860 offsets[num] = offset + first; 1860 offsets[num] = offset + first;
1861 } 1861 }
libqpdf/QPDFWriter.cc
@@ -661,8 +661,10 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor, @@ -661,8 +661,10 @@ QPDFWriter::disableIncompatibleEncryption(int major, int minor,
661 } 661 }
662 else 662 else
663 { 663 {
664 - int V = atoi(this->m->encryption_dictionary["/V"].c_str());  
665 - int R = atoi(this->m->encryption_dictionary["/R"].c_str()); 664 + int V = QUtil::string_to_int(
  665 + this->m->encryption_dictionary["/V"].c_str());
  666 + int R = QUtil::string_to_int(
  667 + this->m->encryption_dictionary["/R"].c_str());
666 if (compareVersions(major, minor, 1, 4) < 0) 668 if (compareVersions(major, minor, 1, 4) < 0)
667 { 669 {
668 if ((V > 1) || (R > 2)) 670 if ((V > 1) || (R > 2))
@@ -705,12 +707,12 @@ void @@ -705,12 +707,12 @@ void
705 QPDFWriter::parseVersion(std::string const& version, 707 QPDFWriter::parseVersion(std::string const& version,
706 int& major, int& minor) const 708 int& major, int& minor) const
707 { 709 {
708 - major = atoi(version.c_str()); 710 + major = QUtil::string_to_int(version.c_str());
709 minor = 0; 711 minor = 0;
710 size_t p = version.find('.'); 712 size_t p = version.find('.');
711 if ((p != std::string::npos) && (version.length() > p)) 713 if ((p != std::string::npos) && (version.length() > p))
712 { 714 {
713 - minor = atoi(version.substr(p + 1).c_str()); 715 + minor = QUtil::string_to_int(version.substr(p + 1).c_str());
714 } 716 }
715 std::string tmp = QUtil::int_to_string(major) + "." + 717 std::string tmp = QUtil::int_to_string(major) + "." +
716 QUtil::int_to_string(minor); 718 QUtil::int_to_string(minor);
libtests/dct_compress.cc
@@ -42,8 +42,8 @@ int main(int argc, char* argv[]) @@ -42,8 +42,8 @@ int main(int argc, char* argv[])
42 42
43 char* infilename = argv[1]; 43 char* infilename = argv[1];
44 char* outfilename = argv[2]; 44 char* outfilename = argv[2];
45 - unsigned int width = atoi(argv[3]);  
46 - unsigned int height = atoi(argv[4]); 45 + int width = QUtil::string_to_int(argv[3]);
  46 + int height = QUtil::string_to_int(argv[4]);
47 char* colorspace = argv[5]; 47 char* colorspace = argv[5];
48 J_COLOR_SPACE cs = 48 J_COLOR_SPACE cs =
49 ((strcmp(colorspace, "rgb") == 0) ? JCS_RGB : 49 ((strcmp(colorspace, "rgb") == 0) ? JCS_RGB :
libtests/png_filter.cc
@@ -61,7 +61,7 @@ int main(int argc, char* argv[]) @@ -61,7 +61,7 @@ int main(int argc, char* argv[])
61 } 61 }
62 bool encode = (strcmp(argv[1], "encode") == 0); 62 bool encode = (strcmp(argv[1], "encode") == 0);
63 char* filename = argv[2]; 63 char* filename = argv[2];
64 - int columns = atoi(argv[3]); 64 + int columns = QUtil::string_to_int(argv[3]);
65 65
66 try 66 try
67 { 67 {
qpdf/pdf_from_scratch.cc
@@ -107,7 +107,7 @@ int main(int argc, char* argv[]) @@ -107,7 +107,7 @@ int main(int argc, char* argv[])
107 107
108 try 108 try
109 { 109 {
110 - int n = atoi(argv[1]); 110 + int n = QUtil::string_to_int(argv[1]);
111 runtest(n); 111 runtest(n);
112 } 112 }
113 catch (std::exception& e) 113 catch (std::exception& e)
qpdf/qpdf.cc
@@ -1127,7 +1127,7 @@ static void parse_version(std::string const&amp; full_version_string, @@ -1127,7 +1127,7 @@ static void parse_version(std::string const&amp; full_version_string,
1127 if (p2 && *(p2 + 1)) 1127 if (p2 && *(p2 + 1))
1128 { 1128 {
1129 *p2++ = '\0'; 1129 *p2++ = '\0';
1130 - extension_level = atoi(p2); 1130 + extension_level = QUtil::string_to_int(p2);
1131 } 1131 }
1132 version = v; 1132 version = v;
1133 } 1133 }
@@ -1233,7 +1233,7 @@ static void parse_rotation_parameter(Options&amp; o, std::string const&amp; parameter) @@ -1233,7 +1233,7 @@ static void parse_rotation_parameter(Options&amp; o, std::string const&amp; parameter)
1233 if (range_valid && 1233 if (range_valid &&
1234 ((angle_str == "90") || (angle_str == "180") || (angle_str == "270"))) 1234 ((angle_str == "90") || (angle_str == "180") || (angle_str == "270")))
1235 { 1235 {
1236 - int angle = atoi(angle_str.c_str()); 1236 + int angle = QUtil::string_to_int(angle_str.c_str());
1237 if (relative == -1) 1237 if (relative == -1)
1238 { 1238 {
1239 angle = -angle; 1239 angle = -angle;
@@ -1492,7 +1492,8 @@ static void parse_options(int argc, char* argv[], Options&amp; o) @@ -1492,7 +1492,8 @@ static void parse_options(int argc, char* argv[], Options&amp; o)
1492 } 1492 }
1493 else if (strcmp(arg, "split-pages") == 0) 1493 else if (strcmp(arg, "split-pages") == 0)
1494 { 1494 {
1495 - int n = ((parameter == 0) ? 1 : atoi(parameter)); 1495 + int n = ((parameter == 0) ? 1 :
  1496 + QUtil::string_to_int(parameter));
1496 o.split_pages = n; 1497 o.split_pages = n;
1497 } 1498 }
1498 else if (strcmp(arg, "verbose") == 0) 1499 else if (strcmp(arg, "verbose") == 0)
@@ -1547,9 +1548,9 @@ static void parse_options(int argc, char* argv[], Options&amp; o) @@ -1547,9 +1548,9 @@ static void parse_options(int argc, char* argv[], Options&amp; o)
1547 if ((gen = strchr(obj, ',')) != 0) 1548 if ((gen = strchr(obj, ',')) != 0)
1548 { 1549 {
1549 *gen++ = 0; 1550 *gen++ = 0;
1550 - o.show_gen = atoi(gen); 1551 + o.show_gen = QUtil::string_to_int(gen);
1551 } 1552 }
1552 - o.show_obj = atoi(obj); 1553 + o.show_obj = QUtil::string_to_int(obj);
1553 o.require_outfile = false; 1554 o.require_outfile = false;
1554 } 1555 }
1555 else if (strcmp(arg, "raw-stream-data") == 0) 1556 else if (strcmp(arg, "raw-stream-data") == 0)
qpdf/test_driver.cc
@@ -1383,7 +1383,7 @@ int main(int argc, char* argv[]) @@ -1383,7 +1383,7 @@ int main(int argc, char* argv[])
1383 1383
1384 try 1384 try
1385 { 1385 {
1386 - int n = atoi(argv[1]); 1386 + int n = QUtil::string_to_int(argv[1]);
1387 char const* filename1 = argv[2]; 1387 char const* filename1 = argv[2];
1388 char const* arg2 = argv[3]; 1388 char const* arg2 = argv[3];
1389 runtest(n, filename1, arg2); 1389 runtest(n, filename1, arg2);