Don't trim whitespace when reading database entries
We don't write with extra or unknown whitespace, so there is little reason for us to trim it when reading either. This also fixes the hopefully never encountered "paths that start or end with spaces" issue, for which two pactests have been added. The tests also contain other evil characters that we have encountered before and handle just fine, but it doesn't hurt to ensure we don't break such support in the future. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
573260556d
commit
cbaff216b3
8 changed files with 122 additions and 16 deletions
|
@ -500,7 +500,7 @@ static char *get_pkgpath(alpm_db_t *db, alpm_pkg_t *info)
|
||||||
|
|
||||||
#define READ_NEXT() do { \
|
#define READ_NEXT() do { \
|
||||||
if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
|
if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
|
||||||
_alpm_strtrim(line); \
|
_alpm_strip_newline(line); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define READ_AND_STORE(f) do { \
|
#define READ_AND_STORE(f) do { \
|
||||||
|
@ -510,8 +510,8 @@ static char *get_pkgpath(alpm_db_t *db, alpm_pkg_t *info)
|
||||||
|
|
||||||
#define READ_AND_STORE_ALL(f) do { \
|
#define READ_AND_STORE_ALL(f) do { \
|
||||||
char *linedup; \
|
char *linedup; \
|
||||||
READ_NEXT(); \
|
if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
|
||||||
if(strlen(line) == 0) break; \
|
if(_alpm_strip_newline(line) == 0) break; \
|
||||||
STRDUP(linedup, line, goto error); \
|
STRDUP(linedup, line, goto error); \
|
||||||
f = alpm_list_add(f, linedup); \
|
f = alpm_list_add(f, linedup); \
|
||||||
} while(1) /* note the while(1) and not (0) */
|
} while(1) /* note the while(1) and not (0) */
|
||||||
|
@ -629,12 +629,12 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
while(fgets(line, sizeof(line), fp)) {
|
while(fgets(line, sizeof(line), fp)) {
|
||||||
_alpm_strtrim(line);
|
_alpm_strip_newline(line);
|
||||||
if(strcmp(line, "%FILES%") == 0) {
|
if(strcmp(line, "%FILES%") == 0) {
|
||||||
size_t files_count = 0, files_size = 0;
|
size_t files_count = 0, files_size = 0;
|
||||||
alpm_file_t *files = NULL;
|
alpm_file_t *files = NULL;
|
||||||
|
|
||||||
while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
|
while(fgets(line, sizeof(line), fp) && _alpm_strip_newline(line)) {
|
||||||
if(files_count >= files_size) {
|
if(files_count >= files_size) {
|
||||||
size_t old_size = files_size;
|
size_t old_size = files_size;
|
||||||
if(files_size == 0) {
|
if(files_size == 0) {
|
||||||
|
@ -661,7 +661,7 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
|
||||||
info->files.count = files_count;
|
info->files.count = files_count;
|
||||||
info->files.files = files;
|
info->files.files = files;
|
||||||
} else if(strcmp(line, "%BACKUP%") == 0) {
|
} else if(strcmp(line, "%BACKUP%") == 0) {
|
||||||
while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
|
while(fgets(line, sizeof(line), fp) && _alpm_strip_newline(line)) {
|
||||||
alpm_backup_t *backup;
|
alpm_backup_t *backup;
|
||||||
CALLOC(backup, 1, sizeof(alpm_backup_t), goto error);
|
CALLOC(backup, 1, sizeof(alpm_backup_t), goto error);
|
||||||
if(_alpm_split_backup(line, &backup)) {
|
if(_alpm_split_backup(line, &backup)) {
|
||||||
|
|
|
@ -149,13 +149,13 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
|
||||||
|
|
||||||
/* loop until we reach EOF or other error */
|
/* loop until we reach EOF or other error */
|
||||||
while((ret = _alpm_archive_fgets(a, &buf)) == ARCHIVE_OK) {
|
while((ret = _alpm_archive_fgets(a, &buf)) == ARCHIVE_OK) {
|
||||||
char *line = _alpm_strtrim(buf.line);
|
size_t len = _alpm_strip_newline(buf.line);
|
||||||
|
|
||||||
linenum++;
|
linenum++;
|
||||||
if(strlen(line) == 0 || line[0] == '#') {
|
if(len == 0 || buf.line[0] == '#') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ptr = line;
|
ptr = buf.line;
|
||||||
key = strsep(&ptr, "=");
|
key = strsep(&ptr, "=");
|
||||||
if(key == NULL || ptr == NULL) {
|
if(key == NULL || ptr == NULL) {
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
|
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
|
||||||
|
@ -213,7 +213,6 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
|
||||||
newpkg->name ? newpkg->name : "error", key, linenum);
|
newpkg->name ? newpkg->name : "error", key, linenum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line[0] = '\0';
|
|
||||||
}
|
}
|
||||||
if(ret != ARCHIVE_EOF) {
|
if(ret != ARCHIVE_EOF) {
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "error parsing package descfile\n");
|
_alpm_log(handle, ALPM_LOG_DEBUG, "error parsing package descfile\n");
|
||||||
|
|
|
@ -443,7 +443,8 @@ static int sync_db_populate(alpm_db_t *db)
|
||||||
|
|
||||||
#define READ_NEXT() do { \
|
#define READ_NEXT() do { \
|
||||||
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
|
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
|
||||||
line = _alpm_strtrim(buf.line); \
|
line = buf.line; \
|
||||||
|
_alpm_strip_newline(line); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#define READ_AND_STORE(f) do { \
|
#define READ_AND_STORE(f) do { \
|
||||||
|
@ -453,9 +454,9 @@ static int sync_db_populate(alpm_db_t *db)
|
||||||
|
|
||||||
#define READ_AND_STORE_ALL(f) do { \
|
#define READ_AND_STORE_ALL(f) do { \
|
||||||
char *linedup; \
|
char *linedup; \
|
||||||
READ_NEXT(); \
|
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
|
||||||
if(strlen(line) == 0) break; \
|
if(_alpm_strip_newline(buf.line) == 0) break; \
|
||||||
STRDUP(linedup, line, goto error); \
|
STRDUP(linedup, buf.line, goto error); \
|
||||||
f = alpm_list_add(f, linedup); \
|
f = alpm_list_add(f, linedup); \
|
||||||
} while(1) /* note the while(1) and not (0) */
|
} while(1) /* note the while(1) and not (0) */
|
||||||
|
|
||||||
|
@ -493,7 +494,8 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||||
|| strcmp(filename, "deltas") == 0) {
|
|| strcmp(filename, "deltas") == 0) {
|
||||||
int ret;
|
int ret;
|
||||||
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
||||||
char *line = _alpm_strtrim(buf.line);
|
char *line = buf.line;
|
||||||
|
_alpm_strip_newline(line);
|
||||||
|
|
||||||
if(strcmp(line, "%NAME%") == 0) {
|
if(strcmp(line, "%NAME%") == 0) {
|
||||||
READ_NEXT();
|
READ_NEXT();
|
||||||
|
|
|
@ -207,6 +207,26 @@ char *_alpm_strtrim(char *str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trim trailing newline from a string (if one exists).
|
||||||
|
* @param str a single line of text
|
||||||
|
* @return the length of the trimmed string
|
||||||
|
*/
|
||||||
|
size_t _alpm_strip_newline(char *str)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
if(str == '\0') {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
len = strlen(str);
|
||||||
|
while(str[len - 1] == '\n') {
|
||||||
|
len--;
|
||||||
|
}
|
||||||
|
str[len] = '\0';
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compression functions */
|
/* Compression functions */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -95,6 +95,7 @@ int _alpm_makepath(const char *path);
|
||||||
int _alpm_makepath_mode(const char *path, mode_t mode);
|
int _alpm_makepath_mode(const char *path, mode_t mode);
|
||||||
int _alpm_copyfile(const char *src, const char *dest);
|
int _alpm_copyfile(const char *src, const char *dest);
|
||||||
char *_alpm_strtrim(char *str);
|
char *_alpm_strtrim(char *str);
|
||||||
|
size_t _alpm_strip_newline(char *str);
|
||||||
int _alpm_unpack_single(alpm_handle_t *handle, const char *archive,
|
int _alpm_unpack_single(alpm_handle_t *handle, const char *archive,
|
||||||
const char *prefix, const char *filename);
|
const char *prefix, const char *filename);
|
||||||
int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix,
|
int _alpm_unpack(alpm_handle_t *handle, const char *archive, const char *prefix,
|
||||||
|
|
|
@ -42,7 +42,7 @@ class pmrule(object):
|
||||||
[testname, args] = self.rule.split("=")
|
[testname, args] = self.rule.split("=")
|
||||||
if testname[0] == "!":
|
if testname[0] == "!":
|
||||||
self.false = 1
|
self.false = 1
|
||||||
testname = testname.lstrip("!")
|
testname = testname[1:]
|
||||||
[kind, case] = testname.split("_")
|
[kind, case] = testname.split("_")
|
||||||
if "|" in args:
|
if "|" in args:
|
||||||
[key, value] = args.split("|", 1)
|
[key, value] = args.split("|", 1)
|
||||||
|
|
33
test/pacman/tests/remove071.py
Normal file
33
test/pacman/tests/remove071.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# coding=utf8
|
||||||
|
self.description = "Remove packages with evil filenames"
|
||||||
|
|
||||||
|
self.filesystem = ["usr/bin/endwithspace",
|
||||||
|
"spaces/name"]
|
||||||
|
|
||||||
|
p1 = pmpkg("spaces")
|
||||||
|
p1.files = ["usr/bin/endwithspace ",
|
||||||
|
" spaces/name"]
|
||||||
|
self.addpkg2db("local", p1)
|
||||||
|
|
||||||
|
p2 = pmpkg("unicodechars")
|
||||||
|
# somewhat derived from FS#9906
|
||||||
|
p2.files = ["usr/share/Märchen",
|
||||||
|
"usr/share/ƏƐƕƺ",
|
||||||
|
"usr/share/предупреждение",
|
||||||
|
"usr/share/סֶאבױ",
|
||||||
|
"usr/share/←↯↻⇈",
|
||||||
|
"usr/share/アヅヨヾ",
|
||||||
|
"usr/share/错误"]
|
||||||
|
self.addpkg2db("local", p2)
|
||||||
|
|
||||||
|
self.args = "-R %s %s" % (p1.name, p2.name)
|
||||||
|
|
||||||
|
self.addrule("PACMAN_RETCODE=0")
|
||||||
|
self.addrule("!PKG_EXIST=%s" % p1.name)
|
||||||
|
self.addrule("!PKG_EXIST=%s" % p2.name)
|
||||||
|
|
||||||
|
for f in p1.files:
|
||||||
|
self.addrule("!FILE_EXIST=%s" % f)
|
||||||
|
self.addrule("FILE_EXIST=%s" % f.strip())
|
||||||
|
for f in p2.files:
|
||||||
|
self.addrule("!FILE_EXIST=%s" % f)
|
51
test/pacman/tests/sync600.py
Normal file
51
test/pacman/tests/sync600.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# coding=utf8
|
||||||
|
self.description = "Sync packages with evil filenames"
|
||||||
|
|
||||||
|
self.filesystem = ["usr/bin/endwithspace",
|
||||||
|
"usr/bin/newendwithspace",
|
||||||
|
"usr/bin/disappear",
|
||||||
|
"spaces/name",
|
||||||
|
"spaces/name2"]
|
||||||
|
|
||||||
|
p1 = pmpkg("spaces")
|
||||||
|
p1.files = ["usr/bin/endwithspace ",
|
||||||
|
"usr/bin/disappear ",
|
||||||
|
" spaces/name",
|
||||||
|
" spaces/gone"]
|
||||||
|
self.addpkg2db("local", p1)
|
||||||
|
|
||||||
|
sp1 = pmpkg("spaces", "1.1-1")
|
||||||
|
sp1.files = ["usr/bin/endwithspace ",
|
||||||
|
"usr/bin/newendwithspace ",
|
||||||
|
" spaces/name",
|
||||||
|
" spaces/name2"]
|
||||||
|
self.addpkg2db("sync", sp1)
|
||||||
|
|
||||||
|
names = ["Märchen", "ƏƐƕƺ", "предупреждение", "סֶאבױ",
|
||||||
|
"←↯↻⇈", "アヅヨヾ", "错误"]
|
||||||
|
|
||||||
|
p2 = pmpkg("unicodechars")
|
||||||
|
# somewhat derived from FS#9906
|
||||||
|
p2.files = ["usr/share/%s" % name for name in names]
|
||||||
|
self.addpkg2db("local", p2)
|
||||||
|
|
||||||
|
sp2 = pmpkg("unicodechars", "2.0-1")
|
||||||
|
sp2.files = ["usr/man/%s" % name for name in names]
|
||||||
|
self.addpkg2db("sync", sp2)
|
||||||
|
|
||||||
|
self.args = "-S %s %s" % (sp1.name, sp2.name)
|
||||||
|
|
||||||
|
self.addrule("PACMAN_RETCODE=0")
|
||||||
|
self.addrule("PKG_VERSION=%s|%s" % (sp1.name, sp1.version))
|
||||||
|
self.addrule("PKG_VERSION=%s|%s" % (sp2.name, sp2.version))
|
||||||
|
|
||||||
|
for f in self.filesystem:
|
||||||
|
self.addrule("FILE_EXIST=%s" % f)
|
||||||
|
self.addrule("FILE_EXIST=usr/bin/endwithspace ")
|
||||||
|
self.addrule("FILE_EXIST= spaces/name")
|
||||||
|
self.addrule("FILE_EXIST= spaces/name2")
|
||||||
|
self.addrule("!FILE_EXIST=usr/bin/disappear ")
|
||||||
|
for f in p2.files:
|
||||||
|
self.addrule("!FILE_EXIST=%s" % f)
|
||||||
|
for f in sp2.files:
|
||||||
|
self.addrule("FILE_EXIST=%s" % f)
|
Loading…
Add table
Reference in a new issue