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 000000000..4a1286a7d Binary files /dev/null and b/test/data/test-leading-slash-uri.asice differ 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)