Loading cmds/installd/tests/installd_utils_test.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) { size_t pkgnameSize = PKG_NAME_MAX; char pkgname[pkgnameSize + 1]; memset(pkgname, 'a', pkgnameSize); pkgname[1] = '.'; pkgname[pkgnameSize] = '\0'; EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0)) Loading Loading @@ -512,5 +513,22 @@ TEST_F(UtilsTest, CreateDataUserPackagePath) { create_data_user_ce_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10, "com.example")); } TEST_F(UtilsTest, IsValidPackageName) { EXPECT_EQ(true, is_valid_package_name("com.example")); EXPECT_EQ(true, is_valid_package_name("com.example-1")); EXPECT_EQ(true, is_valid_package_name("com.example-1024")); EXPECT_EQ(true, is_valid_package_name("com.example.foo---KiJFj4a_tePVw95pSrjg==")); EXPECT_EQ(true, is_valid_package_name("really_LONG.a1234.package_name")); EXPECT_EQ(false, is_valid_package_name("1234.package")); EXPECT_EQ(false, is_valid_package_name("com.1234.package")); EXPECT_EQ(false, is_valid_package_name("package")); EXPECT_EQ(false, is_valid_package_name("")); EXPECT_EQ(false, is_valid_package_name(".")); EXPECT_EQ(false, is_valid_package_name("com.example/../com.evil/")); EXPECT_EQ(false, is_valid_package_name("com.example-1/../com.evil/")); EXPECT_EQ(false, is_valid_package_name("/com.evil")); } } // namespace installd } // namespace android cmds/installd/utils.cpp +31 −35 Original line number Diff line number Diff line Loading @@ -350,47 +350,43 @@ int create_move_path(char path[PKG_PATH_MAX], * 0 on success. */ bool is_valid_package_name(const std::string& packageName) { const char* pkgname = packageName.c_str(); const char *x = pkgname; int alpha = -1; if (strlen(pkgname) > PKG_NAME_MAX) { return false; // This logic is borrowed from PackageParser.java bool hasSep = false; bool front = true; auto it = packageName.begin(); for (; it != packageName.end() && *it != '-'; it++) { char c = *it; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { front = false; continue; } while (*x) { if (isalnum(*x) || (*x == '_')) { /* alphanumeric or underscore are fine */ } else if (*x == '.') { if ((x == pkgname) || (x[1] == '.') || (x[1] == 0)) { /* periods must not be first, last, or doubled */ ALOGE("invalid package name '%s'\n", pkgname); return false; if (!front) { if ((c >= '0' && c <= '9') || c == '_') { continue; } } else if (*x == '-') { /* Suffix -X is fine to let versioning of packages. But whatever follows should be alphanumeric.*/ alpha = 1; } else { /* anything not A-Z, a-z, 0-9, _, or . is invalid */ ALOGE("invalid package name '%s'\n", pkgname); } if (c == '.') { hasSep = true; front = true; continue; } LOG(WARNING) << "Bad package character " << c << " in " << packageName; return false; } x++; if (!hasSep || front) { LOG(WARNING) << "Missing separator in " << packageName; return false; } if (alpha == 1) { // Skip current character x++; while (*x) { if (!isalnum(*x)) { ALOGE("invalid package name '%s' should include only numbers after -\n", pkgname); for (; it != packageName.end(); it++) { char c = *it; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) continue; if ((c >= '0' && c <= '9') || c == '_' || c == '-' || c == '=') continue; LOG(WARNING) << "Bad suffix character " << c << " in " << packageName; return false; } x++; } } return true; } Loading Loading
cmds/installd/tests/installd_utils_test.cpp +18 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ TEST_F(UtilsTest, CreatePkgPath_LongPkgNameSuccess) { size_t pkgnameSize = PKG_NAME_MAX; char pkgname[pkgnameSize + 1]; memset(pkgname, 'a', pkgnameSize); pkgname[1] = '.'; pkgname[pkgnameSize] = '\0'; EXPECT_EQ(0, create_pkg_path(path, pkgname, "", 0)) Loading Loading @@ -512,5 +513,22 @@ TEST_F(UtilsTest, CreateDataUserPackagePath) { create_data_user_ce_package_path("57f8f4bc-abf4-655f-bf67-946fc0f9f25b", 10, "com.example")); } TEST_F(UtilsTest, IsValidPackageName) { EXPECT_EQ(true, is_valid_package_name("com.example")); EXPECT_EQ(true, is_valid_package_name("com.example-1")); EXPECT_EQ(true, is_valid_package_name("com.example-1024")); EXPECT_EQ(true, is_valid_package_name("com.example.foo---KiJFj4a_tePVw95pSrjg==")); EXPECT_EQ(true, is_valid_package_name("really_LONG.a1234.package_name")); EXPECT_EQ(false, is_valid_package_name("1234.package")); EXPECT_EQ(false, is_valid_package_name("com.1234.package")); EXPECT_EQ(false, is_valid_package_name("package")); EXPECT_EQ(false, is_valid_package_name("")); EXPECT_EQ(false, is_valid_package_name(".")); EXPECT_EQ(false, is_valid_package_name("com.example/../com.evil/")); EXPECT_EQ(false, is_valid_package_name("com.example-1/../com.evil/")); EXPECT_EQ(false, is_valid_package_name("/com.evil")); } } // namespace installd } // namespace android
cmds/installd/utils.cpp +31 −35 Original line number Diff line number Diff line Loading @@ -350,47 +350,43 @@ int create_move_path(char path[PKG_PATH_MAX], * 0 on success. */ bool is_valid_package_name(const std::string& packageName) { const char* pkgname = packageName.c_str(); const char *x = pkgname; int alpha = -1; if (strlen(pkgname) > PKG_NAME_MAX) { return false; // This logic is borrowed from PackageParser.java bool hasSep = false; bool front = true; auto it = packageName.begin(); for (; it != packageName.end() && *it != '-'; it++) { char c = *it; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { front = false; continue; } while (*x) { if (isalnum(*x) || (*x == '_')) { /* alphanumeric or underscore are fine */ } else if (*x == '.') { if ((x == pkgname) || (x[1] == '.') || (x[1] == 0)) { /* periods must not be first, last, or doubled */ ALOGE("invalid package name '%s'\n", pkgname); return false; if (!front) { if ((c >= '0' && c <= '9') || c == '_') { continue; } } else if (*x == '-') { /* Suffix -X is fine to let versioning of packages. But whatever follows should be alphanumeric.*/ alpha = 1; } else { /* anything not A-Z, a-z, 0-9, _, or . is invalid */ ALOGE("invalid package name '%s'\n", pkgname); } if (c == '.') { hasSep = true; front = true; continue; } LOG(WARNING) << "Bad package character " << c << " in " << packageName; return false; } x++; if (!hasSep || front) { LOG(WARNING) << "Missing separator in " << packageName; return false; } if (alpha == 1) { // Skip current character x++; while (*x) { if (!isalnum(*x)) { ALOGE("invalid package name '%s' should include only numbers after -\n", pkgname); for (; it != packageName.end(); it++) { char c = *it; if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) continue; if ((c >= '0' && c <= '9') || c == '_' || c == '-' || c == '=') continue; LOG(WARNING) << "Bad suffix character " << c << " in " << packageName; return false; } x++; } } return true; } Loading