summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2021-06-04 16:15:45 +0200
committerDavid Kalnischkies <david@kalnischkies.de>2021-06-04 16:45:06 +0200
commita2406cda4dd0aca523183ed6a8b651f06e0e63f9 (patch)
tree76d8caf99645fce37adc593ab4ae9c208b2d1945
parentba18c4323ecbc66e6a1e3fedae60721f9c5701b1 (diff)
No URL decode and quoting support for Files in Sources
The code exists since ever, but no other client supports this and the specification like debian-policy isn't asking for this either. What it does do is breaking than all others continue working through: If the filename includes in fact URI encoded bits (hopefully no quotes) which is rather unlikely, but none the less possible.
-rw-r--r--apt-pkg/deb/debsrcrecords.cc30
-rwxr-xr-xtest/integration/test-uri-encode-filename-field10
2 files changed, 24 insertions, 16 deletions
diff --git a/apt-pkg/deb/debsrcrecords.cc b/apt-pkg/deb/debsrcrecords.cc
index 89f3f1667..1fd0fdc12 100644
--- a/apt-pkg/deb/debsrcrecords.cc
+++ b/apt-pkg/deb/debsrcrecords.cc
@@ -23,6 +23,7 @@
#include <algorithm>
#include <string>
+#include <sstream>
#include <vector>
#include <ctype.h>
#include <stdlib.h>
@@ -170,6 +171,7 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
std::vector<std::string> const compExts = APT::Configuration::getCompressorExtensions();
+ auto const &posix = std::locale::classic();
for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
{
// derive field from checksum type
@@ -182,27 +184,23 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
string const Files = Sect.FindS(checksumField.c_str());
if (Files.empty() == true)
continue;
+ std::istringstream ss(Files);
+ ss.imbue(posix);
- // Iterate over the entire list grabbing each triplet
- const char *C = Files.c_str();
- while (*C != 0)
+ while (ss.good())
{
- string hash, size, path;
-
- // Parse each of the elements
- if (ParseQuoteWord(C, hash) == false ||
- ParseQuoteWord(C, size) == false ||
- ParseQuoteWord(C, path) == false)
- return _error->Error("Error parsing file record in %s of source package %s", checksumField.c_str(), Package().c_str());
-
+ std::string hash, path;
+ unsigned long long size;
if (iIndex == nullptr && checksumField == "Files")
{
- // the Files field has a different format than the rest in deb-changes files
std::string ignore;
- if (ParseQuoteWord(C, ignore) == false ||
- ParseQuoteWord(C, path) == false)
- return _error->Error("Error parsing file record in %s of source package %s", checksumField.c_str(), Package().c_str());
+ ss >> hash >> size >> ignore >> ignore >> path;
}
+ else
+ ss >> hash >> size >> path;
+
+ if (ss.fail() || hash.empty() || path.empty())
+ return _error->Error("Error parsing file record in %s of source package %s", checksumField.c_str(), Package().c_str());
HashString const hashString(*type, hash);
if (Base.empty() == false)
@@ -226,7 +224,7 @@ bool debSrcRecordParser::Files(std::vector<pkgSrcRecords::File> &List)
// we haven't seen this file yet
pkgSrcRecords::File F;
F.Path = path;
- F.FileSize = strtoull(size.c_str(), NULL, 10);
+ F.FileSize = size;
F.Hashes.push_back(hashString);
F.Hashes.FileSize(F.FileSize);
diff --git a/test/integration/test-uri-encode-filename-field b/test/integration/test-uri-encode-filename-field
index dffee21aa..233332d0a 100755
--- a/test/integration/test-uri-encode-filename-field
+++ b/test/integration/test-uri-encode-filename-field
@@ -17,19 +17,29 @@ runtest() {
testsuccess apt download foo
testsuccess rm 'foo_0+0~0_all.deb'
testsuccess apt install foo
+ testsuccess apt source foo
+ testsuccess rm 'foo_0+0~0.dsc' 'foo_0+0~0.tar.xz'
+ testsuccess rm -r 'foo-0+0~0'
mv '../aptarchive/pool/foo_0+0~0_all.deb' '../aptarchive/pool/foo_0%3a0+0~0_all.deb'
+ mv '../aptarchive/pool/foo_0+0~0.dsc' '../aptarchive/pool/foo_0%3a0+0~0.dsc'
testsuccess apt purge foo -y
testfailure apt download foo
testfailure apt install foo
+ testfailure apt source foo --dsc-only
sed -i -e 's#_0+0~0_#_0%3a0+0~0_#' ../rootdir/var/lib/apt/lists/*Packages
+ sed -i -e 's#_0+0~0.d#_0%3a0+0~0.d#' ../rootdir/var/lib/apt/lists/*Sources
testsuccess apt download foo
testsuccess rm 'foo_0+0~0_all.deb'
testsuccess apt install foo
+ testsuccess apt source foo
+ testsuccess rm 'foo_0%3a0+0~0.dsc' 'foo_0+0~0.tar.xz'
+ testsuccess rm -r 'foo-0+0~0'
cd "$TMPWORKINGDIRECTORY" >/dev/null
mv 'aptarchive/pool/foo_0%3a0+0~0_all.deb' 'aptarchive/pool/foo_0+0~0_all.deb'
+ mv 'aptarchive/pool/foo_0%3a0+0~0.dsc' 'aptarchive/pool/foo_0+0~0.dsc'
}
runtest 'file'