Commit bed165c9fc070d2c483d8cc9bd0e7ac299b29e23

Authored by Jay Berkenbilt
1 parent 1a888ee3

Stop using InputSource::unreadCh

ChangeLog
  1 +2020-10-18 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Note that InputSource::unreadCh is deprecated and will be
  4 + removed in qpdf 11. Use seek(-1, SEEK_CUR) instead. This is what
  5 + it has always effectively done with some input sources and some
  6 + operating systems which don't allow unreading other than the most
  7 + recently read character. InputSource::unreadCh is no longer used
  8 + internally within libqpdf.
  9 +
1 2020-10-16 Jay Berkenbilt <ejb@ql.org> 10 2020-10-16 Jay Berkenbilt <ejb@ql.org>
2 11
3 * Accept pull request that improves how the Windows native crypto 12 * Accept pull request that improves how the Windows native crypto
@@ -117,6 +117,10 @@ ABI Changes @@ -117,6 +117,10 @@ ABI Changes
117 This is a list of changes to make next time there is an ABI change. 117 This is a list of changes to make next time there is an ABI change.
118 Comments appear in the code prefixed by "ABI" 118 Comments appear in the code prefixed by "ABI"
119 119
  120 +* Consider removing InputSource::unreadCh. Maybe we can declare it
  121 + final and delete so it will be forced to be removed from derived
  122 + classes.
  123 +
120 C++-11 124 C++-11
121 ====== 125 ======
122 126
include/qpdf/InputSource.hh
@@ -85,9 +85,14 @@ class QPDF_DLL_CLASS InputSource @@ -85,9 +85,14 @@ class QPDF_DLL_CLASS InputSource
85 virtual size_t read(char* buffer, size_t length) = 0; 85 virtual size_t read(char* buffer, size_t length) = 0;
86 86
87 // Note: you can only unread the character you just read. The 87 // Note: you can only unread the character you just read. The
88 - // specific character is ignored by some implementations. 88 + // specific character is ignored by some implementations. unreadCh
  89 + // will be removed from the API in qpdf 11.
89 virtual void unreadCh(char ch) = 0; 90 virtual void unreadCh(char ch) = 0;
90 91
  92 + // ABI: delete unreadCh, and direct people to seek backward by 1
  93 + // character instead.
  94 + // virtual void unreadCh(char ch) final = delete;
  95 +
91 protected: 96 protected:
92 qpdf_offset_t last_offset; 97 qpdf_offset_t last_offset;
93 98
libqpdf/FileInputSource.cc
@@ -80,7 +80,7 @@ FileInputSource::findAndSkipNextEOL() @@ -80,7 +80,7 @@ FileInputSource::findAndSkipNextEOL()
80 } 80 }
81 else if (! ((ch == '\r') || (ch == '\n'))) 81 else if (! ((ch == '\r') || (ch == '\n')))
82 { 82 {
83 - this->unreadCh(ch); 83 + this->seek(-1, SEEK_CUR);
84 done = true; 84 done = true;
85 } 85 }
86 } 86 }
libqpdf/QPDF.cc
@@ -632,7 +632,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset) @@ -632,7 +632,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
632 } 632 }
633 else 633 else
634 { 634 {
635 - this->m->file->unreadCh(ch); 635 + this->m->file->seek(-1, SEEK_CUR);
636 done = true; 636 done = true;
637 } 637 }
638 } 638 }
@@ -1604,7 +1604,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1604,7 +1604,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1604 // start reading stream data in spite 1604 // start reading stream data in spite
1605 // of not having seen a newline. 1605 // of not having seen a newline.
1606 QTC::TC("qpdf", "QPDF stream with CR only"); 1606 QTC::TC("qpdf", "QPDF stream with CR only");
1607 - input->unreadCh(ch); 1607 + input->seek(-1, SEEK_CUR);
1608 warn(QPDFExc( 1608 warn(QPDFExc(
1609 qpdf_e_damaged_pdf, 1609 qpdf_e_damaged_pdf,
1610 input->getName(), 1610 input->getName(),
@@ -1629,7 +1629,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input, @@ -1629,7 +1629,7 @@ QPDF::readObject(PointerHolder&lt;InputSource&gt; input,
1629 else 1629 else
1630 { 1630 {
1631 QTC::TC("qpdf", "QPDF stream without newline"); 1631 QTC::TC("qpdf", "QPDF stream without newline");
1632 - input->unreadCh(ch); 1632 + input->seek(-1, SEEK_CUR);
1633 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(), 1633 warn(QPDFExc(qpdf_e_damaged_pdf, input->getName(),
1634 this->m->last_object_description, 1634 this->m->last_object_description,
1635 input->tell(), 1635 input->tell(),
libqpdf/QPDFTokenizer.cc
@@ -855,7 +855,7 @@ QPDFTokenizer::readToken(PointerHolder&lt;InputSource&gt; input, @@ -855,7 +855,7 @@ QPDFTokenizer::readToken(PointerHolder&lt;InputSource&gt; input,
855 855
856 if (unread_char) 856 if (unread_char)
857 { 857 {
858 - input->unreadCh(char_to_unread); 858 + input->seek(-1, SEEK_CUR);
859 } 859 }
860 860
861 if (token.getType() != tt_eof) 861 if (token.getType() != tt_eof)
libtests/closed_file_input_source.cc
@@ -27,22 +27,10 @@ void do_tests(InputSource* is) @@ -27,22 +27,10 @@ void do_tests(InputSource* is)
27 check("tell after findAndSkipNextEOL", 522 == is->tell()); 27 check("tell after findAndSkipNextEOL", 522 == is->tell());
28 char b[1]; 28 char b[1];
29 b[0] = '\0'; 29 b[0] = '\0';
30 -#ifdef _WIN32  
31 - // Empirical evidence, and the passage of the rest of the qpdf  
32 - // test suite, suggest that this is working on Windows in the way  
33 - // that it needs to work. If this ifdef is made to be true on  
34 - // Windows, it passes with ClosedFileInputSource but not with  
35 - // FileInputSource, which doesn't make any sense since  
36 - // ClosedFileInputSource is calling FileInputSource to do its  
37 - // work.  
38 - is->seek(521, SEEK_SET);  
39 - is->read(b, 1);  
40 -#else  
41 - is->unreadCh('\n');  
42 - check("read unread character", 1 == is->read(b, 1)); 30 + is->seek(-1, SEEK_CUR);
  31 + check("read previous character", 1 == is->read(b, 1));
43 check("got character", '\n' == b[0]); 32 check("got character", '\n' == b[0]);
44 -#endif  
45 - check("last offset after read unread", 521 == is->getLastOffset()); 33 + check("last offset after read previous", 521 == is->getLastOffset());
46 is->seek(0, SEEK_END); 34 is->seek(0, SEEK_END);
47 check("tell at end", 556 == is->tell()); 35 check("tell at end", 556 == is->tell());
48 is->seek(-25, SEEK_END); 36 is->seek(-25, SEEK_END);