int create_pkg_path_in_dir(char path[PKG_PATH_MAX], const dir_rec_t* dir, const char* pkgname, const char* postfix) { const size_t postfix_len = strlen(postfix); const size_t pkgname_len = strlen(pkgname); if (pkgname_len > PKG_NAME_MAX) { return -1; } if (is_valid_package_name(pkgname) < 0) { return -1; } if ((pkgname_len + dir->len + postfix_len) >= PKG_PATH_MAX) { return -1; } char *dst = path; size_t dst_size = PKG_PATH_MAX; if (append_and_increment(&dst, dir->path, &dst_size) < 0 || append_and_increment(&dst, pkgname, &dst_size) < 0 || append_and_increment(&dst, postfix, &dst_size) < 0) { ALOGE("Error building APK path"); return -1; } return 0; }
/** * Create the path name for user data for a certain persona. * Returns 0 on success, and -1 on failure. */ int create_persona_path(char path[PKG_PATH_MAX], uid_t persona) { size_t uid_len; char* persona_prefix; if (persona == 0) { persona_prefix = PRIMARY_USER_PREFIX; uid_len = 0; } else { persona_prefix = SECONDARY_USER_PREFIX; uid_len = snprintf(NULL, 0, "%d/", persona); } char *dst = path; size_t dst_size = PKG_PATH_MAX; if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 || append_and_increment(&dst, persona_prefix, &dst_size) < 0) { ALOGE("Error building prefix for user path"); return -1; } if (persona != 0) { if (dst_size < uid_len + 1) { ALOGE("Error building user path"); return -1; } int ret = snprintf(dst, dst_size, "%d/", persona); if (ret < 0 || (size_t) ret != uid_len) { ALOGE("Error appending persona id to path"); return -1; } } return 0; }
TEST_F(UtilsTest, AppendAndIncrement_TooBig) { size_t dst_size = 5; char dst[dst_size]; char *dstp = dst; const char* src = "FOO"; EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) << "String should append successfully"; EXPECT_STREQ("FOO", dst) << "String should append correctly"; EXPECT_EQ(-1, append_and_increment(&dstp, src, &dst_size)) << "String should fail because it's too large to fit"; }
/** * Puts the string into the record as a directory. Appends '/' to the end * of all paths. Caller owns the string that is inserted into the directory * record. A null value will result in an error. * * Returns 0 on success and -1 on error. */ int get_path_from_string(dir_rec_t* rec, const char* path) { if (path == NULL) { return -1; } else { const size_t path_len = strlen(path); if (path_len <= 0) { return -1; } // Make sure path is absolute. if (path[0] != '/') { return -1; } if (path[path_len - 1] == '/') { // Path ends with a forward slash. Make our own copy. rec->path = strdup(path); if (rec->path == NULL) { return -1; } rec->len = path_len; } else { // Path does not end with a slash. Generate a new string. char *dst; // Add space for slash and terminating null. size_t dst_size = path_len + 2; rec->path = malloc(dst_size); if (rec->path == NULL) { return -1; } dst = rec->path; if (append_and_increment(&dst, path, &dst_size) < 0 || append_and_increment(&dst, "/", &dst_size)) { LOGE("Error canonicalizing path"); return -1; } rec->len = dst - rec->path; } } return 0; }
TEST_F(UtilsTest, AppendAndIncrement_Normal) { size_t dst_size = 10; char dst[dst_size]; char *dstp = dst; const char* src = "FOO"; EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) << "String should append successfully"; EXPECT_STREQ("FOO", dst) << "String should append correctly"; EXPECT_EQ(0, append_and_increment(&dstp, src, &dst_size)) << "String should append successfully again"; EXPECT_STREQ("FOOFOO", dst) << "String should append correctly again"; }
/** * Create the package path name for a given package name with a postfix for * a certain userid. Returns 0 on success, and -1 on failure. */ int create_pkg_path(char path[PKG_PATH_MAX], const char *pkgname, const char *postfix, userid_t userid) { size_t userid_len; char* userid_prefix; if (userid == 0) { userid_prefix = PRIMARY_USER_PREFIX; userid_len = 0; } else { userid_prefix = SECONDARY_USER_PREFIX; userid_len = snprintf(NULL, 0, "%d", userid); } const size_t prefix_len = android_data_dir.len + strlen(userid_prefix) + userid_len + 1 /*slash*/; char prefix[prefix_len + 1]; char *dst = prefix; size_t dst_size = sizeof(prefix); if (append_and_increment(&dst, android_data_dir.path, &dst_size) < 0 || append_and_increment(&dst, userid_prefix, &dst_size) < 0) { ALOGE("Error building prefix for APK path"); return -1; } if (userid != 0) { int ret = snprintf(dst, dst_size, "%d/", userid); if (ret < 0 || (size_t) ret != userid_len + 1) { ALOGW("Error appending UID to APK path"); return -1; } } dir_rec_t dir; dir.path = prefix; dir.len = prefix_len; return create_pkg_path_in_dir(path, &dir, pkgname, postfix); }