From d30b73aae3270205ee2c2da9440e29b5e76cc38c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Aug 2026 08:37:05 +0000 Subject: [PATCH 1/2] Switch CodeQL to supported compiler Co-authored-by: clauspruefer <17313789+clauspruefer@users.noreply.github.com> --- README.md | 2 +- lib/xml/xmlparser.cpp | 32 ++++++++++++++++++++------------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 6e8444b..dbe3637 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ The technical progression and current state of the NLAP implementation comprise 5. **C++23 Parsing Library:** Engineered a specialized, performance- and heap-optimized C++23 validation library for low-level HTTP/1.1 parsing and message generation. 6. **Architectural Refactoring:** Executed a comprehensive code-base refactoring based on the empirical performance metrics gathered from the initial reference implementations. 7. **Schema Implementation:** Developed the comprehensive structural boundaries for all NLAP protocol subtypes, formalized through complete Document Type Definitions (DTD) and YANG modeling layouts compiled with AI assistance. -8. **Zero-Copy XML Parsing Engine:** Implemented a memory-optimized XML parsing layer utilizing C++23 features (`std::generator`) and non-allocating string views (`std::string_view`) to minimize data-handling overhead, developed with AI assistance. +8. **Zero-Copy XML Parsing Engine:** Implemented a memory-optimized XML parsing layer utilizing non-allocating string views (`std::string_view`) and lightweight iteration helpers to minimize data-handling overhead, developed with AI assistance. # 5. Working Components diff --git a/lib/xml/xmlparser.cpp b/lib/xml/xmlparser.cpp index bf77afa..15acbb7 100644 --- a/lib/xml/xmlparser.cpp +++ b/lib/xml/xmlparser.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -69,13 +68,14 @@ std::string getElementText(DOMElement* Element) return trimCopy(Value); } -std::generator iterateElementChildren(DOMElement* Parent) +template +void forEachElementChild(DOMElement* Parent, Callback&& Visitor) { DOMNodeList* Children = Parent->getChildNodes(); for (XMLSize_t Index = 0; Index < Children->getLength(); ++Index) { DOMNode* Child = Children->item(Index); if (Child->getNodeType() == DOMNode::ELEMENT_NODE) { - co_yield static_cast(Child); + Visitor(static_cast(Child)); } } } @@ -85,7 +85,8 @@ struct MessageSlice std::string_view Slice; }; -std::generator splitMessages(std::string_view Input, bool& FramingError) +template +void splitMessages(std::string_view Input, bool& FramingError, Callback&& Visitor) { std::size_t Cursor = 0; std::size_t LastEnd = std::string_view::npos; @@ -98,7 +99,7 @@ std::generator splitMessages(std::string_view Input, bool& Framing if (LastEnd != std::string_view::npos && Start != LastEnd) { FramingError = true; - co_return; + return; } const std::size_t End = Input.find(NLAP_XML_END_MARKER, Start); @@ -107,7 +108,9 @@ std::generator splitMessages(std::string_view Input, bool& Framing } const std::size_t MessageEnd = End + NLAP_XML_END_MARKER.size(); - co_yield MessageSlice{Input.substr(Start, MessageEnd - Start)}; + if (!Visitor(MessageSlice{Input.substr(Start, MessageEnd - Start)})) { + return; + } Cursor = MessageEnd; LastEnd = MessageEnd; @@ -197,12 +200,12 @@ void populateTree(DOMElement* Element, XMLNode& Node, std::string_view RawMessag { bool HasElementChildren = false; - for (DOMElement* Child : iterateElementChildren(Element)) { + forEachElementChild(Element, [&](DOMElement* Child) { HasElementChildren = true; const std::string ChildName = transcodeXMLCh(Child->getTagName()); XMLNode& ChildNode = Node[ChildName]; populateTree(Child, ChildNode, RawMessage, SearchOffset); - } + }); if (HasElementChildren) { return; @@ -297,11 +300,11 @@ uint16_t parseMessage( XMLNode& RootNode = OutputTree[RootName]; std::size_t SearchOffset = 0; - for (DOMElement* Child : iterateElementChildren(Root)) { + forEachElementChild(Root, [&](DOMElement* Child) { const std::string ChildName = transcodeXMLCh(Child->getTagName()); XMLNode& ChildNode = RootNode[ChildName]; populateTree(Child, ChildNode, RawMessage, SearchOffset); - } + }); return 0; } @@ -372,17 +375,22 @@ ParseResult_t XMLParser::parse(char* InputBuffer) const } bool FramingError = false; - for (const MessageSlice& Slice : splitMessages(InputBufferSV, FramingError)) { + splitMessages(InputBufferSV, FramingError, [&](const MessageSlice& Slice) { ResultTree_t Tree; const uint16_t MessageError = parseMessage(_GrammarPool, Slice.Slice, Tree); if (MessageError != 0) { Result.ErrorCode = MessageError; Result.Results.clear(); - return Result; + return false; } Result.Results.push_back(std::move(Tree)); + return true; + }); + + if (Result.ErrorCode != 0) { + return Result; } if (FramingError) { From 178643a5dc8687027f75c7d2d5cbe34e3f7c9956 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 14 Aug 2026 08:45:12 +0000 Subject: [PATCH 2/2] Force CodeQL to use gcc-14 defaults Co-authored-by: clauspruefer <17313789+clauspruefer@users.noreply.github.com> --- .github/workflows/codeql.yml | 16 ++++++++++++---- README.md | 2 +- lib/xml/xmlparser.cpp | 32 ++++++++++++-------------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3341848..6cdfe16 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -39,11 +39,19 @@ jobs: run: | sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 140 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 140 + sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-14 140 + sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-14 140 sudo update-alternatives --set gcc /usr/bin/gcc-14 sudo update-alternatives --set g++ /usr/bin/g++-14 - cc --version | head -n1 + sudo update-alternatives --set cc /usr/bin/gcc-14 + sudo update-alternatives --set c++ /usr/bin/g++-14 + which gcc + which g++ + which cc + which c++ gcc --version | head -n1 g++ --version | head -n1 + cc --version | head -n1 c++ --version | head -n1 - name: Initialize CodeQL @@ -54,10 +62,10 @@ jobs: - name: Build env: - CC: gcc-14 - CXX: g++-14 + CC: cc + CXX: c++ run: | - cmake -B _build -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 + cmake -B _build -DCMAKE_C_COMPILER=cc -DCMAKE_CXX_COMPILER=c++ cmake --build _build --parallel $(nproc) - name: Perform CodeQL Analysis diff --git a/README.md b/README.md index dbe3637..6e8444b 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ The technical progression and current state of the NLAP implementation comprise 5. **C++23 Parsing Library:** Engineered a specialized, performance- and heap-optimized C++23 validation library for low-level HTTP/1.1 parsing and message generation. 6. **Architectural Refactoring:** Executed a comprehensive code-base refactoring based on the empirical performance metrics gathered from the initial reference implementations. 7. **Schema Implementation:** Developed the comprehensive structural boundaries for all NLAP protocol subtypes, formalized through complete Document Type Definitions (DTD) and YANG modeling layouts compiled with AI assistance. -8. **Zero-Copy XML Parsing Engine:** Implemented a memory-optimized XML parsing layer utilizing non-allocating string views (`std::string_view`) and lightweight iteration helpers to minimize data-handling overhead, developed with AI assistance. +8. **Zero-Copy XML Parsing Engine:** Implemented a memory-optimized XML parsing layer utilizing C++23 features (`std::generator`) and non-allocating string views (`std::string_view`) to minimize data-handling overhead, developed with AI assistance. # 5. Working Components diff --git a/lib/xml/xmlparser.cpp b/lib/xml/xmlparser.cpp index 15acbb7..bf77afa 100644 --- a/lib/xml/xmlparser.cpp +++ b/lib/xml/xmlparser.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -68,14 +69,13 @@ std::string getElementText(DOMElement* Element) return trimCopy(Value); } -template -void forEachElementChild(DOMElement* Parent, Callback&& Visitor) +std::generator iterateElementChildren(DOMElement* Parent) { DOMNodeList* Children = Parent->getChildNodes(); for (XMLSize_t Index = 0; Index < Children->getLength(); ++Index) { DOMNode* Child = Children->item(Index); if (Child->getNodeType() == DOMNode::ELEMENT_NODE) { - Visitor(static_cast(Child)); + co_yield static_cast(Child); } } } @@ -85,8 +85,7 @@ struct MessageSlice std::string_view Slice; }; -template -void splitMessages(std::string_view Input, bool& FramingError, Callback&& Visitor) +std::generator splitMessages(std::string_view Input, bool& FramingError) { std::size_t Cursor = 0; std::size_t LastEnd = std::string_view::npos; @@ -99,7 +98,7 @@ void splitMessages(std::string_view Input, bool& FramingError, Callback&& Visito if (LastEnd != std::string_view::npos && Start != LastEnd) { FramingError = true; - return; + co_return; } const std::size_t End = Input.find(NLAP_XML_END_MARKER, Start); @@ -108,9 +107,7 @@ void splitMessages(std::string_view Input, bool& FramingError, Callback&& Visito } const std::size_t MessageEnd = End + NLAP_XML_END_MARKER.size(); - if (!Visitor(MessageSlice{Input.substr(Start, MessageEnd - Start)})) { - return; - } + co_yield MessageSlice{Input.substr(Start, MessageEnd - Start)}; Cursor = MessageEnd; LastEnd = MessageEnd; @@ -200,12 +197,12 @@ void populateTree(DOMElement* Element, XMLNode& Node, std::string_view RawMessag { bool HasElementChildren = false; - forEachElementChild(Element, [&](DOMElement* Child) { + for (DOMElement* Child : iterateElementChildren(Element)) { HasElementChildren = true; const std::string ChildName = transcodeXMLCh(Child->getTagName()); XMLNode& ChildNode = Node[ChildName]; populateTree(Child, ChildNode, RawMessage, SearchOffset); - }); + } if (HasElementChildren) { return; @@ -300,11 +297,11 @@ uint16_t parseMessage( XMLNode& RootNode = OutputTree[RootName]; std::size_t SearchOffset = 0; - forEachElementChild(Root, [&](DOMElement* Child) { + for (DOMElement* Child : iterateElementChildren(Root)) { const std::string ChildName = transcodeXMLCh(Child->getTagName()); XMLNode& ChildNode = RootNode[ChildName]; populateTree(Child, ChildNode, RawMessage, SearchOffset); - }); + } return 0; } @@ -375,22 +372,17 @@ ParseResult_t XMLParser::parse(char* InputBuffer) const } bool FramingError = false; - splitMessages(InputBufferSV, FramingError, [&](const MessageSlice& Slice) { + for (const MessageSlice& Slice : splitMessages(InputBufferSV, FramingError)) { ResultTree_t Tree; const uint16_t MessageError = parseMessage(_GrammarPool, Slice.Slice, Tree); if (MessageError != 0) { Result.ErrorCode = MessageError; Result.Results.clear(); - return false; + return Result; } Result.Results.push_back(std::move(Tree)); - return true; - }); - - if (Result.ErrorCode != 0) { - return Result; } if (FramingError) {