Merge "updater: fix memory leak based on static analysis."

am: e50d447692

* commit 'e50d447692764cdb18107965c3ff3476d63b68ec':
  updater: fix memory leak based on static analysis.
This commit is contained in:
Yabin Cui
2016-02-05 02:50:26 +00:00
committed by android-build-merger

View File

@@ -34,6 +34,9 @@
#include <linux/xattr.h> #include <linux/xattr.h>
#include <inttypes.h> #include <inttypes.h>
#include <memory>
#include <vector>
#include <android-base/parseint.h> #include <android-base/parseint.h>
#include <android-base/strings.h> #include <android-base/strings.h>
#include <android-base/stringprintf.h> #include <android-base/stringprintf.h>
@@ -439,8 +442,7 @@ Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) {
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
paths[i] = Evaluate(state, argv[i]); paths[i] = Evaluate(state, argv[i]);
if (paths[i] == NULL) { if (paths[i] == NULL) {
int j; for (int j = 0; j < i; ++j) {
for (j = 0; j < i; ++i) {
free(paths[j]); free(paths[j]);
} }
free(paths); free(paths);
@@ -581,13 +583,13 @@ Value* PackageExtractFileFn(const char* name, State* state,
// as the result. // as the result.
char* zip_path; char* zip_path;
if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL;
Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value))); Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value)));
v->type = VAL_BLOB; v->type = VAL_BLOB;
v->size = -1; v->size = -1;
v->data = NULL; v->data = NULL;
if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL;
ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip; ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip;
const ZipEntry* entry = mzFindZipEntry(za, zip_path); const ZipEntry* entry = mzFindZipEntry(za, zip_path);
if (entry == NULL) { if (entry == NULL) {
@@ -1193,44 +1195,40 @@ Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) {
} }
int patchcount = (argc-4) / 2; int patchcount = (argc-4) / 2;
Value** patches = ReadValueVarArgs(state, argc-4, argv+4); std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc-4, argv+4),
free);
if (!arg_values) {
return nullptr;
}
std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patch_shas;
std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patches;
// Protect values by unique_ptrs first to get rid of memory leak.
for (int i = 0; i < patchcount * 2; i += 2) {
patch_shas.emplace_back(arg_values.get()[i], FreeValue);
patches.emplace_back(arg_values.get()[i+1], FreeValue);
}
int i; for (int i = 0; i < patchcount; ++i) {
for (i = 0; i < patchcount; ++i) { if (patch_shas[i]->type != VAL_STRING) {
if (patches[i*2]->type != VAL_STRING) {
ErrorAbort(state, "%s(): sha-1 #%d is not string", name, i); ErrorAbort(state, "%s(): sha-1 #%d is not string", name, i);
break; return nullptr;
} }
if (patches[i*2+1]->type != VAL_BLOB) { if (patches[i]->type != VAL_BLOB) {
ErrorAbort(state, "%s(): patch #%d is not blob", name, i); ErrorAbort(state, "%s(): patch #%d is not blob", name, i);
break; return nullptr;
} }
} }
if (i != patchcount) {
for (i = 0; i < patchcount*2; ++i) {
FreeValue(patches[i]);
}
free(patches);
return NULL;
}
char** patch_sha_str = reinterpret_cast<char**>(malloc(patchcount * sizeof(char*))); std::vector<char*> patch_sha_str;
for (i = 0; i < patchcount; ++i) { std::vector<Value*> patch_ptrs;
patch_sha_str[i] = patches[i*2]->data; for (int i = 0; i < patchcount; ++i) {
patches[i*2]->data = NULL; patch_sha_str.push_back(patch_shas[i]->data);
FreeValue(patches[i*2]); patch_ptrs.push_back(patches[i].get());
patches[i] = patches[i*2+1];
} }
int result = applypatch(source_filename, target_filename, int result = applypatch(source_filename, target_filename,
target_sha1, target_size, target_sha1, target_size,
patchcount, patch_sha_str, patches, NULL); patchcount, patch_sha_str.data(), patch_ptrs.data(), NULL);
for (i = 0; i < patchcount; ++i) {
FreeValue(patches[i]);
}
free(patch_sha_str);
free(patches);
return StringValue(strdup(result == 0 ? "t" : "")); return StringValue(strdup(result == 0 ? "t" : ""));
} }
@@ -1349,9 +1347,13 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) {
return ErrorAbort(state, "%s() expects at least 1 arg", name); return ErrorAbort(state, "%s() expects at least 1 arg", name);
} }
Value** args = ReadValueVarArgs(state, argc, argv); std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc, argv), free);
if (args == NULL) { if (arg_values == nullptr) {
return NULL; return nullptr;
}
std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> args;
for (int i = 0; i < argc; ++i) {
args.emplace_back(arg_values.get()[i], FreeValue);
} }
if (args[0]->size < 0) { if (args[0]->size < 0) {
@@ -1359,14 +1361,13 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) {
} }
uint8_t digest[SHA_DIGEST_LENGTH]; uint8_t digest[SHA_DIGEST_LENGTH];
SHA1(reinterpret_cast<uint8_t*>(args[0]->data), args[0]->size, digest); SHA1(reinterpret_cast<uint8_t*>(args[0]->data), args[0]->size, digest);
FreeValue(args[0]);
if (argc == 1) { if (argc == 1) {
return StringValue(PrintSha1(digest)); return StringValue(PrintSha1(digest));
} }
int i; int i;
uint8_t* arg_digest = reinterpret_cast<uint8_t*>(malloc(SHA_DIGEST_LENGTH)); uint8_t arg_digest[SHA_DIGEST_LENGTH];
for (i = 1; i < argc; ++i) { for (i = 1; i < argc; ++i) {
if (args[i]->type != VAL_STRING) { if (args[i]->type != VAL_STRING) {
printf("%s(): arg %d is not a string; skipping", printf("%s(): arg %d is not a string; skipping",
@@ -1378,19 +1379,13 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) {
} else if (memcmp(digest, arg_digest, SHA_DIGEST_LENGTH) == 0) { } else if (memcmp(digest, arg_digest, SHA_DIGEST_LENGTH) == 0) {
break; break;
} }
FreeValue(args[i]);
} }
if (i >= argc) { if (i >= argc) {
// Didn't match any of the hex strings; return false. // Didn't match any of the hex strings; return false.
return StringValue(strdup("")); return StringValue(strdup(""));
} }
// Found a match; free all the remaining arguments and return the // Found a match.
// matched one. return args[i].release();
int j;
for (j = i+1; j < argc; ++j) {
FreeValue(args[j]);
}
return args[i];
} }
// Read a local file and return its contents (the Value* returned // Read a local file and return its contents (the Value* returned