From f76994f1fb3e25c4563c9d8afce6bbc86701d1d2 Mon Sep 17 00:00:00 2001 From: "B. Stack" Date: Tue, 20 Jun 2023 07:46:53 -0400 Subject: add upstream 12.4 --- zenXml/zenxml/parser.h | 2 +- zenXml/zenxml/xml.h | 46 ++++++++++++++++++++++------------------------ 2 files changed, 23 insertions(+), 25 deletions(-) (limited to 'zenXml/zenxml') diff --git a/zenXml/zenxml/parser.h b/zenXml/zenxml/parser.h index 14ccfd60..8416c211 100644 --- a/zenXml/zenxml/parser.h +++ b/zenXml/zenxml/parser.h @@ -314,7 +314,7 @@ public: explicit Scanner(const std::string& stream) : stream_(stream), pos_(stream_.begin()) { if (zen::startsWith(stream_, BYTE_ORDER_MARK_UTF8)) - pos_ += strLength(BYTE_ORDER_MARK_UTF8); + pos_ += BYTE_ORDER_MARK_UTF8.size(); } Token getNextToken() //throw XmlParsingError diff --git a/zenXml/zenxml/xml.h b/zenXml/zenxml/xml.h index 10f0ecd8..8b86a49f 100644 --- a/zenXml/zenxml/xml.h +++ b/zenXml/zenxml/xml.h @@ -34,39 +34,37 @@ namespace { XmlDoc loadXml(const Zstring& filePath) //throw FileError { - FileInputPlain fileIn(filePath); //throw FileError - const size_t blockSize = fileIn.getBlockSize(); //throw FileError - bool xmlPrefixChecked = false; + FileInputPlain fileIn(filePath); //throw FileError, ErrorFileLocked + std::string headBuf; + const size_t headSizeMin = BYTE_ORDER_MARK_UTF8.size() + strLength(""); - std::string buffer; - for (;;) + const std::string buf = unbufferedLoad([&](void* buffer, size_t bytesToRead) { - warn_static("don't need zero-initialization! => resize_and_overwrite") - buffer.resize(buffer.size() + blockSize); - const size_t bytesRead = fileIn.tryRead(&*(buffer.end() - blockSize), blockSize); //throw FileError; may return short, only 0 means EOF! CONTRACT: bytesToRead > 0! - buffer.resize(buffer.size() - blockSize + bytesRead); //caveat: unsigned arithmetics + const size_t bytesRead = fileIn.tryRead(buffer, bytesToRead); //throw FileError; may return short, only 0 means EOF! => CONTRACT: bytesToRead > 0! //quick test whether input is an XML: avoid loading large binary files up front! - if (!xmlPrefixChecked && buffer.size() >= strLength(BYTE_ORDER_MARK_UTF8) + strLength("")) + if (headBuf.size() < headSizeMin) { - xmlPrefixChecked = true; - - std::string_view bufStart = buffer; - if (startsWith(bufStart, BYTE_ORDER_MARK_UTF8)) - bufStart.remove_prefix(strLength(BYTE_ORDER_MARK_UTF8)); - - if (!startsWith(bufStart, "")) - throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtPath(filePath))); + headBuf.append(static_cast(buffer), std::min(headSizeMin - headBuf.size(), bytesRead)); + + if (headBuf.size() == headSizeMin) + { + std::string_view header = headBuf; + if (startsWith(header, BYTE_ORDER_MARK_UTF8)) + header.remove_prefix(BYTE_ORDER_MARK_UTF8.size()); //keep headBuf.size()! + + if (!startsWith(header, "")) + throw FileError(replaceCpy(_("File %x does not contain a valid configuration."), L"%x", fmtPath(filePath))); + } } - - if (bytesRead == 0) //end of file - break; - } + return bytesRead; + }, + fileIn.getBlockSize()); //throw FileError try { - return parseXml(buffer); //throw XmlParsingError + return parseXml(buf); //throw XmlParsingError } catch (const XmlParsingError& e) { -- cgit