From 5ad24f82799477729c4d5dac3984fc18de57382e Mon Sep 17 00:00:00 2001 From: "U. Bruhin" Date: Tue, 28 Apr 2026 17:43:19 +0200 Subject: [PATCH] DomElement: Ignore garbage bytes \x0C and \x06 in XML files It seems that some EAGLE projects (maybe only the Arduino Nano schematic?) contain garbage bytes, effectively making the XML invalid and the parser failing. Thus now stripping those two garbage bytes from the input data. --- parseagle/board/board.cpp | 2 +- parseagle/common/domelement.cpp | 15 +++++++++------ parseagle/common/domelement.h | 2 +- parseagle/library.cpp | 4 ++-- parseagle/schematic/schematic.cpp | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/parseagle/board/board.cpp b/parseagle/board/board.cpp index bfb435e..286e2b0 100644 --- a/parseagle/board/board.cpp +++ b/parseagle/board/board.cpp @@ -28,7 +28,7 @@ Board::~Board() noexcept void Board::load(const QByteArray& content, QStringList* errors) { - const DomElement root = DomElement::parse(content); + const DomElement root = DomElement::parseDocument(content); const DomElement drawing = root.getFirstChild("drawing"); if (drawing.hasChild("grid")) { diff --git a/parseagle/common/domelement.cpp b/parseagle/common/domelement.cpp index 1e0afd3..c9a05aa 100644 --- a/parseagle/common/domelement.cpp +++ b/parseagle/common/domelement.cpp @@ -51,18 +51,21 @@ DomElement DomElement::parse(QXmlStreamReader& reader) return root; } -DomElement DomElement::parse(const QString& data) +DomElement DomElement::parse(const QByteArray& data) { QXmlStreamReader reader; reader.addData(data); return parse(reader); } -DomElement DomElement::parse(const QByteArray& data) +DomElement DomElement::parseDocument(QByteArray data) { - QXmlStreamReader reader; - reader.addData(data); - return parse(reader); + // Workaround for garbage in some Eagle XML files, see + // https://gitlab.com/kicad/code/kicad/-/work_items/11008 + data.replace("\x0c", ""); + data.replace("\x06", ""); + + return parse(data); } QString DomElement::getAttributeAsString(const QString& name) const @@ -72,7 +75,7 @@ QString DomElement::getAttributeAsString(const QString& name) const } else { throw std::runtime_error( QString("Attribute '%1' not found in XML element '%2'.") - .arg(name).arg(mName).toStdString()); + .arg(name, mName).toStdString()); } } diff --git a/parseagle/common/domelement.h b/parseagle/common/domelement.h index b1cc634..c7cc534 100644 --- a/parseagle/common/domelement.h +++ b/parseagle/common/domelement.h @@ -16,8 +16,8 @@ class DomElement final // Parsers static DomElement parse(QXmlStreamReader& reader); - static DomElement parse(const QString& data); static DomElement parse(const QByteArray& data); + static DomElement parseDocument(QByteArray data); // Getters const QString& getTagName() const noexcept {return mName;} diff --git a/parseagle/library.cpp b/parseagle/library.cpp index a0927c0..d02ee6d 100644 --- a/parseagle/library.cpp +++ b/parseagle/library.cpp @@ -24,7 +24,7 @@ Library::Library(const QByteArray& content, QStringList* errors) Library::Library(const DomElement& root, QStringList* errors) { - load(root, errors); + load(root, errors); } Library::~Library() noexcept @@ -33,7 +33,7 @@ Library::~Library() noexcept void Library::load(const QByteArray& content, QStringList* errors) { - const DomElement root = DomElement::parse(content); + const DomElement root = DomElement::parseDocument(content); const DomElement drawing = root.getFirstChild("drawing"); const DomElement library = drawing.getFirstChild("library"); load(library, errors); diff --git a/parseagle/schematic/schematic.cpp b/parseagle/schematic/schematic.cpp index b36ba24..0739638 100644 --- a/parseagle/schematic/schematic.cpp +++ b/parseagle/schematic/schematic.cpp @@ -27,7 +27,7 @@ Schematic::~Schematic() noexcept } void Schematic::load(const QByteArray& content, QStringList* errors) { - const DomElement root = DomElement::parse(content); + const DomElement root = DomElement::parseDocument(content); const DomElement drawing = root.getFirstChild("drawing"); if (drawing.hasChild("grid")) {