diff --git a/NEWS b/NEWS index dabdb4bf..715c1095 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ xbps-0.42 (???): + * Fixed issue #68 "xbps_binpkg_arch() asserts if arch contains a dash" + https://github.com/voidlinux/xbps/issues/68 + * xbps-query(8): added --cat=FILE mode to print FILE stored in a binary package to stdout. This works exactly as the --files mode: if the matching binary package is not available in the cachedir, xbps will establish a network connection diff --git a/lib/util.c b/lib/util.c index 60803557..ad11524c 100644 --- a/lib/util.c +++ b/lib/util.c @@ -107,9 +107,8 @@ char * xbps_binpkg_pkgver(const char *pkg) { const char *fname; - char *p, *res; - unsigned int i, idx = 0; - bool valid = false; + char *p, *p1; + unsigned int len; /* skip path if found, only interested in filename */ if ((fname = strrchr(pkg, '/'))) @@ -117,60 +116,30 @@ xbps_binpkg_pkgver(const char *pkg) else fname = pkg; - /* get the version component first */ - if ((p = strrchr(fname, '-')) == NULL) - return NULL; + /* 5 == .xbps */ + len = strlen(fname) - 5; + p = malloc(len+1); + assert(p); + (void)memcpy(p, fname, len); + p[len] = '\0'; + p1 = strrchr(p, '.'); + assert(p1); + p[strlen(p)-strlen(p1)] = '\0'; - for (i = 0; i < strlen(p); i++) { - if (p[i] == '_') - break; - if (isdigit((unsigned char)p[i]) && strchr(p, '_')) { - valid = true; - break; - } + /* sanity check it's a proper pkgver string */ + if (xbps_pkg_version(p) == NULL) { + free(p); + return NULL; } - if (!valid) - return NULL; - - /* - * find the index until the architecture component: - * this assumes that revision contains 1 or 2 digits! - */ - for (i = 0; i < strlen(fname); i++) { - /* revision with 1 digit: _[digit]. */ - if (fname[i] == '_' && - isdigit((unsigned char)fname[i+1]) && - fname[i+2] == '.') { - idx = i+2; - break; - } - /* revision with 2 digits: _[digit][digit]. */ - if (fname[i] == '_' && - isdigit((unsigned char)fname[i+1]) && - isdigit((unsigned char)fname[i+2]) && - fname[i+3] == '.') { - idx = i+3; - break; - } - } - if (!idx) - return NULL; - - res = strdup(fname); - assert(res); - res[idx] = '\0'; - - return res; + return p; } char * xbps_binpkg_arch(const char *pkg) { - const char *p, *fname; - char *pkgver, *res; - - if ((pkgver = xbps_binpkg_pkgver(pkg)) == NULL) - return NULL; + const char *fname; + char *p; + unsigned int len; /* skip path if found, only interested in filename */ if ((fname = strrchr(pkg, '/'))) @@ -178,17 +147,14 @@ xbps_binpkg_arch(const char *pkg) else fname = pkg; - p = fname + strlen(pkgver); + /* 5 == .xbps */ + len = strlen(fname) - 5; + p = malloc(len+1); assert(p); - if (*p == '.') - p++; + (void)memcpy(p, fname, len); + p[len] = '\0'; - res = strdup(p); - assert(res); - free(pkgver); - res[strlen(res)-5] = '\0'; - - return res; + return strrchr(p, '.') + 1; } const char * diff --git a/tests/xbps/libxbps/util/main.c b/tests/xbps/libxbps/util/main.c index 2bbf00ab..9ae88f1c 100644 --- a/tests/xbps/libxbps/util/main.c +++ b/tests/xbps/libxbps/util/main.c @@ -65,6 +65,16 @@ ATF_TC_BODY(util_test, tc) ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd>4[3-9]?"), "systemd"); ATF_REQUIRE_STREQ(xbps_pkgpattern_name("systemd<4_1?"), "systemd"); ATF_CHECK_EQ(xbps_pkgpattern_name("*nslookup"), NULL); + ATF_REQUIRE_STREQ(xbps_binpkg_arch("/path/to/foo-1.0_1.x86_64.xbps"), "x86_64"); + ATF_REQUIRE_STREQ(xbps_binpkg_arch("/path/to/foo-1.0_1.x86_64-musl.xbps"), "x86_64-musl"); + ATF_REQUIRE_STREQ(xbps_binpkg_arch("foo-1.0_1.x86_64-musl.xbps"), "x86_64-musl"); + ATF_REQUIRE_STREQ(xbps_binpkg_arch("foo-1.0_1.x86_64.xbps"), "x86_64"); + ATF_REQUIRE_STREQ(xbps_binpkg_pkgver("foo-1.0_1.x86_64.xbps"), "foo-1.0_1"); + ATF_REQUIRE_STREQ(xbps_binpkg_pkgver("foo-1.0_1.x86_64-musl.xbps"), "foo-1.0_1"); + ATF_REQUIRE_STREQ(xbps_binpkg_pkgver("/path/to/foo-1.0_1.x86_64.xbps"), "foo-1.0_1"); + ATF_REQUIRE_STREQ(xbps_binpkg_pkgver("/path/to/foo-1.0_1.x86_64-musl.xbps"), "foo-1.0_1"); + ATF_CHECK_EQ(xbps_binpkg_pkgver("foo-1.0.x86_64.xbps"), NULL); + ATF_CHECK_EQ(xbps_binpkg_pkgver("foo-1.0.x86_64"), NULL); } ATF_TP_ADD_TCS(tp)