From 3c5700c255f4603b5df9c6d183d13dd71a083cc3 Mon Sep 17 00:00:00 2001 From: m-holger Date: Sat, 27 May 2023 18:19:52 +0100 Subject: Code tidy - reflow comments and strings --- libqpdf/ClosedFileInputSource.cc | 6 +- libqpdf/ContentNormalizer.cc | 5 +- libqpdf/FileInputSource.cc | 6 +- libqpdf/InputSource.cc | 74 ++--- libqpdf/InsecureRandomDataProvider.cc | 5 +- libqpdf/JSONHandler.cc | 10 +- libqpdf/MD5.cc | 3 +- libqpdf/NNTree.cc | 135 ++++----- libqpdf/Pl_AES_PDF.cc | 25 +- libqpdf/Pl_ASCII85Decoder.cc | 3 +- libqpdf/Pl_ASCIIHexDecoder.cc | 3 +- libqpdf/Pl_Concatenate.cc | 3 +- libqpdf/Pl_Count.cc | 3 +- libqpdf/Pl_DCT.cc | 30 +- libqpdf/Pl_Discard.cc | 3 +- libqpdf/Pl_Flate.cc | 52 ++-- libqpdf/Pl_Function.cc | 3 +- libqpdf/Pl_LZWDecoder.cc | 11 +- libqpdf/Pl_MD5.cc | 3 +- libqpdf/Pl_OStream.cc | 3 +- libqpdf/Pl_PNGFilter.cc | 4 +- libqpdf/Pl_QPDFTokenizer.cc | 3 +- libqpdf/Pl_RunLength.cc | 10 +- libqpdf/Pl_SHA2.cc | 3 +- libqpdf/Pl_StdioFile.cc | 3 +- libqpdf/Pl_String.cc | 3 +- libqpdf/QPDF.cc | 5 +- libqpdf/QPDFAnnotationObjectHelper.cc | 133 ++++----- libqpdf/QPDFArgParser.cc | 87 +++--- libqpdf/QPDFCryptoProvider.cc | 3 +- libqpdf/QPDFCrypto_gnutls.cc | 5 +- libqpdf/QPDFCrypto_openssl.cc | 4 +- libqpdf/QPDFDocumentHelper.cc | 3 +- libqpdf/QPDFEFStreamObjectHelper.cc | 4 +- libqpdf/QPDFEmbeddedFileDocumentHelper.cc | 9 +- libqpdf/QPDFJob_argv.cc | 9 +- libqpdf/QPDFJob_config.cc | 22 +- libqpdf/QPDFJob_json.cc | 49 ++-- libqpdf/QPDFNameTreeObjectHelper.cc | 5 +- libqpdf/QPDFNumberTreeObjectHelper.cc | 5 +- libqpdf/QPDFObjGen.cc | 16 +- libqpdf/QPDFObjectHandle.cc | 15 +- libqpdf/QPDFObjectHelper.cc | 3 +- libqpdf/QPDFOutlineObjectHelper.cc | 4 +- libqpdf/QPDFPageDocumentHelper.cc | 13 +- libqpdf/QPDFPageLabelDocumentHelper.cc | 14 +- libqpdf/QPDFWriter.cc | 457 ++++++++++++------------------ libqpdf/QPDF_Array.cc | 6 +- libqpdf/QPDF_Dictionary.cc | 6 +- libqpdf/QPDF_Name.cc | 3 +- libqpdf/QPDF_Real.cc | 5 +- libqpdf/QPDF_String.cc | 17 +- libqpdf/QUtil.cc | 115 +++----- libqpdf/SecureRandomDataProvider.cc | 7 +- libqpdf/qpdf-c.cc | 15 +- libqpdf/qpdf/BitStream.hh | 3 +- libqpdf/qpdf/BitWriter.hh | 4 +- libqpdf/qpdf/JSONHandler.hh | 27 +- libqpdf/qpdf/MD5.hh | 3 +- libqpdf/qpdf/NNTree.hh | 5 +- libqpdf/qpdf/OffsetInputSource.hh | 4 +- libqpdf/qpdf/Pl_AES_PDF.hh | 4 +- libqpdf/qpdf/Pl_MD5.hh | 23 +- libqpdf/qpdf/Pl_PNGFilter.hh | 8 +- libqpdf/qpdf/Pl_SHA2.hh | 15 +- libqpdf/qpdf/Pl_TIFFPredictor.hh | 4 +- libqpdf/qpdf/QPDFArgParser.hh | 122 ++++---- libqpdf/qpdf/QPDFCrypto_gnutls.hh | 4 +- libqpdf/qpdf/QPDFObject_private.hh | 14 +- libqpdf/qpdf/QPDF_Dictionary.hh | 9 +- libqpdf/qpdf/RC4.hh | 3 +- 71 files changed, 693 insertions(+), 1010 deletions(-) (limited to 'libqpdf') diff --git a/libqpdf/ClosedFileInputSource.cc b/libqpdf/ClosedFileInputSource.cc index 06ebb156..5e607a76 100644 --- a/libqpdf/ClosedFileInputSource.cc +++ b/libqpdf/ClosedFileInputSource.cc @@ -11,8 +11,7 @@ ClosedFileInputSource::ClosedFileInputSource(char const* filename) : ClosedFileInputSource::~ClosedFileInputSource() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -91,8 +90,7 @@ ClosedFileInputSource::unreadCh(char ch) { before(); this->fis->unreadCh(ch); - // Don't call after -- the file has to stay open after this - // operation. + // Don't call after -- the file has to stay open after this operation. } void diff --git a/libqpdf/ContentNormalizer.cc b/libqpdf/ContentNormalizer.cc index b05b4220..47830f42 100644 --- a/libqpdf/ContentNormalizer.cc +++ b/libqpdf/ContentNormalizer.cc @@ -41,9 +41,8 @@ ContentNormalizer::handleToken(QPDFTokenizer::Token const& token) break; case QPDFTokenizer::tt_string: - // Replacing string and name tokens in this way normalizes - // their representation as this will automatically handle - // quoting of unprintable characters, etc. + // Replacing string and name tokens in this way normalizes their representation as this will + // automatically handle quoting of unprintable characters, etc. writeToken(QPDFTokenizer::Token(QPDFTokenizer::tt_string, token.getValue())); break; diff --git a/libqpdf/FileInputSource.cc b/libqpdf/FileInputSource.cc index 0e0cfa50..ec6e84be 100644 --- a/libqpdf/FileInputSource.cc +++ b/libqpdf/FileInputSource.cc @@ -27,8 +27,7 @@ FileInputSource::FileInputSource(char const* description, FILE* filep, bool clos FileInputSource::~FileInputSource() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer if (this->file && this->close_file) { fclose(this->file); } @@ -68,8 +67,7 @@ FileInputSource::findAndSkipNextEOL() char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; if (p) { result = cur_offset + (p - buf); - // We found \r or \n. Keep reading until we get past - // \r and \n characters. + // We found \r or \n. Keep reading until we get past \r and \n characters. this->seek(result + 1, SEEK_SET); char ch; while (!done) { diff --git a/libqpdf/InputSource.cc b/libqpdf/InputSource.cc index 597781fe..f5dc7706 100644 --- a/libqpdf/InputSource.cc +++ b/libqpdf/InputSource.cc @@ -20,12 +20,10 @@ InputSource::getLastOffset() const std::string InputSource::readLine(size_t max_line_length) { - // Return at most max_line_length characters from the next line. - // Lines are terminated by one or more \r or \n characters. - // Consume the trailing newline characters but don't return them. - // After this is called, the file will be positioned after a line - // terminator or at the end of the file, and last_offset will - // point to position the file had when this method was called. + // Return at most max_line_length characters from the next line. Lines are terminated by one or + // more \r or \n characters. Consume the trailing newline characters but don't return them. + // After this is called, the file will be positioned after a line terminator or at the end of + // the file, and last_offset will point to position the file had when this method was called. qpdf_offset_t offset = this->tell(); auto bp = std::make_unique(max_line_length + 1); @@ -45,22 +43,18 @@ InputSource::readLine(size_t max_line_length) bool InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len, Finder& finder) { - // Basic approach: search for the first character of start_chars - // starting from offset but not going past len (if len != 0). Once - // the first character is found, see if it is the beginning of a - // sequence of characters matching start_chars. If so, call - // finder.check() to do caller-specific additional checks. If not, - // keep searching. + // Basic approach: search for the first character of start_chars starting from offset but not + // going past len (if len != 0). Once the first character is found, see if it is the beginning + // of a sequence of characters matching start_chars. If so, call finder.check() to do + // caller-specific additional checks. If not, keep searching. - // This code is tricky and highly subject to off-by-one or other - // edge case logic errors. See comments throughout that explain - // how we're not missing any edge cases. There are also tests - // specifically constructed to make sure we caught the edge cases - // in testing. + // This code is tricky and highly subject to off-by-one or other edge case logic errors. See + // comments throughout that explain how we're not missing any edge cases. There are also tests + // specifically constructed to make sure we caught the edge cases in testing. char buf[1025]; // size known to input_source.cc in libtests - // To enable us to guarantee null-termination, save an extra byte - // so that buf[size] is valid memory. + // To enable us to guarantee null-termination, save an extra byte so that buf[size] is valid + // memory. size_t size = sizeof(buf) - 1; if ((strlen(start_chars) < 1) || (strlen(start_chars) > size)) { throw std::logic_error("InputSource::findSource called with" @@ -71,19 +65,15 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len qpdf_offset_t buf_offset = offset; size_t bytes_read = 0; - // Guarantee that we return from this loop. Each time through, we - // either return, advance p, or restart the loop with a condition - // that will cause return on the next pass. Eventually we will - // either be out of range or hit EOF, either of which forces us to - // return. + // Guarantee that we return from this loop. Each time through, we either return, advance p, or + // restart the loop with a condition that will cause return on the next pass. Eventually we will + // either be out of range or hit EOF, either of which forces us to return. while (true) { - // Do we need to read more data? Pretend size = 5, buf starts - // at 0, and start_chars has 3 characters. buf[5] is valid and - // null. If p == 2, start_chars could be buf[2] through - // buf[4], so p + strlen(start_chars) == buf + size is okay. - // If p points to buf[size], since strlen(start_chars) is - // always >= 1, this overflow test will be correct for that - // case regardless of start_chars. + // Do we need to read more data? Pretend size = 5, buf starts at 0, and start_chars has 3 + // characters. buf[5] is valid and null. If p == 2, start_chars could be buf[2] through + // buf[4], so p + strlen(start_chars) == buf + size is okay. If p points to buf[size], since + // strlen(start_chars) is always >= 1, this overflow test will be correct for that case + // regardless of start_chars. if ((p == nullptr) || ((p + strlen(start_chars)) > (buf + bytes_read))) { if (p) { QTC::TC( @@ -91,9 +81,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len buf_offset += (p - buf); } this->seek(buf_offset, SEEK_SET); - // Read into buffer and zero out the rest of the buffer - // including buf[size]. We allocated an extra byte so that - // we could guarantee null termination as an extra + // Read into buffer and zero out the rest of the buffer including buf[size]. We + // allocated an extra byte so that we could guarantee null termination as an extra // protection against overrun when using string functions. bytes_read = this->read(buf, size); if (bytes_read < strlen(start_chars)) { @@ -122,19 +111,16 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len } } if ((p + strlen(start_chars)) > (buf + bytes_read)) { - // If there are not enough bytes left in the file for - // start_chars, we will detect this on the next pass - // as EOF and return. + // If there are not enough bytes left in the file for start_chars, we will detect + // this on the next pass as EOF and return. QTC::TC("libtests", "InputSource not enough bytes"); continue; } - // See if p points to a sequence matching start_chars. We - // already checked above to make sure we are not going to - // overrun memory. + // See if p points to a sequence matching start_chars. We already checked above to make + // sure we are not going to overrun memory. if (strncmp(p, start_chars, strlen(start_chars)) == 0) { - // Call finder.check() with the input source - // positioned to the point of the match. + // Call finder.check() with the input source positioned to the point of the match. this->seek(buf_offset + (p - buf), SEEK_SET); if (finder.check()) { return true; @@ -144,8 +130,8 @@ InputSource::findFirst(char const* start_chars, qpdf_offset_t offset, size_t len } else { QTC::TC("libtests", "InputSource first char matched but not string"); } - // This occurrence of the first character wasn't a match. - // Skip over it and keep searching. + // This occurrence of the first character wasn't a match. Skip over it and keep + // searching. ++p; } else { // Trigger reading the next block diff --git a/libqpdf/InsecureRandomDataProvider.cc b/libqpdf/InsecureRandomDataProvider.cc index 5f247167..1c7fb9ef 100644 --- a/libqpdf/InsecureRandomDataProvider.cc +++ b/libqpdf/InsecureRandomDataProvider.cc @@ -21,9 +21,8 @@ long InsecureRandomDataProvider::random() { if (!this->seeded_random) { - // Seed the random number generator with something simple, but - // just to be interesting, don't use the unmodified current - // time. It would be better if this were a more secure seed. + // Seed the random number generator with something simple, but just to be interesting, don't + // use the unmodified current time. It would be better if this were a more secure seed. auto seed = static_cast(QUtil::get_current_time() ^ 0xcccc); #ifdef HAVE_RANDOM ::srandom(seed); diff --git a/libqpdf/JSONHandler.cc b/libqpdf/JSONHandler.cc index f4360a2d..b5c7c35d 100644 --- a/libqpdf/JSONHandler.cc +++ b/libqpdf/JSONHandler.cc @@ -133,12 +133,10 @@ JSONHandler::handle(std::string const& path, JSON j) } if (!handled) { - // It would be nice to include information about what type the - // object was and what types were allowed, but we're relying - // on schema validation to make sure input is properly - // structured before calling the handlers. It would be - // different if this code were trying to be part of a - // general-purpose JSON package. + // It would be nice to include information about what type the object was and what types + // were allowed, but we're relying on schema validation to make sure input is properly + // structured before calling the handlers. It would be different if this code were trying to + // be part of a general-purpose JSON package. QTC::TC("libtests", "JSONHandler unhandled value"); usage("JSON handler: value at " + path + " is not of expected type"); } diff --git a/libqpdf/MD5.cc b/libqpdf/MD5.cc index c0782124..b8e07cf9 100644 --- a/libqpdf/MD5.cc +++ b/libqpdf/MD5.cc @@ -78,8 +78,7 @@ MD5::encodeFile(char const* filename, qpdf_offset_t up_to_offset) } } while (len > 0); if (ferror(file)) { - // Assume, perhaps incorrectly, that errno was set by the - // underlying call to read.... + // Assume, perhaps incorrectly, that errno was set by the underlying call to read.... (void)fclose(file); QUtil::throw_system_error(std::string("MD5: read error on ") + filename); } diff --git a/libqpdf/NNTree.cc b/libqpdf/NNTree.cc index bbdd83f8..129c8734 100644 --- a/libqpdf/NNTree.cc +++ b/libqpdf/NNTree.cc @@ -36,23 +36,18 @@ NNTreeIterator::NNTreeIterator(NNTreeImpl& impl) : void NNTreeIterator::updateIValue(bool allow_invalid) { - // ivalue should never be used inside the class since we return a - // pointer/reference to it. Every bit of code that ever changes - // what object the iterator points to should take care to call - // updateIValue. Failure to do this means that any old references - // to *iter will point to incorrect objects, though the next - // dereference of the iterator will fix it. This isn't necessarily - // catastrophic, but it would be confusing. The test suite - // attempts to exercise various cases to ensure we don't introduce - // that bug in the future, but sadly it's tricky to verify by - // reasoning about the code that this constraint is always - // satisfied. Whenever we update what the iterator points to, we - // should call setItemNumber, which calls this. If we change what - // the iterator in some other way, such as replacing a value or - // removing an item and making the iterator point at a different - // item in potentially the same position, we must call - // updateIValue as well. These cases are handled, and for good - // measure, we also call updateIValue in operator* and operator->. + // ivalue should never be used inside the class since we return a pointer/reference to it. Every + // bit of code that ever changes what object the iterator points to should take care to call + // updateIValue. Failure to do this means that any old references to *iter will point to + // incorrect objects, though the next dereference of the iterator will fix it. This isn't + // necessarily catastrophic, but it would be confusing. The test suite attempts to exercise + // various cases to ensure we don't introduce that bug in the future, but sadly it's tricky to + // verify by reasoning about the code that this constraint is always satisfied. Whenever we + // update what the iterator points to, we should call setItemNumber, which calls this. If we + // change what the iterator in some other way, such as replacing a value or removing an item and + // making the iterator point at a different item in potentially the same position, we must call + // updateIValue as well. These cases are handled, and for good measure, we also call + // updateIValue in operator* and operator->. bool okay = false; if ((item_number >= 0) && this->node.isDictionary()) { @@ -228,12 +223,11 @@ NNTreeIterator::resetLimits(QPDFObjectHandle node, std::list::itera void NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterator parent) { - // Split some node along the path to the item pointed to by this - // iterator, and adjust the iterator so it points to the same - // item. + // Split some node along the path to the item pointed to by this iterator, and adjust the + // iterator so it points to the same item. - // In examples, for simplicity, /Nums is show to just contain - // numbers instead of pairs. Imagine this tree: + // In examples, for simplicity, /Nums is show to just contain numbers instead of pairs. Imagine + // this tree: // // root: << /Kids [ A B C D ] >> // A: << /Nums [ 1 2 3 4 ] >> @@ -260,8 +254,7 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato throw std::logic_error("NNTreeIterator::split called an invalid iterator"); } - // Find the array we actually need to split, which is either this - // node's kids or items. + // Find the array we actually need to split, which is either this node's kids or items. auto kids = to_split.getKey("/Kids"); int nkids = kids.isArray() ? kids.getArrayNItems() : 0; auto items = to_split.getKey(impl.details.itemsKey()); @@ -294,30 +287,22 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato bool is_root = (parent == this->path.end()); bool is_leaf = (nitems > 0); - // CURRENT STATE: tree is in original state; iterator is valid and - // unchanged. + // CURRENT STATE: tree is in original state; iterator is valid and unchanged. if (is_root) { - // What we want to do is to create a new node for the second - // half of the items and put it in the parent's /Kids array - // right after the element that points to the current to_split - // node, but if we're splitting root, there is no parent, so - // handle that first. - - // In the non-root case, parent points to the path element - // whose /Kids contains the first half node, and the first - // half node is to_split. If we are splitting the root, we - // need to push everything down a level, but we want to keep - // the actual root object the same so that indirect references - // to it remain intact (and also in case it might be a direct - // object, which it shouldn't be but that case probably exists - // in the wild). To achieve this, we create a new node for the - // first half and then replace /Kids in the root to contain - // it. Then we adjust the path so that the first element is - // root and the second element, if any, is the new first half. - // In this way, we make the root case identical to the - // non-root case so remaining logic can handle them in the - // same way. + // What we want to do is to create a new node for the second half of the items and put it in + // the parent's /Kids array right after the element that points to the current to_split + // node, but if we're splitting root, there is no parent, so handle that first. + + // In the non-root case, parent points to the path element whose /Kids contains the first + // half node, and the first half node is to_split. If we are splitting the root, we need to + // push everything down a level, but we want to keep the actual root object the same so that + // indirect references to it remain intact (and also in case it might be a direct object, + // which it shouldn't be but that case probably exists in the wild). To achieve this, we + // create a new node for the first half and then replace /Kids in the root to contain it. + // Then we adjust the path so that the first element is root and the second element, if any, + // is the new first half. In this way, we make the root case identical to the non-root case + // so remaining logic can handle them in the same way. auto first_node = impl.qpdf.makeIndirectObject(QPDFObjectHandle::newDictionary()); first_node.replaceKey(key, first_half); @@ -339,12 +324,11 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato to_split = first_node; } - // CURRENT STATE: parent is guaranteed to be defined, and we have - // the invariants that parent[/Kids][kid_number] == to_split and - // (++parent).node == to_split. + // CURRENT STATE: parent is guaranteed to be defined, and we have the invariants that + // parent[/Kids][kid_number] == to_split and (++parent).node == to_split. - // Create a second half array, and transfer the second half of the - // items into the second half array. + // Create a second half array, and transfer the second half of the items into the second half + // array. QPDFObjectHandle second_half = QPDFObjectHandle::newArray(); int start_idx = ((n / 2) & ~1); while (first_half.getArrayNItems() > start_idx) { @@ -358,15 +342,13 @@ NNTreeIterator::split(QPDFObjectHandle to_split, std::list::iterato second_node.replaceKey(key, second_half); resetLimits(second_node, parent); - // CURRENT STATE: half the items from the kids or items array in - // the node being split have been moved into a new node. The new - // node is not yet attached to the tree. The iterator may have a + // CURRENT STATE: half the items from the kids or items array in the node being split have been + // moved into a new node. The new node is not yet attached to the tree. The iterator may have a // path element or leaf node that is out of bounds. - // We need to adjust the parent to add the second node to /Kids - // and, if needed, update kid_number to traverse through it. We - // need to update to_split's path element, or the node if this is - // a leaf, so that the kid/item number points to the right place. + // We need to adjust the parent to add the second node to /Kids and, if needed, update + // kid_number to traverse through it. We need to update to_split's path element, or the node if + // this is a leaf, so that the kid/item number points to the right place. auto parent_kids = parent->node.getKey("/Kids"); parent_kids.insertItem(parent->kid_number + 1, second_node); @@ -430,8 +412,7 @@ NNTreeIterator::insertAfter(QPDFObjectHandle key, QPDFObjectHandle value) void NNTreeIterator::remove() { - // Remove this item, leaving the tree valid and this iterator - // pointing to the next item. + // Remove this item, leaving the tree valid and this iterator pointing to the next item. if (!valid()) { throw std::logic_error("attempt made to remove an invalid iterator"); @@ -450,34 +431,32 @@ NNTreeIterator::remove() // There are still items left if ((this->item_number == 0) || (this->item_number == nitems)) { - // We removed either the first or last item of an items array - // that remains non-empty, so we have to adjust limits. + // We removed either the first or last item of an items array that remains non-empty, so + // we have to adjust limits. QTC::TC("qpdf", "NNTree remove reset limits"); resetLimits(this->node, lastPathElement()); } if (this->item_number == nitems) { - // We removed the last item of a non-empty items array, so - // advance to the successor of the previous item. + // We removed the last item of a non-empty items array, so advance to the successor of + // the previous item. QTC::TC("qpdf", "NNTree erased last item"); this->item_number -= 2; increment(false); } else if (this->item_number < nitems) { - // We don't have to do anything since the removed item's - // successor now occupies its former location. + // We don't have to do anything since the removed item's successor now occupies its + // former location. QTC::TC("qpdf", "NNTree erased non-last item"); updateIValue(); } else { - // We already checked to ensure this condition would not - // happen. + // We already checked to ensure this condition would not happen. throw std::logic_error("NNTreeIterator::remove: item_number > nitems after erase"); } return; } if (this->path.empty()) { - // Special case: if this is the root node, we can leave it - // empty. + // Special case: if this is the root node, we can leave it empty. QTC::TC("qpdf", "NNTree erased all items on leaf/root"); setItemNumber(impl.oh, -1); return; @@ -485,9 +464,8 @@ NNTreeIterator::remove() QTC::TC("qpdf", "NNTree items is empty after remove"); - // We removed the last item from this items array, so we need to - // remove this node from the parent on up the tree. Then we need - // to position ourselves at the removed item's successor. + // We removed the last item from this items array, so we need to remove this node from the + // parent on up the tree. Then we need to position ourselves at the removed item's successor. bool done = false; while (!done) { auto element = lastPathElement(); @@ -503,8 +481,7 @@ NNTreeIterator::remove() resetLimits(element->node, parent); } if (element->kid_number == nkids) { - // Move to the successor of the last child of the - // previous kid. + // Move to the successor of the last child of the previous kid. setItemNumber(QPDFObjectHandle(), -1); --element->kid_number; deepen(kids.getArrayItem(element->kid_number), false, true); @@ -523,8 +500,7 @@ NNTreeIterator::remove() } done = true; } else if (parent == this->path.end()) { - // We erased the very last item. Convert the root to an - // empty items array. + // We erased the very last item. Convert the root to an empty items array. QTC::TC("qpdf", "NNTree non-flat tree is empty after remove"); element->node.removeKey("/Kids"); element->node.replaceKey(impl.details.itemsKey(), QPDFObjectHandle::newArray()); @@ -608,9 +584,8 @@ NNTreeIterator::addPathElement(QPDFObjectHandle const& node, int kid_number) bool NNTreeIterator::deepen(QPDFObjectHandle node, bool first, bool allow_empty) { - // Starting at this node, descend through the first or last kid - // until we reach a node with items. If we succeed, return true; - // otherwise return false and leave path alone. + // Starting at this node, descend through the first or last kid until we reach a node with + // items. If we succeed, return true; otherwise return false and leave path alone. auto opath = this->path; bool failed = false; diff --git a/libqpdf/Pl_AES_PDF.cc b/libqpdf/Pl_AES_PDF.cc index a71052a5..e1a3ea33 100644 --- a/libqpdf/Pl_AES_PDF.cc +++ b/libqpdf/Pl_AES_PDF.cc @@ -98,9 +98,8 @@ Pl_AES_PDF::finish() flush(false); } if (!this->disable_padding) { - // Pad as described in section 3.5.1 of version 1.7 of the PDF - // specification, including providing an entire block of padding - // if the input was a multiple of 16 bytes. + // Pad as described in section 3.5.1 of version 1.7 of the PDF specification, including + // providing an entire block of padding if the input was a multiple of 16 bytes. unsigned char pad = QIntC::to_uchar(this->buf_size - this->offset); memset(this->inbuf + this->offset, pad, pad); this->offset = this->buf_size; @@ -108,11 +107,9 @@ Pl_AES_PDF::finish() } } else { if (this->offset != this->buf_size) { - // This is never supposed to happen as the output is - // always supposed to be padded. However, we have - // encountered files for which the output is not a - // multiple of the block size. In this case, pad with - // zeroes and hope for the best. + // This is never supposed to happen as the output is always supposed to be padded. + // However, we have encountered files for which the output is not a multiple of the + // block size. In this case, pad with zeroes and hope for the best. if (this->offset >= this->buf_size) { throw std::logic_error("buffer overflow in AES encryption" " pipeline"); @@ -156,19 +153,19 @@ Pl_AES_PDF::flush(bool strip_padding) bool return_after_init = false; if (this->cbc_mode) { if (encrypt) { - // Set cbc_block to the initialization vector, and if - // not zero, write it to the output stream. + // Set cbc_block to the initialization vector, and if not zero, write it to the + // output stream. initializeVector(); if (!(this->use_zero_iv || this->use_specified_iv)) { getNext()->write(this->cbc_block, this->buf_size); } } else if (this->use_zero_iv || this->use_specified_iv) { - // Initialize vector with zeroes; zero vector was not - // written to the beginning of the input file. + // Initialize vector with zeroes; zero vector was not written to the beginning of + // the input file. initializeVector(); } else { - // Take the first block of input as the initialization - // vector. There's nothing to write at this time. + // Take the first block of input as the initialization vector. There's nothing to + // write at this time. memcpy(this->cbc_block, this->inbuf, this->buf_size); this->offset = 0; return_after_init = true; diff --git a/libqpdf/Pl_ASCII85Decoder.cc b/libqpdf/Pl_ASCII85Decoder.cc index e789a753..fd36722a 100644 --- a/libqpdf/Pl_ASCII85Decoder.cc +++ b/libqpdf/Pl_ASCII85Decoder.cc @@ -91,8 +91,7 @@ Pl_ASCII85Decoder::flush() } QTC::TC("libtests", "Pl_ASCII85Decoder partial flush", (this->pos == 5) ? 0 : 1); - // Reset before calling getNext()->write in case that throws an - // exception. + // Reset before calling getNext()->write in case that throws an exception. auto t = this->pos - 1; this->pos = 0; memset(this->inbuf, 117, 5); diff --git a/libqpdf/Pl_ASCIIHexDecoder.cc b/libqpdf/Pl_ASCIIHexDecoder.cc index 313d8fed..7cc57a70 100644 --- a/libqpdf/Pl_ASCIIHexDecoder.cc +++ b/libqpdf/Pl_ASCIIHexDecoder.cc @@ -79,8 +79,7 @@ Pl_ASCIIHexDecoder::flush() auto ch = static_cast((b[0] << 4) + b[1]); QTC::TC("libtests", "Pl_ASCIIHexDecoder partial flush", (this->pos == 2) ? 0 : 1); - // Reset before calling getNext()->write in case that throws an - // exception. + // Reset before calling getNext()->write in case that throws an exception. this->pos = 0; this->inbuf[0] = '0'; this->inbuf[1] = '0'; diff --git a/libqpdf/Pl_Concatenate.cc b/libqpdf/Pl_Concatenate.cc index ecb20a44..8f974c05 100644 --- a/libqpdf/Pl_Concatenate.cc +++ b/libqpdf/Pl_Concatenate.cc @@ -7,8 +7,7 @@ Pl_Concatenate::Pl_Concatenate(char const* identifier, Pipeline* next) : Pl_Concatenate::~Pl_Concatenate() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_Count.cc b/libqpdf/Pl_Count.cc index cb458f0c..07bb2654 100644 --- a/libqpdf/Pl_Count.cc +++ b/libqpdf/Pl_Count.cc @@ -16,8 +16,7 @@ Pl_Count::Pl_Count(char const* identifier, Pipeline* next) : Pl_Count::~Pl_Count() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_DCT.cc b/libqpdf/Pl_DCT.cc index 5634e022..f82fc2aa 100644 --- a/libqpdf/Pl_DCT.cc +++ b/libqpdf/Pl_DCT.cc @@ -77,8 +77,7 @@ Pl_DCT::Pl_DCT( Pl_DCT::~Pl_DCT() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -92,14 +91,12 @@ Pl_DCT::finish() { m->buf.finish(); - // Using a std::shared_ptr here and passing it into compress - // and decompress causes a memory leak with setjmp/longjmp. Just - // use a pointer and delete it. + // Using a std::shared_ptr here and passing it into compress and decompress causes a + // memory leak with setjmp/longjmp. Just use a pointer and delete it. Buffer* b = m->buf.getBuffer(); if (b->getSize() == 0) { - // Special case: empty data will never succeed and probably - // means we're calling finish a second time from an exception - // handler. + // Special case: empty data will never succeed and probably means we're calling finish a + // second time from an exception handler. delete b; this->getNext()->finish(); return; @@ -114,8 +111,7 @@ Pl_DCT::finish() jerr.pub.error_exit = error_handler; bool error = false; - // The jpeg library is a "C" library, so we use setjmp and longjmp - // for exception handling. + // The jpeg library is a "C" library, so we use setjmp and longjmp for exception handling. if (setjmp(jerr.jmpbuf) == 0) { try { if (m->action == a_compress) { @@ -124,9 +120,8 @@ Pl_DCT::finish() decompress(reinterpret_cast(&cinfo_decompress), b); } } catch (std::exception& e) { - // Convert an exception back to a longjmp so we can ensure - // that the right cleanup happens. This will get converted - // back to an exception. + // Convert an exception back to a longjmp so we can ensure that the right cleanup + // happens. This will get converted back to an exception. jerr.msg = e.what(); longjmp(jerr.jmpbuf, 1); } @@ -205,9 +200,8 @@ init_buffer_source(j_decompress_ptr) static boolean fill_buffer_input_buffer(j_decompress_ptr) { - // The whole JPEG data is expected to reside in the supplied memory - // buffer, so any request for more data beyond the given buffer size - // is treated as an error. + // The whole JPEG data is expected to reside in the supplied memory buffer, so any request for + // more data beyond the given buffer size is treated as an error. throw std::runtime_error("invalid jpeg data reading from buffer"); return TRUE; } @@ -216,8 +210,8 @@ static void skip_buffer_input_data(j_decompress_ptr cinfo, long num_bytes) { if (num_bytes < 0) { - throw std::runtime_error("reading jpeg: jpeg library requested" - " skipping a negative number of bytes"); + throw std::runtime_error( + "reading jpeg: jpeg library requested skipping a negative number of bytes"); } size_t to_skip = QIntC::to_size(num_bytes); if ((to_skip > 0) && (to_skip <= cinfo->src->bytes_in_buffer)) { diff --git a/libqpdf/Pl_Discard.cc b/libqpdf/Pl_Discard.cc index f1078e3a..d9ddaef3 100644 --- a/libqpdf/Pl_Discard.cc +++ b/libqpdf/Pl_Discard.cc @@ -9,8 +9,7 @@ Pl_Discard::Pl_Discard() : Pl_Discard::~Pl_Discard() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_Flate.cc b/libqpdf/Pl_Flate.cc index c3e4a9f5..f43c0b7f 100644 --- a/libqpdf/Pl_Flate.cc +++ b/libqpdf/Pl_Flate.cc @@ -16,16 +16,14 @@ Pl_Flate::Members::Members(size_t out_bufsize, action_e action) : zdata(nullptr) { this->outbuf = QUtil::make_shared_array(out_bufsize); - // Indirect through zdata to reach the z_stream so we don't have - // to include zlib.h in Pl_Flate.hh. This means people using - // shared library versions of qpdf don't have to have zlib - // development files available, which particularly helps in a - // Windows environment. + // Indirect through zdata to reach the z_stream so we don't have to include zlib.h in + // Pl_Flate.hh. This means people using shared library versions of qpdf don't have to have zlib + // development files available, which particularly helps in a Windows environment. this->zdata = new z_stream; if (out_bufsize > UINT_MAX) { - throw std::runtime_error("Pl_Flate: zlib doesn't support buffer" - " sizes larger than unsigned int"); + throw std::runtime_error( + "Pl_Flate: zlib doesn't support buffer sizes larger than unsigned int"); } z_stream& zstream = *(static_cast(this->zdata)); @@ -62,8 +60,7 @@ Pl_Flate::Pl_Flate( Pl_Flate::~Pl_Flate() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -88,8 +85,7 @@ Pl_Flate::write(unsigned char const* data, size_t len) this->identifier + ": Pl_Flate: write() called after finish() called"); } - // Write in chunks in case len is too big to fit in an int. - // Assume int is at least 32 bits. + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; unsigned char const* buf = data; @@ -105,20 +101,18 @@ void Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) { if (len > UINT_MAX) { - throw std::runtime_error("Pl_Flate: zlib doesn't support data" - " blocks larger than int"); + throw std::runtime_error("Pl_Flate: zlib doesn't support data blocks larger than int"); } z_stream& zstream = *(static_cast(m->zdata)); - // zlib is known not to modify the data pointed to by next_in but - // doesn't declare the field value const unless compiled to do so. + // zlib is known not to modify the data pointed to by next_in but doesn't declare the field + // value const unless compiled to do so. zstream.next_in = const_cast(data); zstream.avail_in = QIntC::to_uint(len); if (!m->initialized) { int err = Z_OK; - // deflateInit and inflateInit are macros that use old-style - // casts. + // deflateInit and inflateInit are macros that use old-style casts. #if ((defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406) || defined(__clang__)) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wold-style-cast" @@ -147,21 +141,18 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) } if ((m->action == a_inflate) && (err != Z_OK) && zstream.msg && (strcmp(zstream.msg, "incorrect data check") == 0)) { - // Other PDF readers ignore this specific error. Combining - // this with Z_SYNC_FLUSH enables qpdf to handle some - // broken zlib streams without losing data. + // Other PDF readers ignore this specific error. Combining this with Z_SYNC_FLUSH + // enables qpdf to handle some broken zlib streams without losing data. err = Z_STREAM_END; } switch (err) { case Z_BUF_ERROR: - // Probably shouldn't be able to happen, but possible as a - // boundary condition: if the last call to inflate exactly - // filled the output buffer, it's possible that the next - // call to inflate could have nothing to do. There are PDF - // files in the wild that have this error (including at - // least one in qpdf's test suite). In some cases, we want - // to know about this, because it indicates incorrect - // compression, so call a callback if provided. + // Probably shouldn't be able to happen, but possible as a boundary condition: if the + // last call to inflate exactly filled the output buffer, it's possible that the next + // call to inflate could have nothing to do. There are PDF files in the wild that have + // this error (including at least one in qpdf's test suite). In some cases, we want to + // know about this, because it indicates incorrect compression, so call a callback if + // provided. this->warn("input stream is complete but output may still be valid", err); done = true; break; @@ -173,9 +164,8 @@ Pl_Flate::handleData(unsigned char const* data, size_t len, int flush) case Z_OK: { if ((zstream.avail_in == 0) && (zstream.avail_out > 0)) { - // There is nothing left to read, and there was - // sufficient buffer space to write everything we - // needed, so we're done for now. + // There is nothing left to read, and there was sufficient buffer space to write + // everything we needed, so we're done for now. done = true; } uLong ready = QIntC::to_ulong(m->out_bufsize - zstream.avail_out); diff --git a/libqpdf/Pl_Function.cc b/libqpdf/Pl_Function.cc index 2cb22926..c75df2a4 100644 --- a/libqpdf/Pl_Function.cc +++ b/libqpdf/Pl_Function.cc @@ -41,8 +41,7 @@ Pl_Function::Pl_Function(char const* identifier, Pipeline* next, writer_c_char_t Pl_Function::~Pl_Function() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_LZWDecoder.cc b/libqpdf/Pl_LZWDecoder.cc index 8e5fd9d1..4ffcaa3f 100644 --- a/libqpdf/Pl_LZWDecoder.cc +++ b/libqpdf/Pl_LZWDecoder.cc @@ -149,9 +149,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) this->eod = true; } else { if (this->last_code != 256) { - // Add to the table from last time. New table entry would - // be what we read last plus the first character of what - // we're reading now. + // Add to the table from last time. New table entry would be what we read last plus the + // first character of what we're reading now. unsigned char next = '\0'; unsigned int table_size = QIntC::to_uint(table.size()); if (code < 256) { @@ -162,10 +161,8 @@ Pl_LZWDecoder::handleCode(unsigned int code) if (idx > table_size) { throw std::runtime_error("LZWDecoder: bad code received"); } else if (idx == table_size) { - // The encoder would have just created this entry, - // so the first character of this entry would have - // been the same as the first character of the - // last entry. + // The encoder would have just created this entry, so the first character of + // this entry would have been the same as the first character of the last entry. QTC::TC("libtests", "Pl_LZWDecoder last was table size"); next = getFirstChar(this->last_code); } else { diff --git a/libqpdf/Pl_MD5.cc b/libqpdf/Pl_MD5.cc index c0714839..8d45f17a 100644 --- a/libqpdf/Pl_MD5.cc +++ b/libqpdf/Pl_MD5.cc @@ -19,8 +19,7 @@ Pl_MD5::write(unsigned char const* buf, size_t len) this->in_progress = true; } - // Write in chunks in case len is too big to fit in an int. - // Assume int is at least 32 bits. + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; unsigned char const* data = buf; diff --git a/libqpdf/Pl_OStream.cc b/libqpdf/Pl_OStream.cc index 28a08bdc..73fbad21 100644 --- a/libqpdf/Pl_OStream.cc +++ b/libqpdf/Pl_OStream.cc @@ -15,8 +15,7 @@ Pl_OStream::Pl_OStream(char const* identifier, std::ostream& os) : Pl_OStream::~Pl_OStream() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_PNGFilter.cc b/libqpdf/Pl_PNGFilter.cc index b9e297d7..4c2dd623 100644 --- a/libqpdf/Pl_PNGFilter.cc +++ b/libqpdf/Pl_PNGFilter.cc @@ -33,8 +33,8 @@ Pl_PNGFilter::Pl_PNGFilter( } if (!((bits_per_sample == 1) || (bits_per_sample == 2) || (bits_per_sample == 4) || (bits_per_sample == 8) || (bits_per_sample == 16))) { - throw std::runtime_error("PNGFilter created with invalid bits_per_sample not" - " 1, 2, 4, 8, or 16"); + throw std::runtime_error( + "PNGFilter created with invalid bits_per_sample not 1, 2, 4, 8, or 16"); } this->bytes_per_pixel = ((bits_per_sample * samples_per_pixel) + 7) / 8; unsigned long long bpr = ((columns * bits_per_sample * samples_per_pixel) + 7) / 8; diff --git a/libqpdf/Pl_QPDFTokenizer.cc b/libqpdf/Pl_QPDFTokenizer.cc index f2612e85..576c2bfb 100644 --- a/libqpdf/Pl_QPDFTokenizer.cc +++ b/libqpdf/Pl_QPDFTokenizer.cc @@ -23,8 +23,7 @@ Pl_QPDFTokenizer::Pl_QPDFTokenizer( Pl_QPDFTokenizer::~Pl_QPDFTokenizer() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_RunLength.cc b/libqpdf/Pl_RunLength.cc index d9e6799a..d1a5e318 100644 --- a/libqpdf/Pl_RunLength.cc +++ b/libqpdf/Pl_RunLength.cc @@ -18,8 +18,7 @@ Pl_RunLength::Pl_RunLength(char const* identifier, Pipeline* next, action_e acti Pl_RunLength::~Pl_RunLength() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void @@ -135,10 +134,9 @@ Pl_RunLength::flush_encode() void Pl_RunLength::finish() { - // When decoding, we might have read a length byte not followed by - // data, which means the stream was terminated early, but we will - // just ignore this case since this is the only sensible thing to - // do. + // When decoding, we might have read a length byte not followed by data, which means the stream + // was terminated early, but we will just ignore this case since this is the only sensible thing + // to do. if (m->action == a_encode) { flush_encode(); unsigned char ch = 128; diff --git a/libqpdf/Pl_SHA2.cc b/libqpdf/Pl_SHA2.cc index f431ff7d..04ef924c 100644 --- a/libqpdf/Pl_SHA2.cc +++ b/libqpdf/Pl_SHA2.cc @@ -20,8 +20,7 @@ Pl_SHA2::write(unsigned char const* buf, size_t len) this->in_progress = true; } - // Write in chunks in case len is too big to fit in an int. - // Assume int is at least 32 bits. + // Write in chunks in case len is too big to fit in an int. Assume int is at least 32 bits. static size_t const max_bytes = 1 << 30; size_t bytes_left = len; unsigned char const* data = buf; diff --git a/libqpdf/Pl_StdioFile.cc b/libqpdf/Pl_StdioFile.cc index 918aacde..a95d4898 100644 --- a/libqpdf/Pl_StdioFile.cc +++ b/libqpdf/Pl_StdioFile.cc @@ -19,8 +19,7 @@ Pl_StdioFile::Pl_StdioFile(char const* identifier, FILE* f) : Pl_StdioFile::~Pl_StdioFile() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/Pl_String.cc b/libqpdf/Pl_String.cc index 0bee11b3..40c4b56f 100644 --- a/libqpdf/Pl_String.cc +++ b/libqpdf/Pl_String.cc @@ -15,8 +15,7 @@ Pl_String::Pl_String(char const* identifier, Pipeline* next, std::string& s) : Pl_String::~Pl_String() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } void diff --git a/libqpdf/QPDF.cc b/libqpdf/QPDF.cc index 64ff4715..6f718742 100644 --- a/libqpdf/QPDF.cc +++ b/libqpdf/QPDF.cc @@ -106,9 +106,8 @@ namespace throwException() { throw std::logic_error("QPDF operation attempted on a QPDF object with no input " - "source." - " QPDF operations are invalid before processFile (or another" - " process method) or after closeInputSource"); + "source. QPDF operations are invalid before processFile (or " + "another process method) or after closeInputSource"); } }; } // namespace diff --git a/libqpdf/QPDFAnnotationObjectHelper.cc b/libqpdf/QPDFAnnotationObjectHelper.cc index 81ea5a7f..b967a5b3 100644 --- a/libqpdf/QPDFAnnotationObjectHelper.cc +++ b/libqpdf/QPDFAnnotationObjectHelper.cc @@ -54,13 +54,10 @@ QPDFAnnotationObjectHelper::getAppearanceStream(std::string const& which, std::s if (ap.isDictionary()) { QPDFObjectHandle ap_sub = ap.getKey(which); if (ap_sub.isStream()) { - // According to the spec, Appearance State is supposed to - // refer to a subkey of the appearance stream when /AP is - // a dictionary, but files have been seen in the wild - // where Appearance State is `/N` and `/AP` is a stream. - // Therefore, if `which` points to a stream, disregard - // state and just use the stream. See qpdf issue #949 for - // details. + // According to the spec, Appearance State is supposed to refer to a subkey of the + // appearance stream when /AP is a dictionary, but files have been seen in the wild + // where Appearance State is `/N` and `/AP` is a stream. Therefore, if `which` points to + // a stream, disregard state and just use the stream. See qpdf issue #949 for details. QTC::TC("qpdf", "QPDFAnnotationObjectHelper AP stream"); return ap_sub; } @@ -85,84 +82,66 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( return ""; } - // The appearance matrix computed by this method is the - // transformation matrix that needs to be in effect when drawing - // this annotation's appearance stream on the page. The algorithm - // for computing the appearance matrix described in section 12.5.5 - // of the ISO-32000 PDF spec is similar but not identical to what - // we are doing here. + // The appearance matrix computed by this method is the transformation matrix that needs to be + // in effect when drawing this annotation's appearance stream on the page. The algorithm for + // computing the appearance matrix described in section 12.5.5 of the ISO-32000 PDF spec is + // similar but not identical to what we are doing here. - // When rendering an appearance stream associated with an - // annotation, there are four relevant components: + // When rendering an appearance stream associated with an annotation, there are four relevant + // components: // // * The appearance stream's bounding box (/BBox) // * The appearance stream's matrix (/Matrix) // * The annotation's rectangle (/Rect) - // * In the case of form fields with the NoRotate flag, the - // page's rotation + // * In the case of form fields with the NoRotate flag, the page's rotation - // When rendering a form xobject in isolation, just drawn with a - // /Do operator, there is no form field, so page rotation is not - // relevant, and there is no annotation, so /Rect is not relevant, - // so only /BBox and /Matrix are relevant. The effect of these are - // as follows: + // When rendering a form xobject in isolation, just drawn with a /Do operator, there is no form + // field, so page rotation is not relevant, and there is no annotation, so /Rect is not + // relevant, so only /BBox and /Matrix are relevant. The effect of these are as follows: // * /BBox is treated as a clipping region - // * /Matrix is applied as a transformation prior to rendering the - // appearance stream. - - // There is no relationship between /BBox and /Matrix in this - // case. - - // When rendering a form xobject in the context of an annotation, - // things are a little different. In particular, a matrix is - // established such that /BBox, when transformed by /Matrix, would - // fit completely inside of /Rect. /BBox is no longer a clipping - // region. To illustrate the difference, consider a /Matrix of - // [2 0 0 2 0 0], which is scaling by a factor of two along both - // axes. If the appearance stream drew a rectangle equal to /BBox, - // in the case of the form xobject in isolation, this matrix would - // cause only the lower-left quadrant of the rectangle to be - // visible since the scaling would cause the rest of it to fall - // outside of the clipping region. In the case of the form xobject - // displayed in the context of an annotation, such a matrix would - // have no effect at all because it would be applied to the - // bounding box first, and then when the resulting enclosing - // quadrilateral was transformed to fit into /Rect, the effect of - // the scaling would be undone. - - // Our job is to create a transformation matrix that compensates - // for these differences so that the appearance stream of an - // annotation can be drawn as a regular form xobject. - - // To do this, we perform the following steps, which overlap - // significantly with the algorithm in 12.5.5: - - // 1. Transform the four corners of /BBox by applying /Matrix to - // them, creating an arbitrarily transformed quadrilateral. - - // 2. Find the minimum upright rectangle that encompasses the - // resulting quadrilateral. This is the "transformed appearance - // box", T. - - // 3. Compute matrix A that maps the lower left and upper right - // corners of T to the annotation's /Rect. This can be done by - // scaling so that the sizes match and translating so that the + // * /Matrix is applied as a transformation prior to rendering the appearance stream. + + // There is no relationship between /BBox and /Matrix in this case. + + // When rendering a form xobject in the context of an annotation, things are a little different. + // In particular, a matrix is established such that /BBox, when transformed by /Matrix, would + // fit completely inside of /Rect. /BBox is no longer a clipping region. To illustrate the + // difference, consider a /Matrix of [2 0 0 2 0 0], which is scaling by a factor of two along + // both axes. If the appearance stream drew a rectangle equal to /BBox, in the case of the form + // xobject in isolation, this matrix would cause only the lower-left quadrant of the rectangle + // to be visible since the scaling would cause the rest of it to fall outside of the clipping + // region. In the case of the form xobject displayed in the context of an annotation, such a + // matrix would have no effect at all because it would be applied to the bounding box first, and + // then when the resulting enclosing quadrilateral was transformed to fit into /Rect, the effect + // of the scaling would be undone. + + // Our job is to create a transformation matrix that compensates for these differences so that + // the appearance stream of an annotation can be drawn as a regular form xobject. + + // To do this, we perform the following steps, which overlap significantly with the algorithm + // in 12.5.5: + + // 1. Transform the four corners of /BBox by applying /Matrix to them, creating an arbitrarily + // transformed quadrilateral. + + // 2. Find the minimum upright rectangle that encompasses the resulting quadrilateral. This is + // the "transformed appearance box", T. + + // 3. Compute matrix A that maps the lower left and upper right corners of T to the annotation's + // /Rect. This can be done by scaling so that the sizes match and translating so that the // scaled T exactly overlaps /Rect. - // If the annotation's /F flag has bit 4 set, this means that - // annotation is to be rotated about its upper left corner to - // counteract any rotation of the page so it remains upright. To + // If the annotation's /F flag has bit 4 set, this means that annotation is to be rotated about + // its upper left corner to counteract any rotation of the page so it remains upright. To // achieve this effect, we do the following extra steps: - // 1. Perform the rotation on /BBox box prior to transforming it - // with /Matrix (by replacing matrix with concatenation of - // matrix onto the rotation) + // 1. Perform the rotation on /BBox box prior to transforming it with /Matrix (by replacing + // matrix with concatenation of matrix onto the rotation) // 2. Rotate the destination rectangle by the specified amount - // 3. Apply the rotation to A as computed above to get the final - // appearance matrix. + // 3. Apply the rotation to A as computed above to get the final appearance matrix. QPDFObjectHandle rect_obj = this->oh.getKey("/Rect"); QPDFObjectHandle as = getAppearanceStream("/N").getDict(); @@ -192,14 +171,12 @@ QPDFAnnotationObjectHelper::getPageContentForAppearance( QPDFObjectHandle::Rectangle rect = rect_obj.getArrayAsRectangle(); bool do_rotate = (rotate && (flags & an_no_rotate)); if (do_rotate) { - // If the the annotation flags include the NoRotate bit and - // the page is rotated, we have to rotate the annotation about - // its upper left corner by the same amount in the opposite - // direction so that it will remain upright in absolute - // coordinates. Since the semantics of /Rotate for a page are - // to rotate the page, while the effect of rotating using a - // transformation matrix is to rotate the coordinate system, - // the opposite directionality is explicit in the code. + // If the the annotation flags include the NoRotate bit and the page is rotated, we have to + // rotate the annotation about its upper left corner by the same amount in the opposite + // direction so that it will remain upright in absolute coordinates. Since the semantics of + // /Rotate for a page are to rotate the page, while the effect of rotating using a + // transformation matrix is to rotate the coordinate system, the opposite directionality is + // explicit in the code. QPDFMatrix mr; mr.rotatex90(rotate); mr.concat(matrix); diff --git a/libqpdf/QPDFArgParser.cc b/libqpdf/QPDFArgParser.cc index 7e1980ad..78e5e843 100644 --- a/libqpdf/QPDFArgParser.cc +++ b/libqpdf/QPDFArgParser.cc @@ -139,8 +139,8 @@ QPDFArgParser::addInvalidChoiceHandler(std::string const& arg, param_arg_handler auto i = m->option_table->find(arg); if (i == m->option_table->end()) { QTC::TC("libtests", "QPDFArgParser invalid choice handler to unknown"); - throw std::logic_error("QPDFArgParser: attempt to add invalid choice handler" - " to unknown argument"); + throw std::logic_error( + "QPDFArgParser: attempt to add invalid choice handler to unknown argument"); } auto& oe = i->second; oe.invalid_choice_handler = handler; @@ -231,9 +231,9 @@ QPDFArgParser::invalidHelpArg(std::string const& p) void QPDFArgParser::handleArgFileArguments() { - // Support reading arguments from files. Create a new argv. Ensure - // that argv itself as well as all its contents are automatically - // deleted by using shared pointers to back the pointers in argv. + // Support reading arguments from files. Create a new argv. Ensure that argv itself as well as + // all its contents are automatically deleted by using shared pointers to back the pointers in + // argv. m->new_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); for (int i = 1; i < m->argc; ++i) { char const* argfile = nullptr; @@ -264,12 +264,10 @@ QPDFArgParser::handleArgFileArguments() void QPDFArgParser::handleBashArguments() { - // Do a minimal job of parsing bash_line into arguments. This - // doesn't do everything the shell does (e.g. $(...), variable - // expansion, arithmetic, globs, etc.), but it should be good - // enough for purposes of handling completion. As we build up the - // new argv, we can't use m->new_argv because this code has to - // interoperate with @file arguments, so memory for both ways of + // Do a minimal job of parsing bash_line into arguments. This doesn't do everything the shell + // does (e.g. $(...), variable expansion, arithmetic, globs, etc.), but it should be good enough + // for purposes of handling completion. As we build up the new argv, we can't use m->new_argv + // because this code has to interoperate with @file arguments, so memory for both ways of // fabricating argv has to be protected. bool last_was_backslash = false; @@ -321,12 +319,11 @@ QPDFArgParser::handleBashArguments() } } if (m->bash_argv.empty()) { - // This can't happen if properly invoked by bash, but ensure - // we have a valid argv[0] regardless. + // This can't happen if properly invoked by bash, but ensure we have a valid argv[0] + // regardless. m->bash_argv.push_back(QUtil::make_shared_cstr(m->argv[0])); } - // Explicitly discard any non-space-terminated word. The "current - // word" is handled specially. + // Explicitly discard any non-space-terminated word. The "current word" is handled specially. m->bash_argv_ph = QUtil::make_shared_array(1 + m->bash_argv.size()); for (size_t i = 0; i < m->bash_argv.size(); ++i) { m->bash_argv_ph.get()[i] = m->bash_argv.at(i).get(); @@ -367,12 +364,10 @@ QPDFArgParser::checkCompletion() { // See if we're being invoked from bash completion. std::string bash_point_env; - // On Windows with mingw, there have been times when there appears - // to be no way to distinguish between an empty environment - // variable and an unset variable. There are also conditions under - // which bash doesn't set COMP_LINE. Therefore, enter this logic - // if either COMP_LINE or COMP_POINT are set. They will both be - // set together under ordinary circumstances. + // On Windows with mingw, there have been times when there appears to be no way to distinguish + // between an empty environment variable and an unset variable. There are also conditions under + // which bash doesn't set COMP_LINE. Therefore, enter this logic if either COMP_LINE or + // COMP_POINT are set. They will both be set together under ordinary circumstances. bool got_line = QUtil::get_env("COMP_LINE", &m->bash_line); bool got_point = QUtil::get_env("COMP_POINT", &bash_point_env); if (got_line || got_point) { @@ -385,15 +380,12 @@ QPDFArgParser::checkCompletion() if (p > m->bash_line.length()) { p = m->bash_line.length(); } - // Set bash_cur and bash_prev based on bash_line rather than - // relying on argv. This enables us to use bashcompinit to get - // completion in zsh too since bashcompinit sets COMP_LINE and - // COMP_POINT but doesn't invoke the command with options like - // bash does. - - // p is equal to length of the string. Walk backwards looking - // for the first separator. bash_cur is everything after the - // last separator, possibly empty. + // Set bash_cur and bash_prev based on bash_line rather than relying on argv. This enables + // us to use bashcompinit to get completion in zsh too since bashcompinit sets COMP_LINE and + // COMP_POINT but doesn't invoke the command with options like bash does. + + // p is equal to length of the string. Walk backwards looking for the first separator. + // bash_cur is everything after the last separator, possibly empty. char sep(0); while (p > 0) { --p; @@ -407,10 +399,9 @@ QPDFArgParser::checkCompletion() m->bash_cur = m->bash_line.substr(1 + p, std::string::npos); } if ((sep == ':') || (sep == '=')) { - // Bash sets prev to the non-space separator if any. - // Actually, if there are multiple separators in a row, - // they are all included in prev, but that detail is not - // important to us and not worth coding. + // Bash sets prev to the non-space separator if any. Actually, if there are multiple + // separators in a row, they are all included in prev, but that detail is not important + // to us and not worth coding. m->bash_prev = m->bash_line.substr(p, 1); } else { // Go back to the last separator and set prev based on @@ -429,8 +420,8 @@ QPDFArgParser::checkCompletion() m->bash_prev = m->bash_line.substr(0, p); } if (m->argc == 1) { - // This is probably zsh using bashcompinit. There are a - // few differences in the expected output. + // This is probably zsh using bashcompinit. There are a few differences in the expected + // output. m->zsh_completion = true; } handleBashArguments(); @@ -454,8 +445,7 @@ QPDFArgParser::parseArgs() std::string o_arg(arg); std::string arg_s(arg); if (strcmp(arg, "--") == 0) { - // Special case for -- option, which is used to break out - // of subparsers. + // Special case for -- option, which is used to break out of subparsers. oep = m->option_table->find("--"); end_option = true; if (oep == m->option_table->end()) { @@ -471,11 +461,9 @@ QPDFArgParser::parseArgs() QTC::TC("libtests", "QPDFArgParser single dash"); } - // Prevent --=something from being treated as an empty arg - // by searching for = from after the first character. We - // do this since the empty string in the option table is - // for positional arguments. Besides, it doesn't make - // sense to have an empty option. + // Prevent --=something from being treated as an empty arg by searching for = from after + // the first character. We do this since the empty string in the option table is for + // positional arguments. Besides, it doesn't make sense to have an empty option. arg_s = arg; size_t equal_pos = std::string::npos; if (arg_s.length() > 0) { @@ -489,8 +477,7 @@ QPDFArgParser::parseArgs() if ((!m->bash_completion) && (m->argc == 2) && (m->cur_arg == 1) && m->help_option_table.count(arg_s)) { - // Handle help option, which is only valid as the sole - // option. + // Handle help option, which is only valid as the sole option. QTC::TC("libtests", "QPDFArgParser help option"); oep = m->help_option_table.find(arg_s); help_option = true; @@ -500,8 +487,7 @@ QPDFArgParser::parseArgs() oep = m->option_table->find(arg_s); } } else { - // The empty string maps to the positional argument - // handler. + // The empty string maps to the positional argument handler. QTC::TC("libtests", "QPDFArgParser positional"); oep = m->option_table->find(""); parameter = arg; @@ -522,8 +508,7 @@ QPDFArgParser::parseArgs() std::string message = "--" + arg_s + " must be given as --" + arg_s + "="; if (oe.invalid_choice_handler) { oe.invalid_choice_handler(parameter); - // Method should call usage() or exit. Just in case it - // doesn't... + // Method should call usage() or exit. Just in case it doesn't... message += "option"; } else if (!oe.choices.empty()) { QTC::TC("libtests", "QPDFArgParser required choices"); @@ -609,8 +594,8 @@ QPDFArgParser::addOptionsToCompletions(option_table_t& option_table) std::string base = "--" + arg; if (oe.param_arg_handler) { if (m->zsh_completion) { - // zsh doesn't treat = as a word separator, so add all - // the options so we don't get a space after the =. + // zsh doesn't treat = as a word separator, so add all the options so we don't get a + // space after the =. addChoicesToCompletions(option_table, arg, base + "="); } m->completions.insert(base + "="); diff --git a/libqpdf/QPDFCryptoProvider.cc b/libqpdf/QPDFCryptoProvider.cc index 37f152c9..2a18a366 100644 --- a/libqpdf/QPDFCryptoProvider.cc +++ b/libqpdf/QPDFCryptoProvider.cc @@ -92,8 +92,7 @@ QPDFCryptoProvider::setDefaultProvider_internal(std::string const& name) { if (!m->providers.count(name)) { throw std::logic_error( - "QPDFCryptoProvider: request to set default" - " provider to unknown implementation \"" + + "QPDFCryptoProvider: request to set default provider to unknown implementation \"" + name + "\""); } m->default_provider = name; diff --git a/libqpdf/QPDFCrypto_gnutls.cc b/libqpdf/QPDFCrypto_gnutls.cc index c96cdfbc..ee460416 100644 --- a/libqpdf/QPDFCrypto_gnutls.cc +++ b/libqpdf/QPDFCrypto_gnutls.cc @@ -233,9 +233,8 @@ QPDFCrypto_gnutls::rijndael_process(unsigned char* in_data, unsigned char* out_d this->cipher_ctx, in_data, rijndael_buf_size, out_data, rijndael_buf_size); } - // Gnutls doesn't support AES in ECB (non-CBC) mode, but the - // result is the same as if you just reset the cbc block to all - // zeroes each time. We jump through a few hoops here to make this + // Gnutls doesn't support AES in ECB (non-CBC) mode, but the result is the same as if you just + // reset the cbc block to all zeroes each time. We jump through a few hoops here to make this // work. if (!this->cbc_mode) { static unsigned char zeroes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/libqpdf/QPDFCrypto_openssl.cc b/libqpdf/QPDFCrypto_openssl.cc index 87591eb5..f82230be 100644 --- a/libqpdf/QPDFCrypto_openssl.cc +++ b/libqpdf/QPDFCrypto_openssl.cc @@ -83,8 +83,8 @@ static void check_openssl(int status) { if (status != 1) { - // OpenSSL creates a "queue" of errors; copy the first (innermost) - // error to the exception message. + // OpenSSL creates a "queue" of errors; copy the first (innermost) error to the exception + // message. char buf[256] = ""; ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); std::string what = "OpenSSL error: "; diff --git a/libqpdf/QPDFDocumentHelper.cc b/libqpdf/QPDFDocumentHelper.cc index ad23e6f8..cdafc5fb 100644 --- a/libqpdf/QPDFDocumentHelper.cc +++ b/libqpdf/QPDFDocumentHelper.cc @@ -2,6 +2,5 @@ QPDFDocumentHelper::~QPDFDocumentHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/QPDFEFStreamObjectHelper.cc b/libqpdf/QPDFEFStreamObjectHelper.cc index a7ece6ae..b21c8981 100644 --- a/libqpdf/QPDFEFStreamObjectHelper.cc +++ b/libqpdf/QPDFEFStreamObjectHelper.cc @@ -134,8 +134,8 @@ QPDFEFStreamObjectHelper::newFromStream(QPDFObjectHandle stream) QPDFEFStreamObjectHelper result(stream); stream.getDict().replaceKey("/Type", QPDFObjectHandle::newName("/EmbeddedFile")); Pl_Discard discard; - // The PDF spec specifies use of MD5 here and notes that it is not - // to be used for security. MD5 is known to be insecure. + // The PDF spec specifies use of MD5 here and notes that it is not to be used for security. MD5 + // is known to be insecure. Pl_MD5 md5("EF md5", &discard); Pl_Count count("EF size", &md5); if (!stream.pipeStreamData(&count, nullptr, 0, qpdf_dl_all)) { diff --git a/libqpdf/QPDFEmbeddedFileDocumentHelper.cc b/libqpdf/QPDFEmbeddedFileDocumentHelper.cc index d1c7a05c..fd735e79 100644 --- a/libqpdf/QPDFEmbeddedFileDocumentHelper.cc +++ b/libqpdf/QPDFEmbeddedFileDocumentHelper.cc @@ -1,10 +1,9 @@ #include -// File attachments are stored in the /EmbeddedFiles (name tree) key -// of the /Names dictionary from the document catalog. Each entry -// points to a /FileSpec, which in turn points to one more Embedded -// File Streams. Note that file specs can appear in other places as -// well, such as file attachment annotations, among others. +// File attachments are stored in the /EmbeddedFiles (name tree) key of the /Names dictionary from +// the document catalog. Each entry points to a /FileSpec, which in turn points to one more Embedded +// File Streams. Note that file specs can appear in other places as well, such as file attachment +// annotations, among others. // // root -> /Names -> /EmbeddedFiles = name tree // filename -> filespec diff --git a/libqpdf/QPDFJob_argv.cc b/libqpdf/QPDFJob_argv.cc index 3116b097..4a9addbd 100644 --- a/libqpdf/QPDFJob_argv.cc +++ b/libqpdf/QPDFJob_argv.cc @@ -65,9 +65,9 @@ ArgParser::initOptionTables() this->ap.addFinalCheck([this]() { c_main->checkConfiguration(); }); // add_help is defined in auto_job_help.hh add_help(this->ap); - // Special case: ignore -- at the top level. This undocumented - // behavior is for backward compatibility; it was unintentionally - // the case prior to 10.6, and some users were relying on it. + // Special case: ignore -- at the top level. This undocumented behavior is for backward + // compatibility; it was unintentionally the case prior to 10.6, and some users were relying on + // it. this->ap.selectMainOptionTable(); this->ap.addBare("--", []() {}); } @@ -254,8 +254,7 @@ ArgParser::argPagesPositional(std::string const& arg) range_p = this->accumulated_args.at(1).c_str(); } - // See if the user omitted the range entirely, in which case we - // assume "1-z". + // See if the user omitted the range entirely, in which case we assume "1-z". std::string next_file; if (range_p == nullptr) { if (arg.empty()) { diff --git a/libqpdf/QPDFJob_config.cc b/libqpdf/QPDFJob_config.cc index 7c275f20..e847bcd4 100644 --- a/libqpdf/QPDFJob_config.cc +++ b/libqpdf/QPDFJob_config.cc @@ -25,18 +25,14 @@ QPDFJob::Config* QPDFJob::Config::emptyInput() { if (o.m->infilename == nullptr) { - // Various places in QPDFJob.cc know that the empty string for - // infile means empty. We set it to something other than a - // null pointer as an indication that some input source has - // been specified. This approach means that passing "" as - // the argument to inputFile in job JSON, or equivalently - // using "" as a positional command-line argument would be the - // same as --empty. This probably isn't worth blocking or - // coding around. + // Various places in QPDFJob.cc know that the empty string for infile means empty. We set it + // to something other than a null pointer as an indication that some input source has been + // specified. This approach means that passing "" as the argument to inputFile in job JSON, + // or equivalently using "" as a positional command-line argument would be the same as + // --empty. This probably isn't worth blocking or coding around. o.m->infilename = QUtil::make_shared_cstr(""); } else { - usage("empty input can't be used" - " since input file has already been given"); + usage("empty input can't be used since input file has already been given"); } return this; } @@ -58,8 +54,7 @@ QPDFJob::Config::replaceInput() if ((o.m->outfilename == nullptr) && (!o.m->replace_input)) { o.m->replace_input = true; } else { - usage("replace-input can't be used" - " since output file has already been given"); + usage("replace-input can't be used since output file has already been given"); } return this; } @@ -298,8 +293,7 @@ QPDFJob::Config::jsonOutput(std::string const& parameter) o.m->json_output = true; json(parameter); if (!o.m->json_stream_data_set) { - // No need to set json_stream_data_set -- that indicates - // explicit use of --json-stream-data. + // No need to set json_stream_data_set -- that indicates explicit use of --json-stream-data. o.m->json_stream_data = qpdf_sj_inline; } if (!o.m->decode_level_set) { diff --git a/libqpdf/QPDFJob_json.cc b/libqpdf/QPDFJob_json.cc index 126f9a13..92488df1 100644 --- a/libqpdf/QPDFJob_json.cc +++ b/libqpdf/QPDFJob_json.cc @@ -30,27 +30,20 @@ namespace typedef std::function param_handler_t; typedef std::function json_handler_t; - // The code that calls these methods is automatically - // generated by generate_auto_job. This describes how we - // implement what it does. We keep a stack of handlers in - // json_handlers. The top of the stack is the "current" json - // handler, intially for the top-level object. Whenever we - // encounter a scalar, we add a handler using addBare, - // addParameter, or addChoices. Whenever we encounter a - // dictionary, we first add the dictionary handlers. Then we - // walk into the dictionary and, for each key, we register a - // dict key handler and push it to the stack, then do the same - // process for the key's value. Then we pop the key handler - // off the stack. When we encounter an array, we add the array - // handlers, push an item handler to the stack, call - // recursively for the array's single item (as this is what is - // expected in a schema), and pop the item handler. Note that - // we don't pop dictionary start/end handlers. The dictionary - // handlers and the key handlers are at the same level in - // JSONHandler. This logic is subtle and took several tries to - // get right. It's best understood by carefully understanding - // the behavior of JSONHandler, the JSON schema, and the code - // in generate_auto_job. + // The code that calls these methods is automatically generated by generate_auto_job. This + // describes how we implement what it does. We keep a stack of handlers in json_handlers. + // The top of the stack is the "current" json handler, intially for the top-level object. + // Whenever we encounter a scalar, we add a handler using addBare, addParameter, or + // addChoices. Whenever we encounter a dictionary, we first add the dictionary handlers. + // Then we walk into the dictionary and, for each key, we register a dict key handler and + // push it to the stack, then do the same process for the key's value. Then we pop the key + // handler off the stack. When we encounter an array, we add the array handlers, push an + // item handler to the stack, call recursively for the array's single item (as this is what + // is expected in a schema), and pop the item handler. Note that we don't pop dictionary + // start/end handlers. The dictionary handlers and the key handlers are at the same level in + // JSONHandler. This logic is subtle and took several tries to get right. It's best + // understood by carefully understanding the behavior of JSONHandler, the JSON schema, and + // the code in generate_auto_job. void addBare(bare_handler_t); void addParameter(param_handler_t); @@ -261,9 +254,8 @@ Handlers::setupReplaceInput() void Handlers::beginEncrypt(JSON j) { - // This method is only called if the overall JSON structure - // matches the schema, so we already know that keys that are - // present have the right types. + // This method is only called if the overall JSON structure matches the schema, so we already + // know that keys that are present have the right types. int key_len = 0; std::string user_password; std::string owner_password; @@ -284,14 +276,13 @@ Handlers::beginEncrypt(JSON j) }); if (key_len == 0) { QTC::TC("qpdf", "QPDFJob json encrypt no key length"); - usage("exactly one of 40bit, 128bit, or 256bit must be given;" - " an empty dictionary may be supplied for one of them" - " to set the key length without imposing any restrictions"); + usage("exactly one of 40bit, 128bit, or 256bit must be given; an empty dictionary may be " + "supplied for one of them to set the key length without imposing any restrictions"); } if (!(user_password_seen && owner_password_seen)) { QTC::TC("qpdf", "QPDFJob json encrypt missing password"); - usage("the user and owner password are both required; use the empty" - " string for the user password if you don't want a password"); + usage("the user and owner password are both required; use the empty string for the user " + "password if you don't want a password"); } this->c_enc = c_main->encrypt(key_len, user_password, owner_password); } diff --git a/libqpdf/QPDFNameTreeObjectHelper.cc b/libqpdf/QPDFNameTreeObjectHelper.cc index bfe67ecc..5a9992fb 100644 --- a/libqpdf/QPDFNameTreeObjectHelper.cc +++ b/libqpdf/QPDFNameTreeObjectHelper.cc @@ -36,9 +36,8 @@ static NameTreeDetails name_tree_details; QPDFNameTreeObjectHelper::~QPDFNameTreeObjectHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer. For this specific class, see github issue - // #745. + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific + // class, see github issue #745. } QPDFNameTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : diff --git a/libqpdf/QPDFNumberTreeObjectHelper.cc b/libqpdf/QPDFNumberTreeObjectHelper.cc index f35158d5..95cee9c8 100644 --- a/libqpdf/QPDFNumberTreeObjectHelper.cc +++ b/libqpdf/QPDFNumberTreeObjectHelper.cc @@ -37,9 +37,8 @@ static NumberTreeDetails number_tree_details; QPDFNumberTreeObjectHelper::~QPDFNumberTreeObjectHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer. For this specific class, see github issue - // #745. + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer. For this specific + // class, see github issue #745. } QPDFNumberTreeObjectHelper::Members::Members(QPDFObjectHandle& oh, QPDF& q, bool auto_repair) : diff --git a/libqpdf/QPDFObjGen.cc b/libqpdf/QPDFObjGen.cc index 8e5bd178..f3b19f6c 100644 --- a/libqpdf/QPDFObjGen.cc +++ b/libqpdf/QPDFObjGen.cc @@ -27,8 +27,8 @@ QPDFObjGen::set::add(QPDFObjectHandle const& oh) if (auto* ptr = oh.getObjectPtr()) { return add(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); return false; } } @@ -39,8 +39,8 @@ QPDFObjGen::set::add(QPDFObjectHelper const& helper) if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { return add(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); return false; } } @@ -51,8 +51,8 @@ QPDFObjGen::set::erase(QPDFObjectHandle const& oh) if (auto* ptr = oh.getObjectPtr()) { erase(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); } } @@ -62,7 +62,7 @@ QPDFObjGen::set::erase(QPDFObjectHelper const& helper) if (auto* ptr = helper.getObjectHandle().getObjectPtr()) { erase(ptr->getObjGen()); } else { - throw std::logic_error("attempt to retrieve QPDFObjGen from " - "uninitialized QPDFObjectHandle"); + throw std::logic_error( + "attempt to retrieve QPDFObjGen from uninitialized QPDFObjectHandle"); } } diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc index fa5e52e8..3797ad12 100644 --- a/libqpdf/QPDFObjectHandle.cc +++ b/libqpdf/QPDFObjectHandle.cc @@ -229,11 +229,9 @@ QPDFObjectHandle::isSameObjectAs(QPDFObjectHandle const& rhs) const void QPDFObjectHandle::disconnect() { - // Recursively remove association with any QPDF object. This - // method may only be called during final destruction. - // QPDF::~QPDF() calls it for indirect objects using the object - // pointer itself, so we don't do that here. Other objects call it - // through this method. + // Recursively remove association with any QPDF object. This method may only be called during + // final destruction. QPDF::~QPDF() calls it for indirect objects using the object pointer + // itself, so we don't do that here. Other objects call it through this method. if (!isIndirect()) { this->obj->disconnect(); } @@ -1783,10 +1781,9 @@ QPDFObjectHandle::parseContentStream_data( tokenizer.allowEOF(); bool empty = false; while (QIntC::to_size(input->tell()) < stream_length) { - // Read a token and seek to the beginning. The offset we get - // from this process is the beginning of the next - // non-ignorable (space, comment) token. This way, the offset - // and don't including ignorable content. + // Read a token and seek to the beginning. The offset we get from this process is the + // beginning of the next non-ignorable (space, comment) token. This way, the offset and + // don't including ignorable content. tokenizer.readToken(input, "content", true); qpdf_offset_t offset = input->getLastOffset(); input->seek(offset, SEEK_SET); diff --git a/libqpdf/QPDFObjectHelper.cc b/libqpdf/QPDFObjectHelper.cc index 3696dc03..eb7de06e 100644 --- a/libqpdf/QPDFObjectHelper.cc +++ b/libqpdf/QPDFObjectHelper.cc @@ -2,6 +2,5 @@ QPDFObjectHelper::~QPDFObjectHelper() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } diff --git a/libqpdf/QPDFOutlineObjectHelper.cc b/libqpdf/QPDFOutlineObjectHelper.cc index 37e2c0d2..3b5db47a 100644 --- a/libqpdf/QPDFOutlineObjectHelper.cc +++ b/libqpdf/QPDFOutlineObjectHelper.cc @@ -14,8 +14,8 @@ QPDFOutlineObjectHelper::QPDFOutlineObjectHelper( m(new Members(dh)) { if (depth > 50) { - // Not exercised in test suite, but was tested manually by - // temporarily changing max depth to 1. + // Not exercised in test suite, but was tested manually by temporarily changing max depth + // to 1. return; } if (QPDFOutlineDocumentHelper::Accessor::checkSeen(m->dh, this->oh.getObjGen())) { diff --git a/libqpdf/QPDFPageDocumentHelper.cc b/libqpdf/QPDFPageDocumentHelper.cc index 06ec5ff7..3811d7dd 100644 --- a/libqpdf/QPDFPageDocumentHelper.cc +++ b/libqpdf/QPDFPageDocumentHelper.cc @@ -59,8 +59,8 @@ QPDFPageDocumentHelper::flattenAnnotations(int required_flags, int forbidden_fla if (afdh.getNeedAppearances()) { this->qpdf.getRoot() .getKey("/AcroForm") - .warnIfPossible("document does not have updated appearance streams," - " so form fields will not be flattened"); + .warnIfPossible("document does not have updated appearance streams, so form fields " + "will not be flattened"); } for (auto& ph: getAllPages()) { QPDFObjectHandle resources = ph.getAttribute("/Resources", true); @@ -126,11 +126,10 @@ QPDFPageDocumentHelper::flattenAnnotationsForPage( } new_content += content; } else if (process) { - // If an annotation has no appearance stream, just drop - // the annotation when flattening. This can happen for - // unchecked checkboxes and radio buttons, popup windows - // associated with comments that aren't visible, and other - // types of annotations that aren't visible. + // If an annotation has no appearance stream, just drop the annotation when flattening. + // This can happen for unchecked checkboxes and radio buttons, popup windows associated + // with comments that aren't visible, and other types of annotations that aren't + // visible. QTC::TC("qpdf", "QPDFPageDocumentHelper ignore annotation with no appearance"); } else { new_annots.push_back(aoh.getObjectHandle()); diff --git a/libqpdf/QPDFPageLabelDocumentHelper.cc b/libqpdf/QPDFPageLabelDocumentHelper.cc index 4a9b456f..d94c41fd 100644 --- a/libqpdf/QPDFPageLabelDocumentHelper.cc +++ b/libqpdf/QPDFPageLabelDocumentHelper.cc @@ -57,19 +57,17 @@ QPDFPageLabelDocumentHelper::getLabelsForPageRange( long long new_start_idx, std::vector& new_labels) { - // Start off with a suitable label for the first page. For every - // remaining page, if that page has an explicit entry, copy it. - // Otherwise, let the subsequent page just sequence from the prior - // entry. If there is no entry for the first page, fabricate one - // that would match how the page would look in a new file in which - // it also didn't have an explicit label. + // Start off with a suitable label for the first page. For every remaining page, if that page + // has an explicit entry, copy it. Otherwise, let the subsequent page just sequence from the + // prior entry. If there is no entry for the first page, fabricate one that would match how the + // page would look in a new file in which it also didn't have an explicit label. QPDFObjectHandle label = getLabelForPage(start_idx); if (label.isNull()) { label = QPDFObjectHandle::newDictionary(); label.replaceKey("/St", QPDFObjectHandle::newInteger(1 + new_start_idx)); } - // See if the new label is redundant based on the previous entry - // in the vector. If so, don't add it. + // See if the new label is redundant based on the previous entry in the vector. If so, don't add + // it. size_t size = new_labels.size(); bool skip_first = false; if (size >= 2) { diff --git a/libqpdf/QPDFWriter.cc b/libqpdf/QPDFWriter.cc index 782a0c49..94ce07b9 100644 --- a/libqpdf/QPDFWriter.cc +++ b/libqpdf/QPDFWriter.cc @@ -28,8 +28,7 @@ QPDFWriter::ProgressReporter::~ProgressReporter() { - // Must be explicit and not inline -- see QPDF_DLL_CLASS in - // README-maintainer + // Must be explicit and not inline -- see QPDF_DLL_CLASS in README-maintainer } QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function handler) : @@ -39,8 +38,7 @@ QPDFWriter::FunctionProgressReporter::FunctionProgressReporter(std::function 3) { - // Bit 10 is deprecated and should always be set. This used - // to mean accessibility. There is no way to disable - // accessibility with R > 3. + // Bit 10 is deprecated and should always be set. This used to mean accessibility. There + // is no way to disable accessibility with R > 3. bits_to_clear.erase(10); } @@ -669,12 +664,10 @@ QPDFWriter::copyEncryptionParameters(QPDF& qpdf) m->encrypt_metadata = encrypt.getKey("/EncryptMetadata").getBoolValue(); } if (V >= 4) { - // When copying encryption parameters, use AES even if the - // original file did not. Acrobat doesn't create files - // with V >= 4 that don't use AES, and the logic of - // figuring out whether AES is used or not is complicated - // with /StmF, /StrF, and /EFF all potentially having - // different values. + // When copying encryption parameters, use AES even if the original file did not. + // Acrobat doesn't create files with V >= 4 that don't use AES, and the logic of + // figuring out whether AES is used or not is complicated with /StmF, /StrF, and /EFF + // all potentially having different values. m->encrypt_use_aes = true; } QTC::TC("qpdf", "QPDFWriter copy encrypt metadata", m->encrypt_metadata ? 0 : 1); @@ -757,11 +750,9 @@ QPDFWriter::parseVersion(std::string const& version, int& major, int& minor) con } std::string tmp = std::to_string(major) + "." + std::to_string(minor); if (tmp != version) { - // The version number in the input is probably invalid. This - // happens with some files that are designed to exercise bugs, - // such as files in the fuzzer corpus. Unfortunately - // QPDFWriter doesn't have a way to give a warning, so we just - // ignore this case. + // The version number in the input is probably invalid. This happens with some files that + // are designed to exercise bugs, such as files in the fuzzer corpus. Unfortunately + // QPDFWriter doesn't have a way to give a warning, so we just ignore this case. } } @@ -826,15 +817,13 @@ QPDFWriter::setEncryptionParametersInternal( m->encryption_dictionary["/EncryptMetadata"] = "false"; } if ((V == 4) || (V == 5)) { - // The spec says the value for the crypt filter key can be - // anything, and xpdf seems to agree. However, Adobe Reader - // won't open our files unless we use /StdCF. + // The spec says the value for the crypt filter key can be anything, and xpdf seems to + // agree. However, Adobe Reader won't open our files unless we use /StdCF. m->encryption_dictionary["/StmF"] = "/StdCF"; m->encryption_dictionary["/StrF"] = "/StdCF"; std::string method = (m->encrypt_use_aes ? ((V < 5) ? "/AESV2" : "/AESV3") : "/V2"); - // The PDF spec says the /Length key is optional, but the PDF - // previewer on some versions of MacOS won't open encrypted - // files without it. + // The PDF spec says the /Length key is optional, but the PDF previewer on some versions of + // MacOS won't open encrypted files without it. m->encryption_dictionary["/CF"] = "<< /StdCF << /AuthEvent /DocOpen /CFM " + method + " /Length " + std::string((V < 5) ? "16" : "32") + " >> >>"; } @@ -950,12 +939,10 @@ QPDFWriter::PipelinePopper::~PipelinePopper() qpdf_assert_debug(qw->m->pipeline_stack.size() >= 2); qw->m->pipeline->finish(); qpdf_assert_debug(dynamic_cast(qw->m->pipeline_stack.back()) == qw->m->pipeline); - // It might be possible for this assertion to fail if - // writeLinearized exits by exception when deterministic ID, but I - // don't think so. As of this writing, this is the only case in - // which two dynamically allocated PipelinePopper objects ever - // exist at the same time, so the assertion will fail if they get - // popped out of order from automatic destruction. + // It might be possible for this assertion to fail if writeLinearized exits by exception when + // deterministic ID, but I don't think so. As of this writing, this is the only case in which + // two dynamically allocated PipelinePopper objects ever exist at the same time, so the + // assertion will fail if they get popped out of order from automatic destruction. qpdf_assert_debug(qw->m->pipeline->getIdentifier() == stack_id); delete qw->m->pipeline_stack.back(); qw->m->pipeline_stack.pop_back(); @@ -978,9 +965,8 @@ void QPDFWriter::adjustAESStreamLength(size_t& length) { if (m->encrypted && (!m->cur_data_key.empty()) && m->encrypt_use_aes) { - // Stream length will be padded with 1 to 16 bytes to end up - // as a multiple of 16. It will also be prepended by 16 bits - // of random data. + // Stream length will be padded with 1 to 16 bytes to end up as a multiple of 16. It will + // also be prepended by 16 bits of random data. length += 32 - (length & 0xf); } } @@ -1006,8 +992,8 @@ QPDFWriter::pushEncryptionFilter(PipelinePopper& pp) } pushPipeline(p); } - // Must call this unconditionally so we can call popPipelineStack - // to balance pushEncryptionFilter(). + // Must call this unconditionally so we can call popPipelineStack to balance + // pushEncryptionFilter(). activatePipelineStack(pp); } @@ -1031,8 +1017,7 @@ QPDFWriter::pushMD5Pipeline(PipelinePopper& pp) qpdf_assert_debug(m->pipeline->getCount() == 0); m->md5_pipeline = new Pl_MD5("qpdf md5", m->pipeline); m->md5_pipeline->persistAcrossFinish(true); - // Special case code in popPipelineStack clears m->md5_pipeline - // upon deletion. + // Special case code in popPipelineStack clears m->md5_pipeline upon deletion. pushPipeline(m->md5_pipeline); activatePipelineStack(pp); } @@ -1061,8 +1046,7 @@ QPDFWriter::openObject(int objid) void QPDFWriter::closeObject(int objid) { - // Write a newline before endobj as it makes the file easier to - // repair. + // Write a newline before endobj as it makes the file easier to repair. writeString("\nendobj\n"); writeStringQDF("\n"); m->lengths[objid] = m->pipeline->getCount() - m->xref[objid].getOffset(); @@ -1077,8 +1061,7 @@ QPDFWriter::assignCompressedObjectNumbers(QPDFObjGen const& og) return; } - // Reserve numbers for the objects that belong to this object - // stream. + // Reserve numbers for the objects that belong to this object stream. for (auto const& iter: m->object_stream_to_objects[objid]) { m->obj_renumber[iter] = m->next_objid++; } @@ -1088,26 +1071,21 @@ void QPDFWriter::enqueueObject(QPDFObjectHandle object) { if (object.isIndirect()) { - // This owner check can only be done for indirect objects. It - // is possible for a direct object to have an owning QPDF that - // is from another file if a direct QPDFObjectHandle from one - // file was insert into another file without copying. Doing - // that is safe even if the original QPDF gets destroyed, - // which just disconnects the QPDFObjectHandle from its owner. + // This owner check can only be done for indirect objects. It is possible for a direct + // object to have an owning QPDF that is from another file if a direct QPDFObjectHandle from + // one file was insert into another file without copying. Doing that is safe even if the + // original QPDF gets destroyed, which just disconnects the QPDFObjectHandle from its owner. if (object.getOwningQPDF() != &(m->pdf)) { QTC::TC("qpdf", "QPDFWriter foreign object"); - throw std::logic_error("QPDFObjectHandle from different QPDF found while writing." - " Use QPDF::copyForeignObject to add objects from" - " another file."); + throw std::logic_error("QPDFObjectHandle from different QPDF found while writing. Use " + "QPDF::copyForeignObject to add objects from another file."); } if (m->qdf_mode && object.isStreamOfType("/XRef")) { - // As a special case, do not output any extraneous XRef - // streams in QDF mode. Doing so will confuse fix-qdf, - // which expects to see only one XRef stream at the end of - // the file. This case can occur when creating a QDF from - // a file with object streams when preserving unreferenced - // objects since the old cross reference streams are not + // As a special case, do not output any extraneous XRef streams in QDF mode. Doing so + // will confuse fix-qdf, which expects to see only one XRef stream at the end of the + // file. This case can occur when creating a QDF from a file with object streams when + // preserving unreferenced objects since the old cross reference streams are not // actually referenced by object number. QTC::TC("qpdf", "QPDFWriter ignore XRef in qdf mode"); return; @@ -1117,12 +1095,10 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) if (m->obj_renumber.count(og) == 0) { if (m->object_to_object_stream.count(og)) { - // This is in an object stream. Don't process it - // here. Instead, enqueue the object stream. Object - // streams always have generation 0. + // This is in an object stream. Don't process it here. Instead, enqueue the object + // stream. Object streams always have generation 0. int stream_id = m->object_to_object_stream[og]; - // Detect loops by storing invalid object ID 0, which - // will get overwritten later. + // Detect loops by storing invalid object ID 0, which will get overwritten later. m->obj_renumber[og] = 0; enqueueObject(m->pdf.getObjectByID(stream_id, 0)); } else { @@ -1130,9 +1106,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) m->obj_renumber[og] = m->next_objid++; if ((og.getGen() == 0) && m->object_stream_to_objects.count(og.getObj())) { - // For linearized files, uncompressed objects go - // at end, and we take care of assigning numbers - // to them elsewhere. + // For linearized files, uncompressed objects go at end, and we take care of + // assigning numbers to them elsewhere. if (!m->linearized) { assignCompressedObjectNumbers(og); } @@ -1142,8 +1117,8 @@ QPDFWriter::enqueueObject(QPDFObjectHandle object) } } } else if (m->obj_renumber[og] == 0) { - // This can happen if a specially constructed file - // indicates that an object stream is inside itself. + // This can happen if a specially constructed file indicates that an object stream is + // inside itself. QTC::TC("qpdf", "QPDFWriter ignore self-referential object stream"); } return; @@ -1223,12 +1198,10 @@ QPDFWriter::writeTrailer( if (original_id1.empty()) { writeString("<00000000000000000000000000000000>"); } else { - // Write a string of zeroes equal in length to the - // representation of the original ID. While writing the - // original ID would have the same number of bytes, it - // would cause a change to the deterministic ID generated - // by older versions of the software that hard-coded the - // length of the ID to 16 bytes. + // Write a string of zeroes equal in length to the representation of the original ID. + // While writing the original ID would have the same number of bytes, it would cause a + // change to the deterministic ID generated by older versions of the software that + // hard-coded the length of the ID to 16 bytes. writeString("<"); size_t len = QPDF_String(original_id1).unparse(true).length() - 2; for (size_t i = 0; i < len; ++i) { @@ -1284,11 +1257,9 @@ QPDFWriter::willFilterStream( filter = false; } if (filter_on_write && m->compress_streams) { - // Don't filter if the stream is already compressed with - // FlateDecode. This way we don't make it worse if the - // original file used a better Flate algorithm, and we - // don't spend time and CPU cycles uncompressing and - // recompressing stuff. This can be overridden with + // Don't filter if the stream is already compressed with FlateDecode. This way we don't make + // it worse if the original file used a better Flate algorithm, and we don't spend time and + // CPU cycles uncompressing and recompressing stuff. This can be overridden with // setRecompressFlate(true). QPDFObjectHandle filter_obj = stream_dict.getKey("/Filter"); if ((!m->recompress_flate) && (!stream.isDataModified()) && filter_obj.isName() && @@ -1351,8 +1322,8 @@ QPDFWriter::unparseObject( if (level < 0) { throw std::logic_error("invalid level in QPDFWriter::unparseObject"); } - // For non-qdf, "indent" is a single space between tokens. - // For qdf, indent includes the preceding newline. + // For non-qdf, "indent" is a single space between tokens. For qdf, indent includes the + // preceding newline. std::string indent = " "; if (m->qdf_mode) { indent.append(static_cast(2 * level), ' '); @@ -1360,11 +1331,9 @@ QPDFWriter::unparseObject( } if (auto const tc = object.getTypeCode(); tc == ::ot_array) { - // Note: PDF spec 1.4 implementation note 121 states that - // Acrobat requires a space after the [ in the /H key of the - // linearization parameter dictionary. We'll do this - // unconditionally for all arrays because it looks nicer and - // doesn't make the files that much bigger. + // Note: PDF spec 1.4 implementation note 121 states that Acrobat requires a space after the + // [ in the /H key of the linearization parameter dictionary. We'll do this unconditionally + // for all arrays because it looks nicer and doesn't make the files that much bigger. writeString("["); for (auto const& item: object.getArrayAsVector()) { writeString(indent); @@ -1374,13 +1343,11 @@ QPDFWriter::unparseObject( writeString(indent); writeString("]"); } else if (tc == ::ot_dictionary) { - // Make a shallow copy of this object so we can modify it - // safely without affecting the original. This code has logic - // to skip certain keys in agreement with prepareFileForWrite - // and with skip_stream_parameters so that replacing them - // doesn't leave unreferenced objects in the output. We can - // use unsafeShallowCopy here because we are all we are doing - // is removing or replacing top-level keys. + // Make a shallow copy of this object so we can modify it safely without affecting the + // original. This code has logic to skip certain keys in agreement with prepareFileForWrite + // and with skip_stream_parameters so that replacing them doesn't leave unreferenced objects + // in the output. We can use unsafeShallowCopy here because we are all we are doing is + // removing or replacing top-level keys. object = object.unsafeShallowCopy(); // Handle special cases for specific dictionaries. @@ -1400,9 +1367,8 @@ QPDFWriter::unparseObject( // - If it has other things, keep those and remove ADBE // - We have no extensions: no action required // - // Before writing, we guarantee that /Extensions, if present, - // is direct through the ADBE dictionary, so we can modify in - // place. + // Before writing, we guarantee that /Extensions, if present, is direct through the ADBE + // dictionary, so we can modify in place. const bool is_root = (old_og == m->root_og); bool have_extensions_other = false; @@ -1431,8 +1397,7 @@ QPDFWriter::unparseObject( if (is_root) { if (need_extensions_adbe) { if (!(have_extensions_other || have_extensions_adbe)) { - // We need Extensions and don't have it. Create - // it here. + // We need Extensions and don't have it. Create it here. QTC::TC("qpdf", "QPDFWriter create Extensions", m->qdf_mode ? 0 : 1); extensions = object.replaceKeyAndGetNew( "/Extensions", QPDFObjectHandle::newDictionary()); @@ -1488,8 +1453,8 @@ QPDFWriter::unparseObject( object.removeKey("/Filter"); object.removeKey("/DecodeParms"); } else { - // Make sure, no matter what else we have, that we - // don't have /Crypt in the output filters. + // Make sure, no matter what else we have, that we don't have /Crypt in the output + // filters. QPDFObjectHandle filter = object.getKey("/Filter"); QPDFObjectHandle decode_parms = object.getKey("/DecodeParms"); if (filter.isOrHasName("/Crypt")) { @@ -1506,12 +1471,10 @@ QPDFWriter::unparseObject( } } if (idx >= 0) { - // If filter is an array, then the code in - // QPDF_Stream has already verified that - // DecodeParms and Filters are arrays of - // the same length, but if they weren't - // for some reason, eraseItem does type - // and bounds checking. + // If filter is an array, then the code in QPDF_Stream has already + // verified that DecodeParms and Filters are arrays of the same length, + // but if they weren't for some reason, eraseItem does type and bounds + // checking. QTC::TC("qpdf", "QPDFWriter remove Crypt"); filter.eraseItem(idx); decode_parms.eraseItem(idx); @@ -1659,8 +1622,8 @@ QPDFWriter::writeObjectStreamOffsets(std::vector& offsets, int fi void QPDFWriter::writeObjectStream(QPDFObjectHandle object) { - // Note: object might be null if this is a place-holder for an - // object stream that we are generating from scratch. + // Note: object might be null if this is a place-holder for an object stream that we are + // generating from scratch. QPDFObjGen old_og = object.getObjGen(); qpdf_assert_debug(old_og.getGen() == 0); @@ -1670,8 +1633,8 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) std::vector offsets; qpdf_offset_t first = 0; - // Generate stream itself. We have to do this in two passes so we - // can calculate offsets in the first pass. + // Generate stream itself. We have to do this in two passes so we can calculate offsets in the + // first pass. std::shared_ptr stream_buffer; int first_obj = -1; bool compressed = false; @@ -1687,8 +1650,7 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) iter -= first; } - // Take one pass at writing pairs of numbers so we can get - // their size information + // Take one pass at writing pairs of numbers so we can get their size information { PipelinePopper pp_discard(this); pushDiscardFilter(pp_discard); @@ -1721,11 +1683,9 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) std::to_string(count)); if (!m->suppress_original_object_ids) { writeString("; original object ID: " + std::to_string(obj.getObj())); - // For compatibility, only write the generation if - // non-zero. While object streams only allow - // objects with generation 0, if we are generating - // object streams, the old object could have a - // non-zero generation. + // For compatibility, only write the generation if non-zero. While object + // streams only allow objects with generation 0, if we are generating object + // streams, the old object could have a non-zero generation. if (obj.getGen() != 0) { QTC::TC("qpdf", "QPDFWriter original obj non-zero gen"); writeString(" " + std::to_string(obj.getGen())); @@ -1735,16 +1695,14 @@ QPDFWriter::writeObjectStream(QPDFObjectHandle object) } if (pass == 1) { offsets.push_back(m->pipeline->getCount()); - // To avoid double-counting objects being written in - // object streams for progress reporting, decrement in - // pass 1. + // To avoid double-counting objects being written in object streams for progress + // reporting, decrement in pass 1. indicateProgress(true, false); } QPDFObjectHandle obj_to_write = m->pdf.getObject(obj); if (obj_to_write.isStream()) { - // This condition occurred in a fuzz input. Ideally we - // should block it at at parse time, but it's not - // clear to me how to construct a case for this. + // This condition occurred in a fuzz input. Ideally we should block it at at parse + // time, but it's not clear to me how to construct a case for this. QTC::TC("qpdf", "QPDFWriter stream in ostream"); obj_to_write.warnIfPossible("stream found inside object stream; treating as null"); obj_to_write = QPDFObjectHandle::newNull(); @@ -1867,8 +1825,8 @@ QPDFWriter::getOriginalID1() void QPDFWriter::generateID() { - // Generate the ID lazily so that we can handle the user's - // preference to use static or deterministic ID generation. + // Generate the ID lazily so that we can handle the user's preference to use static or + // deterministic ID generation. if (!m->id2.empty()) { return; @@ -1900,27 +1858,22 @@ QPDFWriter::generateID() 0x00}; result = reinterpret_cast(tmp); } else { - // The PDF specification has guidelines for creating IDs, but - // it states clearly that the only thing that's really - // important is that it is very likely to be unique. We can't - // really follow the guidelines in the spec exactly because we - // haven't written the file yet. This scheme should be fine - // though. The deterministic ID case uses a digest of a - // sufficient portion of the file's contents such no two - // non-matching files would match in the subsets used for this - // computation. Note that we explicitly omit the filename from - // the digest calculation for deterministic ID so that the same - // file converted with qpdf, in that case, would have the same - // ID regardless of the output file's name. + // The PDF specification has guidelines for creating IDs, but it states clearly that the + // only thing that's really important is that it is very likely to be unique. We can't + // really follow the guidelines in the spec exactly because we haven't written the file yet. + // This scheme should be fine though. The deterministic ID case uses a digest of a + // sufficient portion of the file's contents such no two non-matching files would match in + // the subsets used for this computation. Note that we explicitly omit the filename from + // the digest calculation for deterministic ID so that the same file converted with qpdf, in + // that case, would have the same ID regardless of the output file's name. std::string seed; if (m->deterministic_id) { if (m->deterministic_id_data.empty()) { QTC::TC("qpdf", "QPDFWriter deterministic with no data"); - throw std::logic_error("INTERNAL ERROR: QPDFWriter::generateID has no" - " data for deterministic ID. This may happen if" - " deterministic ID and file encryption are requested" - " together."); + throw std::logic_error("INTERNAL ERROR: QPDFWriter::generateID has no data for " + "deterministic ID. This may happen if deterministic ID and " + "file encryption are requested together."); } seed += m->deterministic_id_data; } else { @@ -1947,9 +1900,8 @@ QPDFWriter::generateID() result = std::string(reinterpret_cast(digest), sizeof(MD5::Digest)); } - // If /ID already exists, follow the spec: use the original first - // word and generate a new second word. Otherwise, we'll use the - // generated ID for both. + // If /ID already exists, follow the spec: use the original first word and generate a new second + // word. Otherwise, we'll use the generated ID for both. m->id2 = result; // Note: keep /ID from old file even if --static-id was given. @@ -1994,16 +1946,13 @@ QPDFWriter::preserveObjectStreams() if (omap.empty()) { return; } - // Our object_to_object_stream map has to map ObjGen -> ObjGen - // since we may be generating object streams out of old objects - // that have generation numbers greater than zero. However in an - // existing PDF, all object stream objects and all objects in them - // must have generation 0 because the PDF spec does not provide - // any way to do otherwise. This code filters out objects that are - // not allowed to be in object streams. In addition to removing - // objects that were erroneously included in object streams in the - // source PDF, it also prevents unreferenced objects from being - // included. + // Our object_to_object_stream map has to map ObjGen -> ObjGen since we may be generating object + // streams out of old objects that have generation numbers greater than zero. However in an + // existing PDF, all object stream objects and all objects in them must have generation 0 + // because the PDF spec does not provide any way to do otherwise. This code filters out objects + // that are not allowed to be in object streams. In addition to removing objects that were + // erroneously included in object streams in the source PDF, it also prevents unreferenced + // objects from being included. std::set eligible; if (!m->preserve_unreferenced_objects) { std::vector eligible_v = QPDF::Writer::getCompressibleObjGens(m->pdf); @@ -2023,13 +1972,11 @@ QPDFWriter::preserveObjectStreams() void QPDFWriter::generateObjectStreams() { - // Basic strategy: make a list of objects that can go into an - // object stream. Then figure out how many object streams are - // needed so that we can distribute objects approximately evenly - // without having any object stream exceed 100 members. We don't - // have to worry about linearized files here -- if the file is - // linearized, we take care of excluding things that aren't - // allowed here later. + // Basic strategy: make a list of objects that can go into an object stream. Then figure out + // how many object streams are needed so that we can distribute objects approximately evenly + // without having any object stream exceed 100 members. We don't have to worry about linearized + // files here -- if the file is linearized, we take care of excluding things that aren't allowed + // here later. // This code doesn't do anything with /Extends. @@ -2052,9 +1999,8 @@ QPDFWriter::generateObjectStreams() n = 0; } if (n == 0) { - // Construct a new null object as the "original" object - // stream. The rest of the code knows that this means - // we're creating the object stream from scratch. + // Construct a new null object as the "original" object stream. The rest of the code + // knows that this means we're creating the object stream from scratch. cur_ostream = m->pdf.makeIndirectObject(QPDFObjectHandle::newNull()).getObjectID(); } m->object_to_object_stream[iter] = cur_ostream; @@ -2065,8 +2011,7 @@ QPDFWriter::generateObjectStreams() QPDFObjectHandle QPDFWriter::getTrimmedTrailer() { - // Remove keys from the trailer that necessarily have to be - // replaced when writing the file. + // Remove keys from the trailer that necessarily have to be replaced when writing the file. QPDFObjectHandle trailer = m->pdf.getTrailer().unsafeShallowCopy(); @@ -2077,8 +2022,7 @@ QPDFWriter::getTrimmedTrailer() // Remove modification information trailer.removeKey("/Prev"); - // Remove all trailer keys that potentially come from a - // cross-reference stream + // Remove all trailer keys that potentially come from a cross-reference stream trailer.removeKey("/Index"); trailer.removeKey("/W"); trailer.removeKey("/Length"); @@ -2093,8 +2037,7 @@ QPDFWriter::getTrimmedTrailer() void QPDFWriter::prepareFileForWrite() { - // Make document extension level information direct as required by - // the spec. + // Make document extension level information direct as required by the spec. m->pdf.fixDanglingReferences(); QPDFObjectHandle root = m->pdf.getRoot(); @@ -2155,8 +2098,8 @@ QPDFWriter::doWriteSetup() // Encryption has been explicitly set m->preserve_encryption = false; } else if (m->normalize_content || m->stream_decode_level || m->pclm || m->qdf_mode) { - // Encryption makes looking at contents pretty useless. If - // the user explicitly encrypted though, we still obey that. + // Encryption makes looking at contents pretty useless. If the user explicitly encrypted + // though, we still obey that. m->preserve_encryption = false; } @@ -2180,9 +2123,8 @@ QPDFWriter::doWriteSetup() } if (m->qdf_mode) { - // Generate indirect stream lengths for qdf mode since fix-qdf - // uses them for storing recomputed stream length data. - // Certain streams such as object streams, xref streams, and + // Generate indirect stream lengths for qdf mode since fix-qdf uses them for storing + // recomputed stream length data. Certain streams such as object streams, xref streams, and // hint streams always get direct stream lengths. m->direct_stream_lengths = false; } @@ -2215,11 +2157,10 @@ QPDFWriter::doWriteSetup() } if (m->linearized || m->encrypted) { - // The document catalog is not allowed to be compressed in - // linearized files either. It also appears that Adobe Reader - // 8.0.0 has a bug that prevents it from being able to handle - // encrypted files with compressed document catalogs, so we - // disable them in that case as well. + // The document catalog is not allowed to be compressed in linearized files either. It also + // appears that Adobe Reader 8.0.0 has a bug that prevents it from being able to handle + // encrypted files with compressed document catalogs, so we disable them in that case as + // well. if (m->object_to_object_stream.count(m->root_og)) { QTC::TC("qpdf", "QPDFWriter uncompressing root"); m->object_to_object_stream.erase(m->root_og); @@ -2254,9 +2195,8 @@ QPDFWriter::write() { doWriteSetup(); - // Set up progress reporting. For linearized files, we write two - // passes. events_expected is an approximation, but it's good - // enough for progress reporting, which is mostly a guess anyway. + // Set up progress reporting. For linearized files, we write two passes. events_expected is an + // approximation, but it's good enough for progress reporting, which is mostly a guess anyway. m->events_expected = QIntC::to_int(m->pdf.getObjectCount() * (m->linearized ? 2 : 1)); prepareFileForWrite(); @@ -2338,17 +2278,16 @@ QPDFWriter::writeHeader() // PCLm version writeString("\n%PCLm 1.0\n"); } else { - // This string of binary characters would not be valid UTF-8, so - // it really should be treated as binary. + // This string of binary characters would not be valid UTF-8, so it really should be treated + // as binary. writeString("\n%\xbf\xf7\xa2\xfe\n"); } writeStringQDF("%QDF-1.0\n\n"); - // Note: do not write extra header text here. Linearized PDFs - // must include the entire linearization parameter dictionary - // within the first 1024 characters of the PDF file, so for - // linearized files, we have to write extra header text after the - // linearization parameter dictionary. + // Note: do not write extra header text here. Linearized PDFs must include the entire + // linearization parameter dictionary within the first 1024 characters of the PDF file, so for + // linearized files, we have to write extra header text after the linearization parameter + // dictionary. } void @@ -2397,9 +2336,8 @@ QPDFWriter::writeHintStream(int hint_id) qpdf_offset_t QPDFWriter::writeXRefTable(trailer_e which, int first, int last, int size) { - // There are too many extra arguments to replace overloaded - // function with defaults in the header file...too much risk of - // leaving something off. + // There are too many extra arguments to replace overloaded function with defaults in the header + // file...too much risk of leaving something off. return writeXRefTable(which, first, last, size, 0, false, 0, 0, 0, 0); } @@ -2446,9 +2384,8 @@ qpdf_offset_t QPDFWriter::writeXRefStream( int objid, int max_id, qpdf_offset_t max_offset, trailer_e which, int first, int last, int size) { - // There are too many extra arguments to replace overloaded - // function with defaults in the header file...too much risk of - // leaving something off. + // There are too many extra arguments to replace overloaded function with defaults in the header + // file...too much risk of leaving something off. return writeXRefStream( objid, max_id, max_offset, which, first, last, size, 0, 0, 0, 0, false, 0); } @@ -2480,8 +2417,8 @@ QPDFWriter::writeXRefStream( unsigned int esize = 1 + f1_size + f2_size; - // Must store in xref table in advance of writing the actual data - // rather than waiting for openObject to do it. + // Must store in xref table in advance of writing the actual data rather than waiting for + // openObject to do it. m->xref[xref_id] = QPDFXRefEntry(m->pipeline->getCount()); Pipeline* p = pushPipeline(new Pl_Buffer("xref stream")); @@ -2489,9 +2426,8 @@ QPDFWriter::writeXRefStream( if ((m->compress_streams || (m->stream_decode_level == qpdf_dl_none)) && (!m->qdf_mode)) { compressed = true; if (!skip_compression) { - // Write the stream dictionary for compression but don't - // actually compress. This helps us with computation of - // padding for pass 1 of linearization. + // Write the stream dictionary for compression but don't actually compress. This helps + // us with computation of padding for pass 1 of linearization. p = pushPipeline(new Pl_Flate("compress xref", p, Pl_Flate::a_deflate)); } p = pushPipeline(new Pl_PNGFilter("pngify xref", p, Pl_PNGFilter::a_encode, esize)); @@ -2563,13 +2499,11 @@ QPDFWriter::writeXRefStream( size_t QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) { - // This routine is called right after a linearization first pass - // xref stream has been written without compression. Calculate - // the amount of padding that would be required in the worst case, - // assuming the number of uncompressed bytes remains the same. - // The worst case for zlib is that the output is larger than the - // input by 6 bytes plus 5 bytes per 16K, and then we'll add 10 - // extra bytes for number length increases. + // This routine is called right after a linearization first pass xref stream has been written + // without compression. Calculate the amount of padding that would be required in the worst + // case, assuming the number of uncompressed bytes remains the same. The worst case for zlib is + // that the output is larger than the input by 6 bytes plus 5 bytes per 16K, and then we'll add + // 10 extra bytes for number length increases. return QIntC::to_size(16 + (5 * ((xref_bytes + 16383) / 16384))); } @@ -2577,17 +2511,14 @@ QPDFWriter::calculateXrefStreamPadding(qpdf_offset_t xref_bytes) void QPDFWriter::discardGeneration(std::map const& in, std::map& out) { - // There are deep assumptions in the linearization code in QPDF - // that there is only one object with each object number; i.e., - // you can't have two objects with the same object number and - // different generations. This is a pretty safe assumption - // because Adobe Reader and Acrobat can't actually handle this - // case. There is not much if any code in QPDF outside - // linearization that assumes this, but the linearization code as - // currently implemented would do weird things if we found such a - // case. In order to avoid breaking ABI changes in QPDF, we will - // first assert that this condition holds. Then we can create new - // maps for QPDF that throw away generation numbers. + // There are deep assumptions in the linearization code in QPDF that there is only one object + // with each object number; i.e., you can't have two objects with the same object number and + // different generations. This is a pretty safe assumption because Adobe Reader and Acrobat + // can't actually handle this case. There is not much if any code in QPDF outside linearization + // that assumes this, but the linearization code as currently implemented would do weird things + // if we found such a case. In order to avoid breaking ABI changes in QPDF, we will first + // assert that this condition holds. Then we can create new maps for QPDF that throw away + // generation numbers. out.clear(); for (auto const& iter: in) { @@ -2707,25 +2638,21 @@ QPDFWriter::writeLinearized() m->next_objid = part4_first_obj; enqueuePart(part4); if (m->next_objid != after_part4) { - // This can happen with very botched files as in the fuzzer - // test. There are likely some faulty assumptions in - // calculateLinearizationData - throw std::runtime_error("error encountered after" - " writing part 4 of linearized data"); + // This can happen with very botched files as in the fuzzer test. There are likely some + // faulty assumptions in calculateLinearizationData + throw std::runtime_error("error encountered after writing part 4 of linearized data"); } m->next_objid = part6_first_obj; enqueuePart(part6); if (m->next_objid != after_part6) { - throw std::runtime_error("error encountered after" - " writing part 6 of linearized data"); + throw std::runtime_error("error encountered after writing part 6 of linearized data"); } m->next_objid = second_half_first_obj; enqueuePart(part7); enqueuePart(part8); enqueuePart(part9); if (m->next_objid != after_second_half) { - throw std::runtime_error("error encountered after" - " writing part 9 of linearized data"); + throw std::runtime_error("error encountered after writing part 9 of linearized data"); } qpdf_offset_t hint_length = 0; @@ -2754,13 +2681,11 @@ QPDFWriter::writeLinearized() writeHeader(); - // Part 2: linearization parameter dictionary. Save enough - // space to write real dictionary. 200 characters is enough - // space if all numerical values in the parameter dictionary - // that contain offsets are 20 digits long plus a few extra - // characters for safety. The entire linearization parameter - // dictionary must appear within the first 1024 characters of - // the file. + // Part 2: linearization parameter dictionary. Save enough space to write real dictionary. + // 200 characters is enough space if all numerical values in the parameter dictionary that + // contain offsets are 20 digits long plus a few extra characters for safety. The entire + // linearization parameter dictionary must appear within the first 1024 characters of the + // file. qpdf_offset_t pos = m->pipeline->getCount(); openObject(lindict_id); @@ -2772,8 +2697,7 @@ QPDFWriter::writeLinearized() writeString(" /Linearized 1 /L "); writeString(std::to_string(file_size + hint_length)); - // Implementation note 121 states that a space is - // mandatory after this open bracket. + // Implementation note 121 states that a space is mandatory after this open bracket. writeString(" /H [ "); writeString(std::to_string(m->xref[hint_id].getOffset())); writeString(" "); @@ -2793,8 +2717,8 @@ QPDFWriter::writeLinearized() writePad(QIntC::to_size(pos - m->pipeline->getCount() + pad)); writeString("\n"); - // If the user supplied any additional header text, write it - // here after the linearization parameter dictionary. + // If the user supplied any additional header text, write it here after the linearization + // parameter dictionary. writeString(m->extra_header_text); // Part 3: first page cross reference table and trailer. @@ -2807,14 +2731,11 @@ QPDFWriter::writeLinearized() if (need_xref_stream) { // Must pad here too. if (pass == 1) { - // Set first_half_max_obj_offset to a value large - // enough to force four bytes to be reserved for each - // file offset. This would provide adequate space for - // the xref stream as long as the last object in page - // 1 starts with in the first 4 GB of the file, which - // is extremely likely. In the second pass, we will - // know the actual value for this, but it's okay if - // it's smaller. + // Set first_half_max_obj_offset to a value large enough to force four bytes to be + // reserved for each file offset. This would provide adequate space for the xref + // stream as long as the last object in page 1 starts with in the first 4 GB of the + // file, which is extremely likely. In the second pass, we will know the actual + // value for this, but it's okay if it's smaller. first_half_max_obj_offset = 1 << 25; } pos = m->pipeline->getCount(); @@ -2834,13 +2755,11 @@ QPDFWriter::writeLinearized() pass); qpdf_offset_t endpos = m->pipeline->getCount(); if (pass == 1) { - // Pad so we have enough room for the real xref - // stream. + // Pad so we have enough room for the real xref stream. writePad(calculateXrefStreamPadding(endpos - pos)); first_xref_end = m->pipeline->getCount(); } else { - // Pad so that the next object starts at the same - // place as in pass 1. + // Pad so that the next object starts at the same place as in pass 1. writePad(QIntC::to_size(first_xref_end - endpos)); if (m->pipeline->getCount() != first_xref_end) { @@ -2913,9 +2832,8 @@ QPDFWriter::writeLinearized() qpdf_offset_t endpos = m->pipeline->getCount(); if (pass == 1) { - // Pad so we have enough room for the real xref - // stream. See comments for previous xref stream on - // how we calculate the padding. + // Pad so we have enough room for the real xref stream. See comments for previous + // xref stream on how we calculate the padding. writePad(calculateXrefStreamPadding(endpos - pos)); writeString("\n"); second_xref_end = m->pipeline->getCount(); @@ -2925,11 +2843,10 @@ QPDFWriter::writeLinearized() QIntC::to_size(second_xref_end + hint_length - 1 - m->pipeline->getCount())); writeString("\n"); - // If this assertion fails, maybe we didn't have - // enough padding above. + // If this assertion fails, maybe we didn't have enough padding above. if (m->pipeline->getCount() != second_xref_end + hint_length) { - throw std::logic_error("count mismatch after xref stream;" - " possible insufficient padding?"); + throw std::logic_error( + "count mismatch after xref stream; possible insufficient padding?"); } } } else { @@ -2954,8 +2871,7 @@ QPDFWriter::writeLinearized() file_size = m->pipeline->getCount(); pp_pass1 = nullptr; - // Save hint offset since it will be set to zero by - // calling openObject. + // Save hint offset since it will be set to zero by calling openObject. qpdf_offset_t hint_offset1 = m->xref[hint_id].getOffset(); // Write hint stream to a buffer @@ -3003,10 +2919,8 @@ QPDFWriter::enqueueObjectsStandard() QPDFObjectHandle trailer = getTrimmedTrailer(); enqueueObject(trailer.getKey("/Root")); - // Next place any other objects referenced from the trailer - // dictionary into the queue, handling direct objects recursively. - // Root is already there, so enqueuing it a second time is a - // no-op. + // Next place any other objects referenced from the trailer dictionary into the queue, handling + // direct objects recursively. Root is already there, so enqueuing it a second time is a no-op. for (auto const& key: trailer.getKeys()) { enqueueObject(trailer.getKey(key)); } @@ -3015,9 +2929,8 @@ QPDFWriter::enqueueObjectsStandard() void QPDFWriter::enqueueObjectsPCLm() { - // Image transform stream content for page strip images. - // Each of this new stream has to come after every page image - // strip written in the pclm file. + // Image transform stream content for page strip images. Each of this new stream has to come + // after every page image strip written in the pclm file. std::string image_transform_content = "q /image Do Q\n"; // enqueue all pages first diff --git a/libqpdf/QPDF_Array.cc b/libqpdf/QPDF_Array.cc index 760db2e2..1b78e078 100644 --- a/libqpdf/QPDF_Array.cc +++ b/libqpdf/QPDF_Array.cc @@ -12,9 +12,9 @@ QPDF_Array::checkOwnership(QPDFObjectHandle const& item) const if (qpdf) { if (auto item_qpdf = obj->getQPDF()) { if (qpdf != item_qpdf) { - throw std::logic_error("Attempting to add an object from a different QPDF. " - "Use QPDF::copyForeignObject to add objects from " - "another file."); + throw std::logic_error( + "Attempting to add an object from a different QPDF. Use " + "QPDF::copyForeignObject to add objects from another file."); } } } diff --git a/libqpdf/QPDF_Dictionary.cc b/libqpdf/QPDF_Dictionary.cc index 6d259ef5..7700b81b 100644 --- a/libqpdf/QPDF_Dictionary.cc +++ b/libqpdf/QPDF_Dictionary.cc @@ -89,8 +89,7 @@ QPDF_Dictionary::hasKey(std::string const& key) QPDFObjectHandle QPDF_Dictionary::getKey(std::string const& key) { - // PDF spec says fetching a non-existent key from a dictionary - // returns the null object. + // PDF spec says fetching a non-existent key from a dictionary returns the null object. auto item = this->items.find(key); if (item != this->items.end()) { // May be a null object @@ -123,8 +122,7 @@ void QPDF_Dictionary::replaceKey(std::string const& key, QPDFObjectHandle value) { if (value.isNull()) { - // The PDF spec doesn't distinguish between keys with null - // values and missing keys. + // The PDF spec doesn't distinguish between keys with null values and missing keys. removeKey(key); } else { // add or replace value diff --git a/libqpdf/QPDF_Name.cc b/libqpdf/QPDF_Name.cc index 8e439213..4597372e 100644 --- a/libqpdf/QPDF_Name.cc +++ b/libqpdf/QPDF_Name.cc @@ -32,8 +32,7 @@ QPDF_Name::normalizeName(std::string const& name) char ch = name.at(i); // Don't use locale/ctype here; follow PDF spec guidelines. if (ch == '\0') { - // QPDFTokenizer embeds a null character to encode an - // invalid #. + // QPDFTokenizer embeds a null character to encode an invalid #. result += "#"; } else if ( ch < 33 || ch == '#' || ch == '/' || ch == '(' || ch == ')' || ch == '{' || ch == '}' || diff --git a/libqpdf/QPDF_Real.cc b/libqpdf/QPDF_Real.cc index 19b65a7e..1d954dcd 100644 --- a/libqpdf/QPDF_Real.cc +++ b/libqpdf/QPDF_Real.cc @@ -41,9 +41,8 @@ QPDF_Real::unparse() JSON QPDF_Real::getJSON(int json_version) { - // While PDF allows .x or -.x, JSON does not. Rather than - // converting from string to double and back, just handle this as a - // special case for JSON. + // While PDF allows .x or -.x, JSON does not. Rather than converting from string to double and + // back, just handle this as a special case for JSON. std::string result; if (this->val.length() == 0) { // Can't really happen... diff --git a/libqpdf/QPDF_String.cc b/libqpdf/QPDF_String.cc index 386d7672..3886b399 100644 --- a/libqpdf/QPDF_String.cc +++ b/libqpdf/QPDF_String.cc @@ -2,9 +2,8 @@ #include -// DO NOT USE ctype -- it is locale dependent for some things, and -// it's not worth the risk of including it in case it may accidentally -// be used. +// DO NOT USE ctype -- it is locale dependent for some things, and it's not worth the risk of +// including it in case it may accidentally be used. static bool is_iso_latin1_printable(char ch) @@ -62,8 +61,7 @@ QPDF_String::getJSON(int json_version) } else if (!useHexString()) { std::string test; if (QUtil::utf8_to_pdf_doc(candidate, test, '?') && (test == this->val)) { - // This is a PDF-doc string that can be losslessly encoded - // as Unicode. + // This is a PDF-doc string that can be losslessly encoded as Unicode. is_unicode = true; result = candidate; } @@ -79,9 +77,8 @@ QPDF_String::getJSON(int json_version) bool QPDF_String::useHexString() const { - // Heuristic: use the hexadecimal representation of a string if - // there are any non-printable (in PDF Doc encoding) characters or - // if too large of a proportion of the string consists of + // Heuristic: use the hexadecimal representation of a string if there are any non-printable (in + // PDF Doc encoding) characters or if too large of a proportion of the string consists of // non-ASCII characters. unsigned int non_ascii = 0; for (auto const ch: this->val) { @@ -172,8 +169,8 @@ QPDF_String::getUTF8Val() const if (QUtil::is_utf16(this->val)) { return QUtil::utf16_to_utf8(this->val); } else if (QUtil::is_explicit_utf8(this->val)) { - // PDF 2.0 allows UTF-8 strings when explicitly prefixed with - // the three-byte representation of U+FEFF. + // PDF 2.0 allows UTF-8 strings when explicitly prefixed with the three-byte representation + // of U+FEFF. return this->val.substr(3); } else { return QUtil::pdf_doc_to_utf8(this->val); diff --git a/libqpdf/QUtil.cc b/libqpdf/QUtil.cc index 5fa3c9ca..76d6bfd5 100644 --- a/libqpdf/QUtil.cc +++ b/libqpdf/QUtil.cc @@ -296,9 +296,8 @@ template static std::string int_to_string_base_internal(T num, int base, int length) { - // Backward compatibility -- int_to_string, which calls this - // function, used to use sprintf with %0*d, so we interpret length - // such that a negative value appends spaces and a positive value + // Backward compatibility -- int_to_string, which calls this function, used to use sprintf with + // %0*d, so we interpret length such that a negative value appends spaces and a positive value // prepends zeroes. if (!((base == 8) || (base == 10) || (base == 16))) { throw std::logic_error("int_to_string_base called with unsupported base"); @@ -352,9 +351,8 @@ QUtil::uint_to_string_base(unsigned long long num, int base, int length) std::string QUtil::double_to_string(double num, int decimal_places, bool trim_trailing_zeroes) { - // Backward compatibility -- this code used to use sprintf and - // treated decimal_places <= 0 to mean to use the default, which - // was six decimal places. Starting in 10.2, we trim trailing + // Backward compatibility -- this code used to use sprintf and treated decimal_places <= 0 to + // mean to use the default, which was six decimal places. Starting in 10.2, we trim trailing // zeroes by default. if (decimal_places <= 0) { decimal_places = 6; @@ -739,8 +737,8 @@ std::string QUtil::hex_decode(std::string const& input) { std::string result; - // We know result.size() <= 0.5 * input.size() + 1. However, reserving - // string space for this upper bound has a negative impact. + // We know result.size() <= 0.5 * input.size() + 1. However, reserving string space for this + // upper bound has a negative impact. bool first = true; char decoded; for (auto ch: input) { @@ -1003,15 +1001,12 @@ QUtil::toUTF8(unsigned long uval) { std::string result; - // A UTF-8 encoding of a Unicode value is a single byte for - // Unicode values <= 127. For larger values, the first byte of - // the UTF-8 encoding has '1' as each of its n highest bits and - // '0' for its (n+1)th highest bit where n is the total number of - // bytes required. Subsequent bytes start with '10' and have the - // remaining 6 bits free for encoding. For example, an 11-bit - // Unicode value can be stored in two bytes where the first is - // 110zzzzz, the second is 10zzzzzz, and the z's represent the - // remaining bits. + // A UTF-8 encoding of a Unicode value is a single byte for Unicode values <= 127. For larger + // values, the first byte of the UTF-8 encoding has '1' as each of its n highest bits and '0' + // for its (n+1)th highest bit where n is the total number of bytes required. Subsequent bytes + // start with '10' and have the remaining 6 bits free for encoding. For example, an 11-bit + // Unicode value can be stored in two bytes where the first is 110zzzzz, the second is 10zzzzzz, + // and the z's represent the remaining bits. if (uval > 0x7fffffff) { throw std::runtime_error("bounds error in QUtil::toUTF8"); @@ -1026,8 +1021,7 @@ QUtil::toUTF8(unsigned long uval) unsigned char maxval = 0x3f; // six bits while (uval > QIntC::to_ulong(maxval)) { - // Assign low six bits plus 10000000 to lowest unused - // byte position, then shift + // Assign low six bits plus 10000000 to lowest unused byte position, then shift *cur_byte = static_cast(0x80 + (uval & 0x3f)); uval >>= 6; // Maximum that will fit in high byte now shrinks by one bit @@ -1038,8 +1032,7 @@ QUtil::toUTF8(unsigned long uval) } --cur_byte; } - // If maxval is k bits long, the high (7 - k) bits of the - // resulting byte must be high. + // If maxval is k bits long, the high (7 - k) bits of the resulting byte must be high. *cur_byte = static_cast(QIntC::to_ulong(0xff - (1 + (maxval << 1))) + uval); result += reinterpret_cast(cur_byte); @@ -1265,8 +1258,7 @@ QUtil::read_lines_from_file( if (preserve_eol) { buf->append(1, c); } else { - // Remove any carriage return that preceded the - // newline and discard the newline + // Remove any carriage return that preceded the newline and discard the newline if ((!buf->empty()) && ((*(buf->rbegin())) == '\r')) { buf->erase(buf->length() - 1); } @@ -1391,8 +1383,7 @@ QUtil::parse_numrange(char const* range, int max) p = nullptr; for (size_t i = 0; i < work.size(); i += 2) { int num = work.at(i); - // max == 0 means we don't know the max and are just - // testing for valid syntax. + // max == 0 means we don't know the max and are just testing for valid syntax. if ((max > 0) && ((num < 1) || (num > max))) { throw std::runtime_error("number " + QUtil::int_to_string(num) + " out of range"); } @@ -1519,21 +1510,18 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco result += "\xfe\xff"; break; case e_pdfdoc: - // We need to avoid having the result start with something - // that will be interpreted as UTF-16 or UTF-8, meaning we - // can't end up with a string that starts with "fe ff", - // (UTF-16-BE) "ff fe" (UTF-16-LE, not officially part of the - // PDF spec, but recognized by most readers including qpdf), - // or "ef bb bf" (UTF-8). It's more efficient to check the - // input string to see if it will map to one of those - // sequences than to check the output string since all cases - // start with the same starting character. + // We need to avoid having the result start with something that will be interpreted as + // UTF-16 or UTF-8, meaning we can't end up with a string that starts with "fe ff", + // (UTF-16-BE) "ff fe" (UTF-16-LE, not officially part of the PDF spec, but recognized by + // most readers including qpdf), or "ef bb bf" (UTF-8). It's more efficient to check the + // input string to see if it will map to one of those sequences than to check the output + // string since all cases start with the same starting character. if ((len >= 4) && (utf8_val[0] == '\xc3')) { static std::string fe_ff("\xbe\xc3\xbf"); static std::string ff_fe("\xbf\xc3\xbe"); static std::string ef_bb_bf("\xaf\xc2\xbb\xc2\xbf"); - // C++-20 has starts_with, but when this was written, qpdf - // had a minimum supported version of C++-17. + // C++-20 has starts_with, but when this was written, qpdf had a minimum supported + // version of C++-17. if ((utf8_val.compare(1, 3, fe_ff) == 0) || (utf8_val.compare(1, 3, ff_fe) == 0) || (utf8_val.compare(1, 5, ef_bb_bf) == 0)) { result += unknown; @@ -1560,10 +1548,9 @@ transcode_utf8(std::string const& utf8_val, std::string& result, encoding_e enco if (encoding == e_utf16) { result += QUtil::toUTF16(QIntC::to_ulong(ch)); } else if ((encoding == e_pdfdoc) && (((ch >= 0x18) && (ch <= 0x1f)) || (ch == 127))) { - // PDFDocEncoding maps some low characters to Unicode, - // so if we encounter those invalid UTF-8 code points, - // map them to unknown so reversing the mapping - // doesn't change them into other characters. + // PDFDocEncoding maps some low characters to Unicode, so if we encounter those + // invalid UTF-8 code points, map them to unknown so reversing the mapping doesn't + // change them into other characters. okay = false; result.append(1, unknown); } else { @@ -1682,10 +1669,9 @@ std::string QUtil::utf16_to_utf8(std::string const& val) { std::string result; - // This code uses unsigned long and unsigned short to hold - // codepoint values. It requires unsigned long to be at least - // 32 bits and unsigned short to be at least 16 bits, but it - // will work fine if they are larger. + // This code uses unsigned long and unsigned short to hold codepoint values. It requires + // unsigned long to be at least 32 bits and unsigned short to be at least 16 bits, but it will + // work fine if they are larger. unsigned long codepoint = 0L; size_t len = val.length(); size_t start = 0; @@ -1696,14 +1682,11 @@ QUtil::utf16_to_utf8(std::string const& val) } start += 2; } - // If the string has an odd number of bytes, the last byte is - // ignored. + // If the string has an odd number of bytes, the last byte is ignored. for (size_t i = start; i + 1 < len; i += 2) { - // Convert from UTF16-BE. If we get a malformed - // codepoint, this code will generate incorrect output - // without giving a warning. Specifically, a high - // codepoint not followed by a low codepoint will be - // discarded, and a low codepoint not preceded by a high + // Convert from UTF16-BE. If we get a malformed codepoint, this code will generate + // incorrect output without giving a warning. Specifically, a high codepoint not followed + // by a low codepoint will be discarded, and a low codepoint not preceded by a high // codepoint will just get its low 10 bits output. auto msb = is_le ? i + 1 : i; auto lsb = is_le ? i : i + 1; @@ -1829,8 +1812,7 @@ QUtil::possible_repaired_encodings(std::string supplied) } std::string output; if (is_valid_utf8) { - // Maybe we were given UTF-8 but wanted one of the single-byte - // encodings. + // Maybe we were given UTF-8 but wanted one of the single-byte encodings. if (utf8_to_pdf_doc(supplied, output)) { result.push_back(output); } @@ -1841,8 +1823,7 @@ QUtil::possible_repaired_encodings(std::string supplied) result.push_back(output); } } else { - // Maybe we were given one of the single-byte encodings but - // wanted UTF-8. + // Maybe we were given one of the single-byte encodings but wanted UTF-8. std::string from_pdf_doc(pdf_doc_to_utf8(supplied)); result.push_back(from_pdf_doc); std::string from_win_ansi(win_ansi_to_utf8(supplied)); @@ -1850,8 +1831,8 @@ QUtil::possible_repaired_encodings(std::string supplied) std::string from_mac_roman(mac_roman_to_utf8(supplied)); result.push_back(from_mac_roman); - // Maybe we were given one of the other single-byte encodings - // but wanted one of the other ones. + // Maybe we were given one of the other single-byte encodings but wanted one of the other + // ones. if (utf8_to_win_ansi(from_pdf_doc, output)) { result.push_back(output); } @@ -1888,9 +1869,8 @@ static int call_main_from_wmain( bool, int argc, wchar_t const* const argv[], std::function realmain) { - // argv contains UTF-16-encoded strings with a 16-bit wchar_t. - // Convert this to UTF-8-encoded strings for compatibility with - // other systems. That way the rest of qpdf.cc can just act like + // argv contains UTF-16-encoded strings with a 16-bit wchar_t. Convert this to UTF-8-encoded + // strings for compatibility with other systems. That way the rest of qpdf.cc can just act like // arguments are UTF-8. std::vector> utf8_argv; @@ -1950,16 +1930,13 @@ QUtil::get_max_memory_usage() fprintf(stderr, "%s", buf); } - // Warning: this code uses regular expression to extract data from - // an XML string. This is generally a bad idea, but we're going to - // do it anyway because QUtil.hh warns against using this function - // for other than development/testing, and if this function fails - // to generate reasonable output during performance testing, it - // will be noticed. + // Warning: this code uses regular expression to extract data from an XML string. This is + // generally a bad idea, but we're going to do it anyway because QUtil.hh warns against using + // this function for other than development/testing, and if this function fails to generate + // reasonable output during performance testing, it will be noticed. - // This is my best guess at how to interpret malloc_info. Anyway - // it seems to provide useful information for detecting code - // changes that drastically change memory usage. + // This is my best guess at how to interpret malloc_info. Anyway it seems to provide useful + // information for detecting code changes that drastically change memory usage. size_t result = 0; try { std::cregex_iterator m_begin(buf, buf + size, tag_re); diff --git a/libqpdf/SecureRandomDataProvider.cc b/libqpdf/SecureRandomDataProvider.cc index c47c8707..64199903 100644 --- a/libqpdf/SecureRandomDataProvider.cc +++ b/libqpdf/SecureRandomDataProvider.cc @@ -89,10 +89,9 @@ SecureRandomDataProvider::provideRandomData(unsigned char* data, size_t len) # elif defined(RANDOM_DEVICE) - // Optimization: wrap the file open and close in a class so that - // the file is closed in a destructor, then make this static to - // keep the file handle open. Only do this if it can be done in a - // thread-safe fashion. + // Optimization: wrap the file open and close in a class so that the file is closed in a + // destructor, then make this static to keep the file handle open. Only do this if it can be + // done in a thread-safe fashion. FILE* f = QUtil::safe_fopen(RANDOM_DEVICE, "rb"); size_t fr = fread(data, 1, len, f); fclose(f); diff --git a/libqpdf/qpdf-c.cc b/libqpdf/qpdf-c.cc index 05568558..fe2a608e 100644 --- a/libqpdf/qpdf-c.cc +++ b/libqpdf/qpdf-c.cc @@ -269,9 +269,8 @@ qpdf_read(qpdf_data qpdf, char const* filename, char const* password) qpdf->filename = filename; qpdf->password = password; status = trap_errors(qpdf, &call_read); - // We no longer have a good way to exercise a file with both - // warnings and errors because qpdf is getting much better at - // recovering. + // We no longer have a good way to exercise a file with both warnings and errors because qpdf is + // getting much better at recovering. QTC::TC( "qpdf", "qpdf-c called qpdf_read", @@ -806,9 +805,8 @@ template static RET trap_oh_errors(qpdf_data qpdf, std::function fallback, std::function fn) { - // Note: fallback is a function so we don't have to evaluate it - // unless needed. This is important because sometimes the fallback - // creates an object. + // Note: fallback is a function so we don't have to evaluate it unless needed. This is important + // because sometimes the fallback creates an object. RET ret; QPDF_ERROR_CODE status = trap_errors(qpdf, [&ret, fn](qpdf_data q) { ret = fn(q); }); if (status & QPDF_ERRORS) { @@ -820,9 +818,8 @@ trap_oh_errors(qpdf_data qpdf, std::function fallback, std::functionqpdf->getFilename(), "", 0, - "C API function caught an exception that it isn't" - " returning; please point the application developer" - " to ERROR HANDLING in qpdf-c.h")); + "C API function caught an exception that it isn't returning; please point the " + "application developer to ERROR HANDLING in qpdf-c.h")); qpdf->oh_error_occurred = true; } *QPDFLogger::defaultLogger()->getError() << qpdf->error->what() << "\n"; diff --git a/libqpdf/qpdf/BitStream.hh b/libqpdf/qpdf/BitStream.hh index b807f56c..329c486d 100644 --- a/libqpdf/qpdf/BitStream.hh +++ b/libqpdf/qpdf/BitStream.hh @@ -12,8 +12,7 @@ class BitStream void reset(); unsigned long long getBits(size_t nbits); long long getBitsSigned(size_t nbits); - // Only call getBitsInt when requesting a number of bits that will - // definitely fit in an int. + // Only call getBitsInt when requesting a number of bits that definitely fit in an int. int getBitsInt(size_t nbits); void skipToNextByte(); diff --git a/libqpdf/qpdf/BitWriter.hh b/libqpdf/qpdf/BitWriter.hh index 33fdd8f4..24c74162 100644 --- a/libqpdf/qpdf/BitWriter.hh +++ b/libqpdf/qpdf/BitWriter.hh @@ -10,8 +10,8 @@ class Pipeline; class BitWriter { public: - // Write bits to the pipeline. It is the caller's responsibility - // to eventually call finish on the pipeline. + // Write bits to the pipeline. It is the caller's responsibility to eventually call finish on + // the pipeline. BitWriter(Pipeline* pl); void writeBits(unsigned long long val, size_t bits); void writeBitsSigned(long long val, size_t bits); diff --git a/libqpdf/qpdf/JSONHandler.hh b/libqpdf/qpdf/JSONHandler.hh index e4a76af5..8fdcaee6 100644 --- a/libqpdf/qpdf/JSONHandler.hh +++ b/libqpdf/qpdf/JSONHandler.hh @@ -7,37 +7,32 @@ #include #include -// This class allows a sax-like walk through a JSON object with -// functionality that mostly mirrors QPDFArgParser. It is primarily -// here to facilitate automatic generation of some of the code to help -// keep QPDFJob json consistent with command-line arguments. +// This class allows a sax-like walk through a JSON object with functionality that mostly mirrors +// QPDFArgParser. It is primarily here to facilitate automatic generation of some of the code to +// help keep QPDFJob json consistent with command-line arguments. class JSONHandler { public: - // A QPDFUsage exception is thrown if there are any errors - // validating the JSON object. + // A QPDFUsage exception is thrown if there are any errors validating the JSON object. JSONHandler(); ~JSONHandler() = default; - // Based on the type of handler, expect the object to be of a - // certain type. QPDFUsage is thrown otherwise. Multiple handlers - // may be registered, which allows the object to be of various - // types. If an anyHandler is added, no other handler will be - // called. There is no "final" handler -- if the top-level is a - // dictionary or array, just use its end handler. + // Based on the type of handler, expect the object to be of a certain type. QPDFUsage is thrown + // otherwise. Multiple handlers may be registered, which allows the object to be of various + // types. If an anyHandler is added, no other handler will be called. There is no "final" + // handler -- if the top-level is a dictionary or array, just use its end handler. typedef std::function json_handler_t; typedef std::function void_handler_t; typedef std::function string_handler_t; typedef std::function bool_handler_t; - // If an any handler is added, it will be called for any value - // including null, and no other handler will be called. + // If an any handler is added, it will be called for any value including null, and no other + // handler will be called. void addAnyHandler(json_handler_t fn); - // If any of the remaining handlers are registered, each - // registered handle will be called. + // If any of the remaining handlers are registered, each registered handle will be called. void addNullHandler(void_handler_t fn); void addStringHandler(string_handler_t fn); void addNumberHandler(string_handler_t fn); diff --git a/libqpdf/qpdf/MD5.hh b/libqpdf/qpdf/MD5.hh index 977cd4b5..be97edb5 100644 --- a/libqpdf/qpdf/MD5.hh +++ b/libqpdf/qpdf/MD5.hh @@ -29,8 +29,7 @@ class MD5 // computes a raw digest void digest(Digest); - // prints the digest to stdout terminated with \r\n (primarily for - // testing) + // prints the digest to stdout terminated with \r\n (primarily for testing) void print(); // returns the digest as a hexadecimal string diff --git a/libqpdf/qpdf/NNTree.hh b/libqpdf/qpdf/NNTree.hh index 6345b105..4b5ba200 100644 --- a/libqpdf/qpdf/NNTree.hh +++ b/libqpdf/qpdf/NNTree.hh @@ -104,9 +104,8 @@ class NNTreeImpl iterator insert(QPDFObjectHandle key, QPDFObjectHandle value); bool remove(QPDFObjectHandle key, QPDFObjectHandle* value = nullptr); - // Change the split threshold for easier testing. There's no real - // reason to expose this to downstream tree helpers, but it has to - // be public so we can call it from the test suite. + // Change the split threshold for easier testing. There's no real reason to expose this to + // downstream tree helpers, but it has to be public so we can call it from the test suite. void setSplitThreshold(int split_threshold); private: diff --git a/libqpdf/qpdf/OffsetInputSource.hh b/libqpdf/qpdf/OffsetInputSource.hh index 2d506f80..f9246363 100644 --- a/libqpdf/qpdf/OffsetInputSource.hh +++ b/libqpdf/qpdf/OffsetInputSource.hh @@ -1,8 +1,8 @@ #ifndef QPDF_OFFSETINPUTSOURCE_HH #define QPDF_OFFSETINPUTSOURCE_HH -// This class implements an InputSource that proxies for an underlying -// input source but offset a specific number of bytes. +// This class implements an InputSource that proxies for an underlying input source but offset a +// specific number of bytes. #include diff --git a/libqpdf/qpdf/Pl_AES_PDF.hh b/libqpdf/qpdf/Pl_AES_PDF.hh index b3fde312..32f4c351 100644 --- a/libqpdf/qpdf/Pl_AES_PDF.hh +++ b/libqpdf/qpdf/Pl_AES_PDF.hh @@ -5,8 +5,8 @@ #include #include -// This pipeline implements AES-128 and AES-256 with CBC and block -// padding as specified in the PDF specification. +// This pipeline implements AES-128 and AES-256 with CBC and block padding as specified in the PDF +// specification. class Pl_AES_PDF: public Pipeline { diff --git a/libqpdf/qpdf/Pl_MD5.hh b/libqpdf/qpdf/Pl_MD5.hh index bd56f9c6..5763d6eb 100644 --- a/libqpdf/qpdf/Pl_MD5.hh +++ b/libqpdf/qpdf/Pl_MD5.hh @@ -1,13 +1,11 @@ #ifndef PL_MD5_HH #define PL_MD5_HH -// This pipeline sends its output to its successor unmodified. After -// calling finish, the MD5 checksum of the data that passed through -// the pipeline is available. +// This pipeline sends its output to its successor unmodified. After calling finish, the MD5 +// checksum of the data that passed through the pipeline is available. -// This pipeline is reusable; i.e., it is safe to call write() after -// calling finish(). The first call to write() after a call to -// finish() initializes a new MD5 object. +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). The first +// call to write() after a call to finish() initializes a new MD5 object. #include #include @@ -20,15 +18,12 @@ class Pl_MD5: public Pipeline virtual void write(unsigned char const*, size_t); virtual void finish(); std::string getHexDigest(); - // Enable/disable. Disabling the pipeline causes it to become a - // pass-through. This makes it possible to stick an MD5 pipeline - // in a pipeline when it may or may not be required. Disabling it - // avoids incurring the runtime overhead of doing needless - // digest computation. + // Enable/disable. Disabling the pipeline causes it to become a pass-through. This makes it + // possible to stick an MD5 pipeline in a pipeline when it may or may not be required. Disabling + // it avoids incurring the runtime overhead of doing needless digest computation. void enable(bool enabled); - // If persistAcrossFinish is called, calls to finish do not - // finalize the underlying md5 object. In this case, the object is - // not finalized until getHexDigest() is called. + // If persistAcrossFinish is called, calls to finish do not finalize the underlying md5 object. + // In this case, the object is not finalized until getHexDigest() is called. void persistAcrossFinish(bool); private: diff --git a/libqpdf/qpdf/Pl_PNGFilter.hh b/libqpdf/qpdf/Pl_PNGFilter.hh index 7ab7bf0d..ed8e1e9c 100644 --- a/libqpdf/qpdf/Pl_PNGFilter.hh +++ b/libqpdf/qpdf/Pl_PNGFilter.hh @@ -1,11 +1,11 @@ #ifndef PL_PNGFILTER_HH #define PL_PNGFILTER_HH -// This pipeline applies or reverses the application of a PNG filter -// as described in the PNG specification. +// This pipeline applies or reverses the application of a PNG filter as described in the PNG +// specification. -// NOTE: In its current implementation, this filter always encodes -// using the "up" filter, but it decodes all the filters. +// NOTE: In its current implementation, this filter always encodes using the "up" filter, but it +// decodes all the filters. #include diff --git a/libqpdf/qpdf/Pl_SHA2.hh b/libqpdf/qpdf/Pl_SHA2.hh index 571271eb..9b3275f0 100644 --- a/libqpdf/qpdf/Pl_SHA2.hh +++ b/libqpdf/qpdf/Pl_SHA2.hh @@ -1,16 +1,13 @@ #ifndef PL_SHA2_HH #define PL_SHA2_HH -// Bits must be a supported number of bits, currently only 256, 384, -// or 512. Passing 0 as bits leaves the pipeline uncommitted, in -// which case resetBits must be called before the pipeline is used. -// If a next is provided, this pipeline sends its output to its -// successor unmodified. After calling finish, the SHA2 checksum of -// the data that passed through the pipeline is available. +// Bits must be a supported number of bits, currently only 256, 384, or 512. Passing 0 as bits +// leaves the pipeline uncommitted, in which case resetBits must be called before the pipeline is +// used. If a next is provided, this pipeline sends its output to its successor unmodified. After +// calling finish, the SHA2 checksum of the data that passed through the pipeline is available. -// This pipeline is reusable; i.e., it is safe to call write() after -// calling finish(). The first call to write() after a call to -// finish() initializes a new SHA2 object. resetBits may also be +// This pipeline is reusable; i.e., it is safe to call write() after calling finish(). The first +// call to write() after a call to finish() initializes a new SHA2 object. resetBits may also be // called between finish and the next call to write. #include diff --git a/libqpdf/qpdf/Pl_TIFFPredictor.hh b/libqpdf/qpdf/Pl_TIFFPredictor.hh index 6bc48e72..21757593 100644 --- a/libqpdf/qpdf/Pl_TIFFPredictor.hh +++ b/libqpdf/qpdf/Pl_TIFFPredictor.hh @@ -1,8 +1,8 @@ #ifndef PL_TIFFPREDICTOR_HH #define PL_TIFFPREDICTOR_HH -// This pipeline reverses the application of a TIFF predictor as -// described in the TIFF specification. +// This pipeline reverses the application of a TIFF predictor as described in the TIFF +// specification. #include diff --git a/libqpdf/qpdf/QPDFArgParser.hh b/libqpdf/qpdf/QPDFArgParser.hh index d9e33b5a..3b22a805 100644 --- a/libqpdf/qpdf/QPDFArgParser.hh +++ b/libqpdf/qpdf/QPDFArgParser.hh @@ -9,41 +9,33 @@ #include #include -// This is not a general-purpose argument parser. It is tightly -// crafted to work with qpdf. qpdf's command-line syntax is very -// complex because of its long history, and it doesn't really follow -// any kind of normal standard for arguments, but it's important for -// backward compatibility to ensure we don't break what constitutes a -// valid command. This class handles the quirks of qpdf's argument -// parsing, bash/zsh completion, and support for @argfile to read -// arguments from a file. For the qpdf CLI, setup of QPDFArgParser is -// done mostly by automatically-generated code (one-off code for -// qpdf), though the handlers themselves are hand-coded. See -// generate_auto_job at the top of the source tree for details. +// This is not a general-purpose argument parser. It is tightly crafted to work with qpdf. qpdf's +// command-line syntax is very complex because of its long history, and it doesn't really follow any +// kind of normal standard for arguments, but it's important for backward compatibility to ensure we +// don't break what constitutes a valid command. This class handles the quirks of qpdf's argument +// parsing, bash/zsh completion, and support for @argfile to read arguments from a file. For the +// qpdf CLI, setup of QPDFArgParser is done mostly by automatically-generated code (one-off code for +// qpdf), though the handlers themselves are hand-coded. See generate_auto_job at the top of the +// source tree for details. class QPDFArgParser { public: - // progname_env is used to override argv[0] when figuring out the - // name of the executable for setting up completion. This may be - // needed if the program is invoked by a wrapper. + // progname_env is used to override argv[0] when figuring out the name of the executable for + // setting up completion. This may be needed if the program is invoked by a wrapper. QPDFArgParser(int argc, char const* const argv[], char const* progname_env); - // Calls exit(0) if a help option is given or if in completion - // mode. If there are argument parsing errors, QPDFUsage is - // thrown. + // Calls exit(0) if a help option is given or if in completion mode. If there are argument + // parsing errors, QPDFUsage is thrown. void parseArgs(); - // Return the program name as the last path element of the program - // executable. + // Return the program name as the last path element of the program executable. std::string getProgname(); - // Methods for registering arguments. QPDFArgParser starts off - // with the main option table selected. You can add handlers for - // arguments in the current option table, and you can select which - // option table is current. The help option table is special and - // contains arguments that are only valid as the first and only - // option. Named option tables are for subparsers and always start - // a series of options that end with `--`. + // Methods for registering arguments. QPDFArgParser starts off with the main option table + // selected. You can add handlers for arguments in the current option table, and you can select + // which option table is current. The help option table is special and contains arguments that + // are only valid as the first and only option. Named option tables are for subparsers and + // always start a series of options that end with `--`. typedef std::function bare_arg_handler_t; typedef std::function param_arg_handler_t; @@ -65,9 +57,8 @@ class QPDFArgParser void addChoices(std::string const& arg, param_arg_handler_t, bool required, char const** choices); - // The default behavior when an invalid choice is specified with - // an option that takes choices is to list all the choices. This - // may not be good if there are too many choices, so you can + // The default behavior when an invalid choice is specified with an option that takes choices is + // to list all the choices. This may not be good if there are too many choices, so you can // provide your own handler in this case. void addInvalidChoiceHandler(std::string const& arg, param_arg_handler_t); @@ -77,42 +68,33 @@ class QPDFArgParser // Help generation methods - // Help is available on topics and options. Options may be - // associated with topics. Users can run --help, --help=topic, or - // --help=--arg to get help. The top-level help tells the user how - // to run help and lists available topics. Help for a topic prints - // a short synopsis about the topic and lists any options that may - // be associated with the topic. Help for an option provides a - // short synopsis for that option. All help output is appended - // with a blurb (if supplied) directing the user to the full - // documentation. Help is not shown for options for which help has - // not been added. This makes it possible to have undocumented - // options for testing, backward-compatibility, etc. Also, it - // could be quite confusing to handle appropriate help for some - // inner options that may be repeated with different semantics - // inside different option tables. There is also no checking for - // whether an option that has help actually exists. In other - // words, it's up to the caller to ensure that help actually - // corresponds to the program's actual options. Rather than this - // being an intentional design decision, it is because this class - // is specifically for qpdf, qpdf generates its help and has other - // means to ensure consistency. + // Help is available on topics and options. Options may be associated with topics. Users can run + // --help, --help=topic, or --help=--arg to get help. The top-level help tells the user how + // to run help and lists available topics. Help for a topic prints a short synopsis about the + // topic and lists any options that may be associated with the topic. Help for an option + // provides a short synopsis for that option. All help output is appended with a blurb (if + // supplied) directing the user to the full documentation. Help is not shown for options for + // which help has not been added. This makes it possible to have undocumented options for + // testing, backward-compatibility, etc. Also, it could be quite confusing to handle appropriate + // help for some inner options that may be repeated with different semantics inside different + // option tables. There is also no checking for whether an option that has help actually exists. + // In other words, it's up to the caller to ensure that help actually corresponds to the + // program's actual options. Rather than this being an intentional design decision, it is + // because this class is specifically for qpdf, qpdf generates its help and has other means to + // ensure consistency. // Note about newlines: // - // short_text should fit easily after the topic/option on the same - // line and should not end with a newline. Keep it to around 40 to - // 60 characters. + // short_text should fit easily after the topic/option on the same line and should not end with + // a newline. Keep it to around 40 to 60 characters. // - // long_text and footer should end with a single newline. They can - // have embedded newlines. Keep lines to under 80 columns. + // long_text and footer should end with a single newline. They can have embedded newlines. Keep + // lines to under 80 columns. // - // QPDFArgParser does reformat the text, but it may add blank - // lines in some situations. Following the above conventions will - // keep the help looking uniform. + // QPDFArgParser does reformat the text, but it may add blank lines in some situations. + // Following the above conventions will keep the help looking uniform. - // If provided, this footer is appended to all help, separated by - // a blank line. + // If provided, this footer is appended to all help, separated by a blank line. void addHelpFooter(std::string const&); // Add a help topic along with the text for that topic @@ -126,14 +108,12 @@ class QPDFArgParser std::string const& short_text, std::string const& long_text); - // Return the help text for a topic or option. Passing a null - // pointer returns the top-level help information. Passing an - // unknown value returns a string directing the user to run the + // Return the help text for a topic or option. Passing a null pointer returns the top-level help + // information. Passing an unknown value returns a string directing the user to run the // top-level --help option. std::string getHelp(std::string const& topic_or_option); - // Convenience methods for adding member functions of a class as - // handlers. + // Convenience methods for adding member functions of a class as handlers. template static bare_arg_handler_t bindBare(void (T::*f)(), T* o) @@ -147,21 +127,19 @@ class QPDFArgParser return std::bind(std::mem_fn(f), o, std::placeholders::_1); } - // When processing arguments, indicate how many arguments remain - // after the one whose handler is being called. + // When processing arguments, indicate how many arguments remain after the one whose handler is + // being called. int argsLeft() const; // Indicate whether we are in completion mode. bool isCompleting() const; - // Insert a completion during argument parsing; useful for - // customizing completion in the position argument handler. Should - // only be used in completion mode. + // Insert a completion during argument parsing; useful for customizing completion in the + // position argument handler. Should only be used in completion mode. void insertCompletion(std::string const&); - // Throw a Usage exception with the given message. In completion - // mode, this just exits to prevent errors from partial commands - // or other error messages from messing up completion. + // Throw a Usage exception with the given message. In completion mode, this just exits to + // prevent errors from partial commands or other error messages from messing up completion. void usage(std::string const& message); private: diff --git a/libqpdf/qpdf/QPDFCrypto_gnutls.hh b/libqpdf/qpdf/QPDFCrypto_gnutls.hh index efec1bbf..00f25857 100644 --- a/libqpdf/qpdf/QPDFCrypto_gnutls.hh +++ b/libqpdf/qpdf/QPDFCrypto_gnutls.hh @@ -4,8 +4,8 @@ #include #include -// gnutls headers must be last to prevent them from interfering with -// other headers. gnutls.h has to be included first. +// gnutls headers must be last to prevent them from interfering with other headers. gnutls.h has to +// be included first. #include // This comment prevents clang-format from putting crypto.h before gnutls.h #include diff --git a/libqpdf/qpdf/QPDFObject_private.hh b/libqpdf/qpdf/QPDFObject_private.hh index bbd6ccf1..5e87c215 100644 --- a/libqpdf/qpdf/QPDFObject_private.hh +++ b/libqpdf/qpdf/QPDFObject_private.hh @@ -1,9 +1,8 @@ #ifndef QPDFOBJECT_HH #define QPDFOBJECT_HH -// NOTE: This file is called QPDFObject_private.hh instead of -// QPDFObject.hh because of include/qpdf/QPDFObject.hh. See comments -// there for an explanation. +// NOTE: This file is called QPDFObject_private.hh instead of QPDFObject.hh because of +// include/qpdf/QPDFObject.hh. See comments there for an explanation. #include #include @@ -51,8 +50,7 @@ class QPDFObject return value->type_code; } - // Return a string literal that describes the type, useful for - // debugging and testing + // Return a string literal that describes the type, useful for debugging and testing char const* getTypeName() const { @@ -146,14 +144,12 @@ class QPDFObject void disconnect() { - // Disconnect an object from its owning QPDF. This is called - // by QPDF's destructor. + // Disconnect an object from its owning QPDF. This is called by QPDF's destructor. value->disconnect(); value->qpdf = nullptr; value->og = QPDFObjGen(); } - // Mark an object as destroyed. Used by QPDF's destructor for its - // indirect objects. + // Mark an object as destroyed. Used by QPDF's destructor for its indirect objects. void destroy(); bool diff --git a/libqpdf/qpdf/QPDF_Dictionary.hh b/libqpdf/qpdf/QPDF_Dictionary.hh index bf3dfb2d..da38db7a 100644 --- a/libqpdf/qpdf/QPDF_Dictionary.hh +++ b/libqpdf/qpdf/QPDF_Dictionary.hh @@ -19,16 +19,15 @@ class QPDF_Dictionary: public QPDFValue virtual JSON getJSON(int json_version); virtual void disconnect(); - // hasKey() and getKeys() treat keys with null values as if they - // aren't there. getKey() returns null for the value of a - // non-existent key. This is as per the PDF spec. + // hasKey() and getKeys() treat keys with null values as if they aren't there. getKey() returns + // null for the value of a non-existent key. This is as per the PDF spec. bool hasKey(std::string const&); QPDFObjectHandle getKey(std::string const&); std::set getKeys(); std::map const& getAsMap() const; - // If value is null, remove key; otherwise, replace the value of - // key, adding it if it does not exist. + // If value is null, remove key; otherwise, replace the value of key, adding it if it does not + // exist. void replaceKey(std::string const& key, QPDFObjectHandle value); // Remove key, doing nothing if key does not exist void removeKey(std::string const& key); diff --git a/libqpdf/qpdf/RC4.hh b/libqpdf/qpdf/RC4.hh index 257e6980..08bde7a3 100644 --- a/libqpdf/qpdf/RC4.hh +++ b/libqpdf/qpdf/RC4.hh @@ -11,8 +11,7 @@ class RC4 // key_len of -1 means treat key_data as a null-terminated string RC4(unsigned char const* key_data, int key_len = -1); - // It is safe to pass the same pointer to in_data and out_data to - // encrypt/decrypt in place + // It is safe to pass the same pointer to in_data and out_data to encrypt/decrypt in place void process(unsigned char const* in_data, size_t len, unsigned char* out_data); private: -- cgit v1.2.3-54-g00ecf