From 68371b9b17c1b22d6fa68ec37c8bf786b2c8148f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20Soutad=C3=A9?= Date: Fri, 23 Dec 2022 17:51:01 +0100 Subject: [PATCH] Check for potential write error (or not buffer full consumed) --- include/uPDFParser.h | 1 + include/uPDFParser_common.h | 3 ++- src/uPDFParser.cpp | 48 ++++++++++++++++++++++++++----------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/include/uPDFParser.h b/include/uPDFParser.h index 6026ecb..633c395 100644 --- a/include/uPDFParser.h +++ b/include/uPDFParser.h @@ -118,6 +118,7 @@ namespace uPDFParser Name* parseName(std::string& token); void repairTrailer(); + void writeBuffer(int fd, const char* buffer, int size); void writeUpdate(const std::string& filename); int version_major, version_minor; diff --git a/include/uPDFParser_common.h b/include/uPDFParser_common.h index 77cc6a0..edeb81d 100644 --- a/include/uPDFParser_common.h +++ b/include/uPDFParser_common.h @@ -22,7 +22,8 @@ namespace uPDFParser INVALID_OBJECT, INVALID_TRAILER, INVALID_HEXASTRING, - NOT_IMPLEMENTED + NOT_IMPLEMENTED, + IO_ERROR }; diff --git a/src/uPDFParser.cpp b/src/uPDFParser.cpp index bd9fd42..524ab71 100644 --- a/src/uPDFParser.cpp +++ b/src/uPDFParser.cpp @@ -619,7 +619,9 @@ namespace uPDFParser for (;endOffset > startOffset; endOffset--) { lseek(fd, -1, SEEK_CUR); - read(fd, &c, 1); + ret = read(fd, &c, 1); + if (ret <= 0) + break; if (c != '\n' && c != '\r') break; lseek(fd, -1, SEEK_CUR); @@ -824,6 +826,24 @@ namespace uPDFParser trailer.dictionary().addData(keys[i], (*xrefObject)[keys[i]]->clone()); } } + + void Parser::writeBuffer(int fd, const char* buffer, int size) + { + int ret; + + do { + ret = ::write(fd, buffer, size); + if (ret >= 0) + { + size -= ret; + buffer += ret; + } + else + { + EXCEPTION(IO_ERROR, "IO Error (write) %m"); + } + } while (size); + } void Parser::writeUpdate(const std::string& filename) { @@ -848,11 +868,11 @@ namespace uPDFParser ret = ::read(fd, buffer, sizeof(buffer)); if (ret <= 0) break; - ::write(newFd, buffer, ret); + writeBuffer(newFd, buffer, ret); } } - ::write(newFd, "\r", 1); + writeBuffer(newFd, "\r", 1); int maxId = 0; std::stringstream xref; @@ -872,7 +892,7 @@ namespace uPDFParser nbNewObjects ++; std::string objStr = object->str(); curOffset = lseek(newFd, 0, SEEK_CUR); - ::write(newFd, objStr.c_str(), objStr.size()); + writeBuffer(newFd, objStr.c_str(), objStr.size()); xref << std::setw(0) << object->objectId() << " 1\n"; xref << std::setw(10) << curOffset << " " << std::setw(5) << object->generationNumber() << " n\r\n"; // Here \r seems important } @@ -886,7 +906,7 @@ namespace uPDFParser off_t newXrefOffset = lseek(newFd, 0, SEEK_CUR); std::string xrefStr = xref.str(); - ::write(newFd, xrefStr.c_str(), xrefStr.size()); + writeBuffer(newFd, xrefStr.c_str(), xrefStr.size()); trailer.deleteKey("Prev"); if (xrefOffset != (off_t)-1) @@ -895,14 +915,14 @@ namespace uPDFParser trailer.dictionary().addData("Size", new Integer(maxId+1)); std::string trailerStr = trailer.dictionary().str(); - ::write(newFd, "trailer\n", 8); - ::write(newFd, trailerStr.c_str(), trailerStr.size()); + writeBuffer(newFd, "trailer\n", 8); + writeBuffer(newFd, trailerStr.c_str(), trailerStr.size()); std::stringstream startxref; startxref << "startxref\n" << newXrefOffset << "\n%%EOF"; std::string startxrefStr = startxref.str(); - ::write(newFd, startxrefStr.c_str(), startxrefStr.size()); + writeBuffer(newFd, startxrefStr.c_str(), startxrefStr.size()); close(newFd); } @@ -922,7 +942,7 @@ namespace uPDFParser version_major, version_minor, 0xe2, 0xe3, 0xcf, 0xd3); - ::write(newFd, header, ret); + writeBuffer(newFd, header, ret); int maxId = 0; std::stringstream xref; @@ -939,7 +959,7 @@ namespace uPDFParser Object* object = *it; std::string objStr = object->str(); curOffset = lseek(newFd, 0, SEEK_CUR); - ::write(newFd, objStr.c_str(), objStr.size()); + writeBuffer(newFd, objStr.c_str(), objStr.size()); xref << std::setw(0) << object->objectId() << " 1\n"; xref << std::setw(10) << curOffset << " " << std::setw(5) << object->generationNumber(); if (object->used()) @@ -966,7 +986,7 @@ namespace uPDFParser off_t newXrefOffset = lseek(newFd, 0, SEEK_CUR); std::string xrefStr = xref.str(); - ::write(newFd, xrefStr.c_str(), xrefStr.size()); + writeBuffer(newFd, xrefStr.c_str(), xrefStr.size()); trailer.deleteKey("Prev"); trailer.deleteKey("Size"); @@ -977,14 +997,14 @@ namespace uPDFParser trailer.dictionary().addData("XRefStm", new Integer(xrefStmOffset)); std::string trailerStr = trailer.dictionary().str(); - ::write(newFd, "trailer\n", 8); - ::write(newFd, trailerStr.c_str(), trailerStr.size()); + writeBuffer(newFd, "trailer\n", 8); + writeBuffer(newFd, trailerStr.c_str(), trailerStr.size()); std::stringstream startxref; startxref << "startxref\n" << newXrefOffset << "\n%%EOF"; std::string startxrefStr = startxref.str(); - ::write(newFd, startxrefStr.c_str(), startxrefStr.size()); + writeBuffer(newFd, startxrefStr.c_str(), startxrefStr.size()); close(newFd); }