From 2aa789d0f49a112e41a761036ce42bf2477b9f43 Mon Sep 17 00:00:00 2001 From: Raul Metsma Date: Mon, 11 May 2026 12:54:20 +0300 Subject: [PATCH] Fix validating files with leading / IB-8933 Signed-off-by: Raul Metsma --- src/SignatureXAdES_B.cpp | 10 ++++------ src/SignatureXAdES_LTA.cpp | 3 --- src/util/File.cpp | 2 ++ test/data/test-leading-slash-uri.asice | Bin 0 -> 7181 bytes test/libdigidocpp_boost.cpp | 12 ++++++++++++ 5 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 test/data/test-leading-slash-uri.asice diff --git a/src/SignatureXAdES_B.cpp b/src/SignatureXAdES_B.cpp index ace6ac43d..ca65b2fbe 100644 --- a/src/SignatureXAdES_B.cpp +++ b/src/SignatureXAdES_B.cpp @@ -154,10 +154,11 @@ int initXmlSecCallback() return {}; } - auto find = [name](auto files) -> const DataFile* { + string uriName = File::fromUriPath(name); + auto find = [&uriName](auto files) -> const DataFile* { for(const DataFile *file: files) { - if(file->fileName() == name) + if(file->fileName() == uriName) return file; } return {}; @@ -506,10 +507,7 @@ void SignatureXAdES_B::validate(const string &policy) const EXCEPTION_ADD(exception, "Reference '%.*s' ID missing", int(uri.size()), uri.data()); else { - string uriPath = File::fromUriPath(uri); - if(uriPath.front() == '/') - uriPath.erase(0); - signatureref.emplace(uriPath, mimeinfo[string("#").append(ref["Id"])]); + signatureref.emplace(File::fromUriPath(uri), mimeinfo[string("#").append(ref["Id"])]); } } if(!signedInfoFound) diff --git a/src/SignatureXAdES_LTA.cpp b/src/SignatureXAdES_LTA.cpp index 33d341a8b..7c14acb48 100644 --- a/src/SignatureXAdES_LTA.cpp +++ b/src/SignatureXAdES_LTA.cpp @@ -54,9 +54,6 @@ void SignatureXAdES_LTA::calcArchiveDigest(const Digest &digest, string_view can } string uriPath = File::fromUriPath(uri); - if(uriPath.front() == '/') - uriPath.erase(0); - auto files = bdoc->dataFiles(); auto file = find_if(files.cbegin(), files.cend(), [&uriPath](DataFile *file) { return file->fileName() == uriPath; diff --git a/src/util/File.cpp b/src/util/File.cpp index 4f0f31a4b..0ea70c3cd 100644 --- a/src/util/File.cpp +++ b/src/util/File.cpp @@ -336,6 +336,8 @@ constexpr bool fromHexChar(auto pos, auto end, auto &value) string File::fromUriPath(string_view path) { + if(!path.empty() && path.front() == '/') + path.remove_prefix(1); string ret; ret.reserve(path.size()); uint8_t value = 0; diff --git a/test/data/test-leading-slash-uri.asice b/test/data/test-leading-slash-uri.asice new file mode 100644 index 0000000000000000000000000000000000000000..4a1286a7dae3c7f0ed8c123ec99630fcf83006ef GIT binary patch literal 7181 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 L0AK?CYsP;71Jap~ literal 0 HcmV?d00001 diff --git a/test/libdigidocpp_boost.cpp b/test/libdigidocpp_boost.cpp index 9b0d9674a..84c756203 100644 --- a/test/libdigidocpp_boost.cpp +++ b/test/libdigidocpp_boost.cpp @@ -573,6 +573,18 @@ BOOST_AUTO_TEST_CASE(manifest_data_file_dot_and_empty_paths_are_rejected) BOOST_CHECK_THROW(Container::openPtr("dot.asice"), Exception); BOOST_CHECK_THROW(Container::openPtr("pt-empty.asice"), Exception); } + +BOOST_AUTO_TEST_CASE(LeadingSlashReferenceURI) +{ + // Container signed with URI="/test1.txt" (leading slash). + // Without the erase(0,1) fix the reference path is erased to "", + // failing to match the DataFile and throwing during validate(). + auto d = Container::openPtr("test-leading-slash-uri.asice"); + BOOST_REQUIRE_EQUAL(d->dataFiles().size(), 1U); + BOOST_REQUIRE_EQUAL(d->signatures().size(), 1U); + BOOST_CHECK_EQUAL(d->dataFiles().front()->fileName(), "test1.txt"); + BOOST_CHECK_NO_THROW(d->signatures().front()->validate()); +} BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE(ASiCSTestSuite)