Commit bed165c9fc070d2c483d8cc9bd0e7ac299b29e23
1 parent
1a888ee3
Stop using InputSource::unreadCh
Showing
7 changed files
with
27 additions
and
21 deletions
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 |
TODO
| @@ -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<InputSource> input, | @@ -1604,7 +1604,7 @@ QPDF::readObject(PointerHolder<InputSource> 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<InputSource> input, | @@ -1629,7 +1629,7 @@ QPDF::readObject(PointerHolder<InputSource> 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<InputSource> input, | @@ -855,7 +855,7 @@ QPDFTokenizer::readToken(PointerHolder<InputSource> 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); |