forked from mirrors/pacman
Compare commits
11 Commits
allan/priv
...
morganamil
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83838214b7 | ||
|
|
4baeb8e40b | ||
|
|
18b65ec909 | ||
|
|
45ce932fd0 | ||
|
|
da4b590bce | ||
|
|
0649a66ee5 | ||
|
|
6e6d3f18e3 | ||
|
|
0a394144b2 | ||
|
|
fde59b99e8 | ||
|
|
edd57c8b96 | ||
|
|
5c75a55c7d |
@@ -1149,7 +1149,9 @@ typedef enum _alpm_progress_t {
|
||||
* make take a while to complete.
|
||||
* @param ctx user-provided context
|
||||
* @param progress the kind of event that is progressing
|
||||
* @param pkg for package operations, the name of the package being operated on
|
||||
* @param pkg the name of the package being operated on. if the progress kind
|
||||
* is a packae operation (add, upgrade, downgrade, reinstall, remove).
|
||||
* otherwise this will be an empty string.
|
||||
* @param percent the percent completion of the action
|
||||
* @param howmany the total amount of items in the action
|
||||
* @param current the current amount of items completed
|
||||
@@ -2293,7 +2295,9 @@ typedef enum _alpm_pkgreason_t {
|
||||
/** Explicitly requested by the user. */
|
||||
ALPM_PKG_REASON_EXPLICIT = 0,
|
||||
/** Installed as a dependency for another package. */
|
||||
ALPM_PKG_REASON_DEPEND = 1
|
||||
ALPM_PKG_REASON_DEPEND = 1,
|
||||
/** Failed parsing of local database */
|
||||
ALPM_PKG_REASON_UNKNOWN = 2
|
||||
} alpm_pkgreason_t;
|
||||
|
||||
/** Location a package object was loaded from. */
|
||||
|
||||
@@ -630,6 +630,10 @@ static int local_db_populate(alpm_db_t *db)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* treat local metadata errors as warning-only,
|
||||
* they are already installed and otherwise they can't be operated on */
|
||||
_alpm_pkg_check_meta(pkg);
|
||||
|
||||
/* add to the collection */
|
||||
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
||||
pkg->name, db->treename);
|
||||
@@ -650,6 +654,17 @@ static int local_db_populate(alpm_db_t *db)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static alpm_pkgreason_t _read_pkgreason(alpm_handle_t *handle, const char *pkgname, const char *line) {
|
||||
if(strcmp(line, "0") == 0) {
|
||||
return ALPM_PKG_REASON_EXPLICIT;
|
||||
} else if(strcmp(line, "1") == 0) {
|
||||
return ALPM_PKG_REASON_DEPEND;
|
||||
} else {
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("unknown install reason for package %s: %s\n"), pkgname, line);
|
||||
return ALPM_PKG_REASON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: the return value must be freed by the caller */
|
||||
char *_alpm_local_db_pkgpath(alpm_db_t *db, alpm_pkg_t *info,
|
||||
const char *filename)
|
||||
@@ -772,7 +787,7 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
|
||||
READ_AND_STORE(info->packager);
|
||||
} else if(strcmp(line, "%REASON%") == 0) {
|
||||
READ_NEXT();
|
||||
info->reason = (alpm_pkgreason_t)atoi(line);
|
||||
info->reason = _read_pkgreason(db->handle, info->name, line);
|
||||
} else if(strcmp(line, "%VALIDATION%") == 0) {
|
||||
alpm_list_t *i, *v = NULL;
|
||||
READ_AND_STORE_ALL(v);
|
||||
@@ -822,6 +837,12 @@ static int local_db_read(alpm_pkg_t *info, int inforeq)
|
||||
}
|
||||
}
|
||||
FREELIST(lines);
|
||||
} else {
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s: unknown key '%s' in sync database\n"), info->name, line);
|
||||
alpm_list_t *lines = NULL;
|
||||
READ_AND_STORE_ALL(lines);
|
||||
FREELIST(lines);
|
||||
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
@@ -251,8 +251,10 @@ static int parse_descfile(alpm_handle_t *handle, struct archive *a, alpm_pkg_t *
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
const char *pkgname = newpkg->name ? newpkg->name : "error";
|
||||
_alpm_log(handle, ALPM_LOG_ERROR, _("%s: unknown key '%s' in package description\n"), pkgname, key);
|
||||
_alpm_log(handle, ALPM_LOG_DEBUG, "%s: unknown key '%s' in description file line %d\n",
|
||||
newpkg->name ? newpkg->name : "error", key, linenum);
|
||||
pkgname, key, linenum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -652,8 +654,6 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
|
||||
goto pkg_invalid;
|
||||
}
|
||||
|
||||
_alpm_archive_read_free(archive);
|
||||
|
||||
/* internal fields for package struct */
|
||||
newpkg->origin = ALPM_PKG_FROM_FILE;
|
||||
STRDUP(newpkg->origin_data.file, pkgfile, goto error);
|
||||
@@ -675,6 +675,11 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle,
|
||||
newpkg->infolevel |= INFRQ_FILES;
|
||||
}
|
||||
|
||||
if(_alpm_pkg_check_meta(newpkg) != 0) {
|
||||
goto pkg_invalid;
|
||||
}
|
||||
|
||||
_alpm_archive_read_free(archive);
|
||||
close(fd);
|
||||
return newpkg;
|
||||
|
||||
|
||||
@@ -344,6 +344,11 @@ static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
|
||||
pkg->ops = get_sync_pkg_ops();
|
||||
pkg->handle = db->handle;
|
||||
|
||||
if(_alpm_pkg_check_meta(pkg) != 0) {
|
||||
_alpm_pkg_free(pkg);
|
||||
RET_ERR(db->handle, ALPM_ERR_PKG_INVALID, NULL);
|
||||
}
|
||||
|
||||
/* add to the collection */
|
||||
_alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
|
||||
pkg->name, db->treename);
|
||||
@@ -452,6 +457,14 @@ static int sync_db_populate(alpm_db_t *db)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* the db file was successfully read, but contained errors */
|
||||
if(ret == -1) {
|
||||
db->status &= ~DB_STATUS_VALID;
|
||||
db->status |= DB_STATUS_INVALID;
|
||||
_alpm_db_free_pkgcache(db);
|
||||
GOTO_ERR(db->handle, ALPM_ERR_DB_INVALID, cleanup);
|
||||
}
|
||||
/* reading the db file failed */
|
||||
if(archive_ret != ARCHIVE_EOF) {
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("could not read db '%s' (%s)\n"),
|
||||
db->treename, archive_error_string(archive));
|
||||
@@ -678,6 +691,11 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||
}
|
||||
}
|
||||
FREELIST(lines);
|
||||
} else {
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s: unknown key '%s' in local database\n"), pkg->name, line);
|
||||
alpm_list_t *lines = NULL;
|
||||
READ_AND_STORE_ALL(lines);
|
||||
FREELIST(lines);
|
||||
}
|
||||
}
|
||||
if(ret != ARCHIVE_EOF) {
|
||||
|
||||
@@ -563,18 +563,17 @@ static void free_groupcache(alpm_db_t *db)
|
||||
|
||||
void _alpm_db_free_pkgcache(alpm_db_t *db)
|
||||
{
|
||||
if(db == NULL || !(db->status & DB_STATUS_PKGCACHE)) {
|
||||
if(db == NULL || db->pkgcache == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
_alpm_log(db->handle, ALPM_LOG_DEBUG,
|
||||
"freeing package cache for repository '%s'\n", db->treename);
|
||||
|
||||
if(db->pkgcache) {
|
||||
alpm_list_free_inner(db->pkgcache->list,
|
||||
(alpm_list_fn_free)_alpm_pkg_free);
|
||||
_alpm_pkghash_free(db->pkgcache);
|
||||
}
|
||||
alpm_list_free_inner(db->pkgcache->list,
|
||||
(alpm_list_fn_free)_alpm_pkg_free);
|
||||
_alpm_pkghash_free(db->pkgcache);
|
||||
db->pkgcache = NULL;
|
||||
db->status &= ~DB_STATUS_PKGCACHE;
|
||||
|
||||
free_groupcache(db);
|
||||
|
||||
@@ -556,7 +556,7 @@ static void _alpm_select_depends(alpm_list_t **from, alpm_list_t **to,
|
||||
for(i = *from; i; i = next) {
|
||||
alpm_pkg_t *deppkg = i->data;
|
||||
next = i->next;
|
||||
if((explicit || alpm_pkg_get_reason(deppkg) != ALPM_PKG_REASON_EXPLICIT)
|
||||
if((explicit || alpm_pkg_get_reason(deppkg) == ALPM_PKG_REASON_DEPEND)
|
||||
&& _alpm_pkg_depends_on(pkg, deppkg)) {
|
||||
*to = alpm_list_add(*to, deppkg);
|
||||
*from = alpm_list_remove_item(*from, i);
|
||||
|
||||
@@ -573,7 +573,6 @@ static int curl_check_finished_download(alpm_handle_t *handle, CURLM *curlm, CUR
|
||||
case CURLE_ABORTED_BY_CALLBACK:
|
||||
/* handle the interrupt accordingly */
|
||||
if(dload_interrupted == ABORT_OVER_MAXFILESIZE) {
|
||||
curlerr = CURLE_FILESIZE_EXCEEDED;
|
||||
payload->unlink_on_fail = 1;
|
||||
handle->pm_errno = ALPM_ERR_LIBCURL;
|
||||
_alpm_log(handle, ALPM_LOG_ERROR,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
@@ -844,3 +845,58 @@ int SYMEXPORT alpm_pkg_should_ignore(alpm_handle_t *handle, alpm_pkg_t *pkg)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check that package metadata meets our requirements */
|
||||
int _alpm_pkg_check_meta(alpm_pkg_t *pkg)
|
||||
{
|
||||
char *c;
|
||||
int error_found = 0;
|
||||
|
||||
#define EPKGMETA(error) do { \
|
||||
error_found = -1; \
|
||||
_alpm_log(pkg->handle, ALPM_LOG_ERROR, error, pkg->name, pkg->version); \
|
||||
} while(0)
|
||||
|
||||
/* sanity check */
|
||||
if(pkg->handle == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* immediate bail if package doesn't have name or version */
|
||||
if(pkg->name == NULL || pkg->name[0] == '\0'
|
||||
|| pkg->version == NULL || pkg->version[0] == '\0') {
|
||||
_alpm_log(pkg->handle, ALPM_LOG_ERROR,
|
||||
_("invalid package metadata (name or version missing)"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pkg->name[0] == '-' || pkg->name[0] == '.') {
|
||||
EPKGMETA(_("invalid metadata for package %s-%s "
|
||||
"(package name cannot start with '.' or '-')\n"));
|
||||
}
|
||||
if(_alpm_fnmatch(pkg->name, "[![:alnum:]+_.@-]") == 0) {
|
||||
EPKGMETA(_("invalid metadata for package %s-%s "
|
||||
"(package name contains invalid characters)\n"));
|
||||
}
|
||||
|
||||
/* multiple '-' in pkgver can cause local db entries for different packages
|
||||
* to overlap (e.g. foo-1=2-3 and foo=1-2-3 both give foo-1-2-3) */
|
||||
if((c = strchr(pkg->version, '-')) && (strchr(c + 1, '-'))) {
|
||||
EPKGMETA(_("invalid metadata for package %s-%s "
|
||||
"(package version contains invalid characters)\n"));
|
||||
}
|
||||
if(strchr(pkg->version, '/')) {
|
||||
EPKGMETA(_("invalid metadata for package %s-%s "
|
||||
"(package version contains invalid characters)\n"));
|
||||
}
|
||||
|
||||
/* local db entry is <pkgname>-<pkgver> */
|
||||
if(strlen(pkg->name) + strlen(pkg->version) + 1 > NAME_MAX) {
|
||||
EPKGMETA(_("invalid metadata for package %s-%s "
|
||||
"(package name and version too long)\n"));
|
||||
}
|
||||
|
||||
#undef EPKGMETA
|
||||
|
||||
return error_found;
|
||||
}
|
||||
|
||||
@@ -165,4 +165,6 @@ int _alpm_pkg_compare_versions(alpm_pkg_t *local_pkg, alpm_pkg_t *pkg);
|
||||
alpm_pkg_xdata_t *_alpm_pkg_parse_xdata(const char *string);
|
||||
void _alpm_pkg_xdata_free(alpm_pkg_xdata_t *pd);
|
||||
|
||||
int _alpm_pkg_check_meta(alpm_pkg_t *pkg);
|
||||
|
||||
#endif /* ALPM_PACKAGE_H */
|
||||
|
||||
@@ -589,7 +589,7 @@ void cb_progress(void *ctx, alpm_progress_t event, const char *pkgname,
|
||||
} else {
|
||||
if(current != prevcurrent) {
|
||||
/* update always */
|
||||
} else if(!pkgname || percent == prevpercent ||
|
||||
} else if(pkgname[0] == '\0' || percent == prevpercent ||
|
||||
get_update_timediff(0) < UPDATE_SPEED_MS) {
|
||||
/* only update the progress bar when we have a package name, the
|
||||
* percentage has changed, and it has been long enough. */
|
||||
@@ -653,7 +653,7 @@ void cb_progress(void *ctx, alpm_progress_t event, const char *pkgname,
|
||||
* by the output, and then pad it accordingly so we fill the terminal.
|
||||
*/
|
||||
/* len = opr len + pkgname len (if available) + space + null */
|
||||
len = strlen(opr) + ((pkgname) ? strlen(pkgname) : 0) + 2;
|
||||
len = strlen(opr) + strlen(pkgname) + 2;
|
||||
wcstr = calloc(len, sizeof(wchar_t));
|
||||
/* print our strings to the alloc'ed memory */
|
||||
#if defined(HAVE_SWPRINTF)
|
||||
|
||||
@@ -381,7 +381,7 @@ static int parsearg_global(int opt)
|
||||
break;
|
||||
case OP_ASK:
|
||||
config->noask = 1;
|
||||
config->ask = (unsigned int)atoi(optarg);
|
||||
config->ask = (unsigned int)strtol(optarg, NULL, 10);
|
||||
break;
|
||||
case OP_CACHEDIR:
|
||||
config->cachedirs = alpm_list_add(config->cachedirs, strdup(optarg));
|
||||
@@ -409,7 +409,7 @@ static int parsearg_global(int opt)
|
||||
* here, error and warning are set in config_new, though perhaps a
|
||||
* --quiet option will remove these later */
|
||||
if(optarg) {
|
||||
unsigned short debug = (unsigned short)atoi(optarg);
|
||||
int debug = strtol(optarg, NULL, 10);
|
||||
switch(debug) {
|
||||
case 2:
|
||||
config->logmask |= ALPM_LOG_FUNCTION;
|
||||
|
||||
@@ -462,7 +462,7 @@ static size_t string_length(const char *s)
|
||||
int iter = 0;
|
||||
for(; *s; s++) {
|
||||
if(*s == '\033') {
|
||||
while(*s != 'm') {
|
||||
while(*s != 'm' && *s != '\0') {
|
||||
s++;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -97,6 +97,9 @@ pacman_tests = [
|
||||
'tests/pacman003.py',
|
||||
'tests/pacman004.py',
|
||||
'tests/pacman005.py',
|
||||
'tests/pkg-meta-invalid-name-file.py',
|
||||
'tests/pkg-meta-invalid-name-local.py',
|
||||
'tests/pkg-meta-invalid-name-sync.py',
|
||||
'tests/provision001.py',
|
||||
'tests/provision002.py',
|
||||
'tests/provision003.py',
|
||||
|
||||
9
test/pacman/tests/pkg-meta-invalid-name-file.py
Normal file
9
test/pacman/tests/pkg-meta-invalid-name-file.py
Normal file
@@ -0,0 +1,9 @@
|
||||
self.description = "package name with invalid characters cannot be installed (file)"
|
||||
|
||||
p = pmpkg("-foo")
|
||||
self.addpkg(p)
|
||||
|
||||
self.args = "-U -- %s" % p.filename()
|
||||
|
||||
self.addrule("!PACMAN_RETCODE=0")
|
||||
self.addrule("!PKG_EXIST=-foo")
|
||||
9
test/pacman/tests/pkg-meta-invalid-name-local.py
Normal file
9
test/pacman/tests/pkg-meta-invalid-name-local.py
Normal file
@@ -0,0 +1,9 @@
|
||||
self.description = "local package name with invalid characters can be removed"
|
||||
|
||||
sp = pmpkg("-foo")
|
||||
self.addpkg2db("local", sp)
|
||||
|
||||
self.args = "-R -- %s" % sp.name
|
||||
|
||||
self.addrule("PACMAN_RETCODE=0")
|
||||
self.addrule("!PKG_EXIST=-foo")
|
||||
9
test/pacman/tests/pkg-meta-invalid-name-sync.py
Normal file
9
test/pacman/tests/pkg-meta-invalid-name-sync.py
Normal file
@@ -0,0 +1,9 @@
|
||||
self.description = "package name with invalid characters cannot be installed"
|
||||
|
||||
sp = pmpkg("-foo")
|
||||
self.addpkg2db("sync", sp)
|
||||
|
||||
self.args = "-S -- %s" % sp.name
|
||||
|
||||
self.addrule("!PACMAN_RETCODE=0")
|
||||
self.addrule("!PKG_EXIST=-foo")
|
||||
Reference in New Issue
Block a user