diff options
author | Tianjie Xu | 2016-10-12 12:55:04 -0500 |
---|---|---|
committer | Tianjie Xu | 2016-10-14 20:18:23 -0500 |
commit | aced5d9e4e438ba478ce54f9217166b8ab7cc24f (patch) | |
tree | b3bfca3430c25b7c35501497e0b8a0faf2251538 | |
parent | c5b4b719134a1d2d3b06a81f92a00b24e527248d (diff) | |
download | platform-bootable-recovery-aced5d9e4e438ba478ce54f9217166b8ab7cc24f.tar.gz platform-bootable-recovery-aced5d9e4e438ba478ce54f9217166b8ab7cc24f.tar.xz platform-bootable-recovery-aced5d9e4e438ba478ce54f9217166b8ab7cc24f.zip |
Change StringValue to use std::string
Changing the field of 'Value' in edify to std::string from char*.
Meanwhile cleaning up the users of 'Value' and switching them to
cpp style.
Test: compontent tests passed.
Bug: 31713288
Change-Id: Iec5a7d601b1e4ca40935bf1c70d325dafecec235
-rw-r--r-- | applypatch/applypatch.cpp | 28 | ||||
-rw-r--r-- | applypatch/bspatch.cpp | 12 | ||||
-rw-r--r-- | applypatch/imgpatch.cpp | 44 | ||||
-rw-r--r-- | applypatch/include/applypatch/applypatch.h | 10 | ||||
-rw-r--r-- | applypatch/main.cpp | 42 | ||||
-rw-r--r-- | applypatch/utils.cpp | 12 | ||||
-rw-r--r-- | applypatch/utils.h | 6 | ||||
-rw-r--r-- | edify/edify_parser.cpp | 6 | ||||
-rw-r--r-- | edify/expr.cpp | 328 | ||||
-rw-r--r-- | edify/expr.h | 44 | ||||
-rw-r--r-- | tests/component/applypatch_test.cpp | 132 | ||||
-rw-r--r-- | tests/component/edify_test.cpp | 8 | ||||
-rw-r--r-- | tests/component/updater_test.cpp | 8 | ||||
-rw-r--r-- | updater/blockimg.cpp | 154 | ||||
-rw-r--r-- | updater/install.cpp | 191 | ||||
-rw-r--r-- | updater/updater.cpp | 8 |
16 files changed, 505 insertions, 528 deletions
diff --git a/applypatch/applypatch.cpp b/applypatch/applypatch.cpp index e52ef99d..cf155607 100644 --- a/applypatch/applypatch.cpp +++ b/applypatch/applypatch.cpp | |||
@@ -408,11 +408,10 @@ int ParseSha1(const char* str, uint8_t* digest) { | |||
408 | // Search an array of sha1 strings for one matching the given sha1. | 408 | // Search an array of sha1 strings for one matching the given sha1. |
409 | // Return the index of the match on success, or -1 if no match is | 409 | // Return the index of the match on success, or -1 if no match is |
410 | // found. | 410 | // found. |
411 | int FindMatchingPatch(uint8_t* sha1, char* const * const patch_sha1_str, | 411 | int FindMatchingPatch(uint8_t* sha1, const std::vector<std::string>& patch_sha1_str) { |
412 | int num_patches) { | 412 | for (size_t i = 0; i < patch_sha1_str.size(); ++i) { |
413 | uint8_t patch_sha1[SHA_DIGEST_LENGTH]; | 413 | uint8_t patch_sha1[SHA_DIGEST_LENGTH]; |
414 | for (int i = 0; i < num_patches; ++i) { | 414 | if (ParseSha1(patch_sha1_str[i].c_str(), patch_sha1) == 0 && |
415 | if (ParseSha1(patch_sha1_str[i], patch_sha1) == 0 && | ||
416 | memcmp(patch_sha1, sha1, SHA_DIGEST_LENGTH) == 0) { | 415 | memcmp(patch_sha1, sha1, SHA_DIGEST_LENGTH) == 0) { |
417 | return i; | 416 | return i; |
418 | } | 417 | } |
@@ -423,8 +422,7 @@ int FindMatchingPatch(uint8_t* sha1, char* const * const patch_sha1_str, | |||
423 | // Returns 0 if the contents of the file (argv[2]) or the cached file | 422 | // Returns 0 if the contents of the file (argv[2]) or the cached file |
424 | // match any of the sha1's on the command line (argv[3:]). Returns | 423 | // match any of the sha1's on the command line (argv[3:]). Returns |
425 | // nonzero otherwise. | 424 | // nonzero otherwise. |
426 | int applypatch_check(const char* filename, int num_patches, | 425 | int applypatch_check(const char* filename, const std::vector<std::string>& patch_sha1_str) { |
427 | char** const patch_sha1_str) { | ||
428 | FileContents file; | 426 | FileContents file; |
429 | 427 | ||
430 | // It's okay to specify no sha1s; the check will pass if the | 428 | // It's okay to specify no sha1s; the check will pass if the |
@@ -432,8 +430,7 @@ int applypatch_check(const char* filename, int num_patches, | |||
432 | // partitions, where the filename encodes the sha1s; no need to | 430 | // partitions, where the filename encodes the sha1s; no need to |
433 | // check them twice.) | 431 | // check them twice.) |
434 | if (LoadFileContents(filename, &file) != 0 || | 432 | if (LoadFileContents(filename, &file) != 0 || |
435 | (num_patches > 0 && | 433 | FindMatchingPatch(file.sha1, patch_sha1_str) < 0) { |
436 | FindMatchingPatch(file.sha1, patch_sha1_str, num_patches) < 0)) { | ||
437 | printf("file \"%s\" doesn't have any of expected " | 434 | printf("file \"%s\" doesn't have any of expected " |
438 | "sha1 sums; checking cache\n", filename); | 435 | "sha1 sums; checking cache\n", filename); |
439 | 436 | ||
@@ -448,7 +445,7 @@ int applypatch_check(const char* filename, int num_patches, | |||
448 | return 1; | 445 | return 1; |
449 | } | 446 | } |
450 | 447 | ||
451 | if (FindMatchingPatch(file.sha1, patch_sha1_str, num_patches) < 0) { | 448 | if (FindMatchingPatch(file.sha1, patch_sha1_str) < 0) { |
452 | printf("cache bits don't match any sha1 for \"%s\"\n", filename); | 449 | printf("cache bits don't match any sha1 for \"%s\"\n", filename); |
453 | return 1; | 450 | return 1; |
454 | } | 451 | } |
@@ -532,8 +529,7 @@ int applypatch(const char* source_filename, | |||
532 | const char* target_filename, | 529 | const char* target_filename, |
533 | const char* target_sha1_str, | 530 | const char* target_sha1_str, |
534 | size_t target_size, | 531 | size_t target_size, |
535 | int num_patches, | 532 | const std::vector<std::string>& patch_sha1_str, |
536 | char** const patch_sha1_str, | ||
537 | Value** patch_data, | 533 | Value** patch_data, |
538 | Value* bonus_data) { | 534 | Value* bonus_data) { |
539 | printf("patch %s: ", source_filename); | 535 | printf("patch %s: ", source_filename); |
@@ -573,7 +569,7 @@ int applypatch(const char* source_filename, | |||
573 | } | 569 | } |
574 | 570 | ||
575 | if (!source_file.data.empty()) { | 571 | if (!source_file.data.empty()) { |
576 | int to_use = FindMatchingPatch(source_file.sha1, patch_sha1_str, num_patches); | 572 | int to_use = FindMatchingPatch(source_file.sha1, patch_sha1_str); |
577 | if (to_use >= 0) { | 573 | if (to_use >= 0) { |
578 | source_patch_value = patch_data[to_use]; | 574 | source_patch_value = patch_data[to_use]; |
579 | } | 575 | } |
@@ -589,7 +585,7 @@ int applypatch(const char* source_filename, | |||
589 | return 1; | 585 | return 1; |
590 | } | 586 | } |
591 | 587 | ||
592 | int to_use = FindMatchingPatch(copy_file.sha1, patch_sha1_str, num_patches); | 588 | int to_use = FindMatchingPatch(copy_file.sha1, patch_sha1_str); |
593 | if (to_use >= 0) { | 589 | if (to_use >= 0) { |
594 | copy_patch_value = patch_data[to_use]; | 590 | copy_patch_value = patch_data[to_use]; |
595 | } | 591 | } |
@@ -701,8 +697,8 @@ static int GenerateTarget(FileContents* source_file, | |||
701 | printf("patch is not a blob\n"); | 697 | printf("patch is not a blob\n"); |
702 | return 1; | 698 | return 1; |
703 | } | 699 | } |
704 | char* header = patch->data; | 700 | const char* header = &patch->data[0]; |
705 | ssize_t header_bytes_read = patch->size; | 701 | size_t header_bytes_read = patch->data.size(); |
706 | bool use_bsdiff = false; | 702 | bool use_bsdiff = false; |
707 | if (header_bytes_read >= 8 && memcmp(header, "BSDIFF40", 8) == 0) { | 703 | if (header_bytes_read >= 8 && memcmp(header, "BSDIFF40", 8) == 0) { |
708 | use_bsdiff = true; | 704 | use_bsdiff = true; |
diff --git a/applypatch/bspatch.cpp b/applypatch/bspatch.cpp index a4945da2..eb45e9ce 100644 --- a/applypatch/bspatch.cpp +++ b/applypatch/bspatch.cpp | |||
@@ -64,7 +64,7 @@ void ShowBSDiffLicense() { | |||
64 | ); | 64 | ); |
65 | } | 65 | } |
66 | 66 | ||
67 | static off_t offtin(u_char *buf) | 67 | static off_t offtin(const u_char *buf) |
68 | { | 68 | { |
69 | off_t y; | 69 | off_t y; |
70 | 70 | ||
@@ -130,7 +130,7 @@ int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size, | |||
130 | // from oldfile to x bytes from the diff block; copy y bytes from the | 130 | // from oldfile to x bytes from the diff block; copy y bytes from the |
131 | // extra block; seek forwards in oldfile by z bytes". | 131 | // extra block; seek forwards in oldfile by z bytes". |
132 | 132 | ||
133 | unsigned char* header = (unsigned char*) patch->data + patch_offset; | 133 | const unsigned char* header = reinterpret_cast<const unsigned char*>(&patch->data[patch_offset]); |
134 | if (memcmp(header, "BSDIFF40", 8) != 0) { | 134 | if (memcmp(header, "BSDIFF40", 8) != 0) { |
135 | printf("corrupt bsdiff patch file header (magic number)\n"); | 135 | printf("corrupt bsdiff patch file header (magic number)\n"); |
136 | return 1; | 136 | return 1; |
@@ -149,7 +149,7 @@ int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size, | |||
149 | int bzerr; | 149 | int bzerr; |
150 | 150 | ||
151 | bz_stream cstream; | 151 | bz_stream cstream; |
152 | cstream.next_in = patch->data + patch_offset + 32; | 152 | cstream.next_in = const_cast<char*>(&patch->data[patch_offset + 32]); |
153 | cstream.avail_in = ctrl_len; | 153 | cstream.avail_in = ctrl_len; |
154 | cstream.bzalloc = NULL; | 154 | cstream.bzalloc = NULL; |
155 | cstream.bzfree = NULL; | 155 | cstream.bzfree = NULL; |
@@ -159,7 +159,7 @@ int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size, | |||
159 | } | 159 | } |
160 | 160 | ||
161 | bz_stream dstream; | 161 | bz_stream dstream; |
162 | dstream.next_in = patch->data + patch_offset + 32 + ctrl_len; | 162 | dstream.next_in = const_cast<char*>(&patch->data[patch_offset + 32 + ctrl_len]); |
163 | dstream.avail_in = data_len; | 163 | dstream.avail_in = data_len; |
164 | dstream.bzalloc = NULL; | 164 | dstream.bzalloc = NULL; |
165 | dstream.bzfree = NULL; | 165 | dstream.bzfree = NULL; |
@@ -169,8 +169,8 @@ int ApplyBSDiffPatchMem(const unsigned char* old_data, ssize_t old_size, | |||
169 | } | 169 | } |
170 | 170 | ||
171 | bz_stream estream; | 171 | bz_stream estream; |
172 | estream.next_in = patch->data + patch_offset + 32 + ctrl_len + data_len; | 172 | estream.next_in = const_cast<char*>(&patch->data[patch_offset + 32 + ctrl_len + data_len]); |
173 | estream.avail_in = patch->size - (patch_offset + 32 + ctrl_len + data_len); | 173 | estream.avail_in = patch->data.size() - (patch_offset + 32 + ctrl_len + data_len); |
174 | estream.bzalloc = NULL; | 174 | estream.bzalloc = NULL; |
175 | estream.bzfree = NULL; | 175 | estream.bzfree = NULL; |
176 | estream.opaque = NULL; | 176 | estream.opaque = NULL; |
diff --git a/applypatch/imgpatch.cpp b/applypatch/imgpatch.cpp index 0c06d6b1..1c4409e3 100644 --- a/applypatch/imgpatch.cpp +++ b/applypatch/imgpatch.cpp | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | #include <string.h> | 25 | #include <string.h> |
26 | 26 | ||
27 | #include <string> | ||
27 | #include <vector> | 28 | #include <vector> |
28 | 29 | ||
29 | #include "zlib.h" | 30 | #include "zlib.h" |
@@ -35,10 +36,10 @@ | |||
35 | int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | 36 | int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, |
36 | const unsigned char* patch_data, ssize_t patch_size, | 37 | const unsigned char* patch_data, ssize_t patch_size, |
37 | SinkFn sink, void* token) { | 38 | SinkFn sink, void* token) { |
38 | Value patch = {VAL_BLOB, patch_size, | 39 | Value patch(VAL_BLOB, std::string( |
39 | reinterpret_cast<char*>(const_cast<unsigned char*>(patch_data))}; | 40 | reinterpret_cast<const char*>(patch_data), patch_size)); |
40 | return ApplyImagePatch( | 41 | |
41 | old_data, old_size, &patch, sink, token, nullptr, nullptr); | 42 | return ApplyImagePatch(old_data, old_size, &patch, sink, token, nullptr, nullptr); |
42 | } | 43 | } |
43 | 44 | ||
44 | /* | 45 | /* |
@@ -51,9 +52,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | |||
51 | const Value* patch, | 52 | const Value* patch, |
52 | SinkFn sink, void* token, SHA_CTX* ctx, | 53 | SinkFn sink, void* token, SHA_CTX* ctx, |
53 | const Value* bonus_data) { | 54 | const Value* bonus_data) { |
54 | ssize_t pos = 12; | 55 | if (patch->data.size() < 12) { |
55 | char* header = patch->data; | ||
56 | if (patch->size < 12) { | ||
57 | printf("patch too short to contain header\n"); | 56 | printf("patch too short to contain header\n"); |
58 | return -1; | 57 | return -1; |
59 | } | 58 | } |
@@ -61,6 +60,8 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | |||
61 | // IMGDIFF2 uses CHUNK_NORMAL, CHUNK_DEFLATE, and CHUNK_RAW. | 60 | // IMGDIFF2 uses CHUNK_NORMAL, CHUNK_DEFLATE, and CHUNK_RAW. |
62 | // (IMGDIFF1, which is no longer supported, used CHUNK_NORMAL and | 61 | // (IMGDIFF1, which is no longer supported, used CHUNK_NORMAL and |
63 | // CHUNK_GZIP.) | 62 | // CHUNK_GZIP.) |
63 | size_t pos = 12; | ||
64 | const char* header = &patch->data[0]; | ||
64 | if (memcmp(header, "IMGDIFF2", 8) != 0) { | 65 | if (memcmp(header, "IMGDIFF2", 8) != 0) { |
65 | printf("corrupt patch file header (magic number)\n"); | 66 | printf("corrupt patch file header (magic number)\n"); |
66 | return -1; | 67 | return -1; |
@@ -68,20 +69,19 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | |||
68 | 69 | ||
69 | int num_chunks = Read4(header+8); | 70 | int num_chunks = Read4(header+8); |
70 | 71 | ||
71 | int i; | 72 | for (int i = 0; i < num_chunks; ++i) { |
72 | for (i = 0; i < num_chunks; ++i) { | ||
73 | // each chunk's header record starts with 4 bytes. | 73 | // each chunk's header record starts with 4 bytes. |
74 | if (pos + 4 > patch->size) { | 74 | if (pos + 4 > patch->data.size()) { |
75 | printf("failed to read chunk %d record\n", i); | 75 | printf("failed to read chunk %d record\n", i); |
76 | return -1; | 76 | return -1; |
77 | } | 77 | } |
78 | int type = Read4(patch->data + pos); | 78 | int type = Read4(&patch->data[pos]); |
79 | pos += 4; | 79 | pos += 4; |
80 | 80 | ||
81 | if (type == CHUNK_NORMAL) { | 81 | if (type == CHUNK_NORMAL) { |
82 | char* normal_header = patch->data + pos; | 82 | const char* normal_header = &patch->data[pos]; |
83 | pos += 24; | 83 | pos += 24; |
84 | if (pos > patch->size) { | 84 | if (pos > patch->data.size()) { |
85 | printf("failed to read chunk %d normal header data\n", i); | 85 | printf("failed to read chunk %d normal header data\n", i); |
86 | return -1; | 86 | return -1; |
87 | } | 87 | } |
@@ -97,21 +97,21 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | |||
97 | ApplyBSDiffPatch(old_data + src_start, src_len, | 97 | ApplyBSDiffPatch(old_data + src_start, src_len, |
98 | patch, patch_offset, sink, token, ctx); | 98 | patch, patch_offset, sink, token, ctx); |
99 | } else if (type == CHUNK_RAW) { | 99 | } else if (type == CHUNK_RAW) { |
100 | char* raw_header = patch->data + pos; | 100 | const char* raw_header = &patch->data[pos]; |
101 | pos += 4; | 101 | pos += 4; |
102 | if (pos > patch->size) { | 102 | if (pos > patch->data.size()) { |
103 | printf("failed to read chunk %d raw header data\n", i); | 103 | printf("failed to read chunk %d raw header data\n", i); |
104 | return -1; | 104 | return -1; |
105 | } | 105 | } |
106 | 106 | ||
107 | ssize_t data_len = Read4(raw_header); | 107 | ssize_t data_len = Read4(raw_header); |
108 | 108 | ||
109 | if (pos + data_len > patch->size) { | 109 | if (pos + data_len > patch->data.size()) { |
110 | printf("failed to read chunk %d raw data\n", i); | 110 | printf("failed to read chunk %d raw data\n", i); |
111 | return -1; | 111 | return -1; |
112 | } | 112 | } |
113 | if (ctx) SHA1_Update(ctx, patch->data + pos, data_len); | 113 | if (ctx) SHA1_Update(ctx, &patch->data[pos], data_len); |
114 | if (sink((unsigned char*)patch->data + pos, | 114 | if (sink(reinterpret_cast<const unsigned char*>(&patch->data[pos]), |
115 | data_len, token) != data_len) { | 115 | data_len, token) != data_len) { |
116 | printf("failed to write chunk %d raw data\n", i); | 116 | printf("failed to write chunk %d raw data\n", i); |
117 | return -1; | 117 | return -1; |
@@ -119,9 +119,9 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | |||
119 | pos += data_len; | 119 | pos += data_len; |
120 | } else if (type == CHUNK_DEFLATE) { | 120 | } else if (type == CHUNK_DEFLATE) { |
121 | // deflate chunks have an additional 60 bytes in their chunk header. | 121 | // deflate chunks have an additional 60 bytes in their chunk header. |
122 | char* deflate_header = patch->data + pos; | 122 | const char* deflate_header = &patch->data[pos]; |
123 | pos += 60; | 123 | pos += 60; |
124 | if (pos > patch->size) { | 124 | if (pos > patch->data.size()) { |
125 | printf("failed to read chunk %d deflate header data\n", i); | 125 | printf("failed to read chunk %d deflate header data\n", i); |
126 | return -1; | 126 | return -1; |
127 | } | 127 | } |
@@ -149,7 +149,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | |||
149 | // the patch was constructed with bonus data. The | 149 | // the patch was constructed with bonus data. The |
150 | // deflation will come up 'bonus_size' bytes short; these | 150 | // deflation will come up 'bonus_size' bytes short; these |
151 | // must be appended from the bonus_data value. | 151 | // must be appended from the bonus_data value. |
152 | size_t bonus_size = (i == 1 && bonus_data != NULL) ? bonus_data->size : 0; | 152 | size_t bonus_size = (i == 1 && bonus_data != NULL) ? bonus_data->data.size() : 0; |
153 | 153 | ||
154 | std::vector<unsigned char> expanded_source(expanded_len); | 154 | std::vector<unsigned char> expanded_source(expanded_len); |
155 | 155 | ||
@@ -189,7 +189,7 @@ int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size, | |||
189 | 189 | ||
190 | if (bonus_size) { | 190 | if (bonus_size) { |
191 | memcpy(expanded_source.data() + (expanded_len - bonus_size), | 191 | memcpy(expanded_source.data() + (expanded_len - bonus_size), |
192 | bonus_data->data, bonus_size); | 192 | &bonus_data->data[0], bonus_size); |
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
diff --git a/applypatch/include/applypatch/applypatch.h b/applypatch/include/applypatch/applypatch.h index 9ee39d29..80d68163 100644 --- a/applypatch/include/applypatch/applypatch.h +++ b/applypatch/include/applypatch/applypatch.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <stdint.h> | 20 | #include <stdint.h> |
21 | #include <sys/stat.h> | 21 | #include <sys/stat.h> |
22 | 22 | ||
23 | #include <string> | ||
23 | #include <vector> | 24 | #include <vector> |
24 | 25 | ||
25 | #include "openssl/sha.h" | 26 | #include "openssl/sha.h" |
@@ -52,19 +53,16 @@ int applypatch(const char* source_filename, | |||
52 | const char* target_filename, | 53 | const char* target_filename, |
53 | const char* target_sha1_str, | 54 | const char* target_sha1_str, |
54 | size_t target_size, | 55 | size_t target_size, |
55 | int num_patches, | 56 | const std::vector<std::string>& patch_sha1_str, |
56 | char** const patch_sha1_str, | ||
57 | Value** patch_data, | 57 | Value** patch_data, |
58 | Value* bonus_data); | 58 | Value* bonus_data); |
59 | int applypatch_check(const char* filename, | 59 | int applypatch_check(const char* filename, |
60 | int num_patches, | 60 | const std::vector<std::string>& patch_sha1_str); |
61 | char** const patch_sha1_str); | ||
62 | 61 | ||
63 | int LoadFileContents(const char* filename, FileContents* file); | 62 | int LoadFileContents(const char* filename, FileContents* file); |
64 | int SaveFileContents(const char* filename, const FileContents* file); | 63 | int SaveFileContents(const char* filename, const FileContents* file); |
65 | void FreeFileContents(FileContents* file); | 64 | void FreeFileContents(FileContents* file); |
66 | int FindMatchingPatch(uint8_t* sha1, char* const * const patch_sha1_str, | 65 | int FindMatchingPatch(uint8_t* sha1, const std::vector<std::string>& patch_sha1_str); |
67 | int num_patches); | ||
68 | 66 | ||
69 | // bsdiff.cpp | 67 | // bsdiff.cpp |
70 | void ShowBSDiffLicense(); | 68 | void ShowBSDiffLicense(); |
diff --git a/applypatch/main.cpp b/applypatch/main.cpp index 1968ae48..a3a45d06 100644 --- a/applypatch/main.cpp +++ b/applypatch/main.cpp | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <unistd.h> | 20 | #include <unistd.h> |
21 | 21 | ||
22 | #include <memory> | 22 | #include <memory> |
23 | #include <string> | ||
23 | #include <vector> | 24 | #include <vector> |
24 | 25 | ||
25 | #include "applypatch/applypatch.h" | 26 | #include "applypatch/applypatch.h" |
@@ -30,7 +31,12 @@ static int CheckMode(int argc, char** argv) { | |||
30 | if (argc < 3) { | 31 | if (argc < 3) { |
31 | return 2; | 32 | return 2; |
32 | } | 33 | } |
33 | return applypatch_check(argv[2], argc-3, argv+3); | 34 | std::vector<std::string> sha1; |
35 | for (int i = 3; i < argc; i++) { | ||
36 | sha1.push_back(argv[i]); | ||
37 | } | ||
38 | |||
39 | return applypatch_check(argv[2], sha1); | ||
34 | } | 40 | } |
35 | 41 | ||
36 | static int SpaceMode(int argc, char** argv) { | 42 | static int SpaceMode(int argc, char** argv) { |
@@ -49,11 +55,13 @@ static int SpaceMode(int argc, char** argv) { | |||
49 | // Parse arguments (which should be of the form "<sha1>:<filename>" | 55 | // Parse arguments (which should be of the form "<sha1>:<filename>" |
50 | // into the new parallel arrays *sha1s and *files.Returns true on | 56 | // into the new parallel arrays *sha1s and *files.Returns true on |
51 | // success. | 57 | // success. |
52 | static bool ParsePatchArgs(int argc, char** argv, std::vector<char*>* sha1s, | 58 | static bool ParsePatchArgs(int argc, char** argv, std::vector<std::string>* sha1s, |
53 | std::vector<FileContents>* files) { | 59 | std::vector<FileContents>* files) { |
54 | uint8_t digest[SHA_DIGEST_LENGTH]; | 60 | if (sha1s == nullptr) { |
55 | 61 | return false; | |
62 | } | ||
56 | for (int i = 0; i < argc; ++i) { | 63 | for (int i = 0; i < argc; ++i) { |
64 | uint8_t digest[SHA_DIGEST_LENGTH]; | ||
57 | char* colon = strchr(argv[i], ':'); | 65 | char* colon = strchr(argv[i], ':'); |
58 | if (colon == nullptr) { | 66 | if (colon == nullptr) { |
59 | printf("no ':' in patch argument \"%s\"\n", argv[i]); | 67 | printf("no ':' in patch argument \"%s\"\n", argv[i]); |
@@ -83,18 +91,15 @@ static int FlashMode(const char* src_filename, const char* tgt_filename, | |||
83 | 91 | ||
84 | static int PatchMode(int argc, char** argv) { | 92 | static int PatchMode(int argc, char** argv) { |
85 | FileContents bonusFc; | 93 | FileContents bonusFc; |
86 | Value bonusValue; | 94 | Value bonus(VAL_INVALID, ""); |
87 | Value* bonus = nullptr; | ||
88 | 95 | ||
89 | if (argc >= 3 && strcmp(argv[1], "-b") == 0) { | 96 | if (argc >= 3 && strcmp(argv[1], "-b") == 0) { |
90 | if (LoadFileContents(argv[2], &bonusFc) != 0) { | 97 | if (LoadFileContents(argv[2], &bonusFc) != 0) { |
91 | printf("failed to load bonus file %s\n", argv[2]); | 98 | printf("failed to load bonus file %s\n", argv[2]); |
92 | return 1; | 99 | return 1; |
93 | } | 100 | } |
94 | bonus = &bonusValue; | 101 | bonus.type = VAL_BLOB; |
95 | bonus->type = VAL_BLOB; | 102 | bonus.data = reinterpret_cast<const char*>(bonusFc.data.data()); |
96 | bonus->size = bonusFc.data.size(); | ||
97 | bonus->data = reinterpret_cast<char*>(bonusFc.data.data()); | ||
98 | argc -= 2; | 103 | argc -= 2; |
99 | argv += 2; | 104 | argv += 2; |
100 | } | 105 | } |
@@ -112,29 +117,26 @@ static int PatchMode(int argc, char** argv) { | |||
112 | 117 | ||
113 | // If no <src-sha1>:<patch> is provided, it is in flash mode. | 118 | // If no <src-sha1>:<patch> is provided, it is in flash mode. |
114 | if (argc == 5) { | 119 | if (argc == 5) { |
115 | if (bonus != nullptr) { | 120 | if (bonus.type != VAL_INVALID) { |
116 | printf("bonus file not supported in flash mode\n"); | 121 | printf("bonus file not supported in flash mode\n"); |
117 | return 1; | 122 | return 1; |
118 | } | 123 | } |
119 | return FlashMode(argv[1], argv[2], argv[3], target_size); | 124 | return FlashMode(argv[1], argv[2], argv[3], target_size); |
120 | } | 125 | } |
121 | std::vector<char*> sha1s; | 126 | std::vector<std::string> sha1s; |
122 | std::vector<FileContents> files; | 127 | std::vector<FileContents> files; |
123 | if (!ParsePatchArgs(argc-5, argv+5, &sha1s, &files)) { | 128 | if (!ParsePatchArgs(argc-5, argv+5, &sha1s, &files)) { |
124 | printf("failed to parse patch args\n"); | 129 | printf("failed to parse patch args\n"); |
125 | return 1; | 130 | return 1; |
126 | } | 131 | } |
127 | std::vector<Value> patches(files.size()); | 132 | std::vector<Value> patches; |
128 | std::vector<Value*> patch_ptrs(files.size()); | 133 | std::vector<Value*> patch_ptrs; |
129 | for (size_t i = 0; i < files.size(); ++i) { | 134 | for (size_t i = 0; i < files.size(); ++i) { |
130 | patches[i].type = VAL_BLOB; | 135 | patches.push_back(Value(VAL_BLOB, reinterpret_cast<const char*>(files[i].data.data()))); |
131 | patches[i].size = files[i].data.size(); | 136 | patch_ptrs.push_back(&patches[i]); |
132 | patches[i].data = reinterpret_cast<char*>(files[i].data.data()); | ||
133 | patch_ptrs[i] = &patches[i]; | ||
134 | } | 137 | } |
135 | return applypatch(argv[1], argv[2], argv[3], target_size, | 138 | return applypatch(argv[1], argv[2], argv[3], target_size, |
136 | patch_ptrs.size(), sha1s.data(), | 139 | sha1s, patch_ptrs.data(), &bonus); |
137 | patch_ptrs.data(), bonus); | ||
138 | } | 140 | } |
139 | 141 | ||
140 | // This program applies binary patches to files in a way that is safe | 142 | // This program applies binary patches to files in a way that is safe |
diff --git a/applypatch/utils.cpp b/applypatch/utils.cpp index fef250f0..450dc8d7 100644 --- a/applypatch/utils.cpp +++ b/applypatch/utils.cpp | |||
@@ -38,22 +38,22 @@ void Write8(int64_t value, FILE* f) { | |||
38 | fputc((value >> 56) & 0xff, f); | 38 | fputc((value >> 56) & 0xff, f); |
39 | } | 39 | } |
40 | 40 | ||
41 | int Read2(void* pv) { | 41 | int Read2(const void* pv) { |
42 | unsigned char* p = reinterpret_cast<unsigned char*>(pv); | 42 | const unsigned char* p = reinterpret_cast<const unsigned char*>(pv); |
43 | return (int)(((unsigned int)p[1] << 8) | | 43 | return (int)(((unsigned int)p[1] << 8) | |
44 | (unsigned int)p[0]); | 44 | (unsigned int)p[0]); |
45 | } | 45 | } |
46 | 46 | ||
47 | int Read4(void* pv) { | 47 | int Read4(const void* pv) { |
48 | unsigned char* p = reinterpret_cast<unsigned char*>(pv); | 48 | const unsigned char* p = reinterpret_cast<const unsigned char*>(pv); |
49 | return (int)(((unsigned int)p[3] << 24) | | 49 | return (int)(((unsigned int)p[3] << 24) | |
50 | ((unsigned int)p[2] << 16) | | 50 | ((unsigned int)p[2] << 16) | |
51 | ((unsigned int)p[1] << 8) | | 51 | ((unsigned int)p[1] << 8) | |
52 | (unsigned int)p[0]); | 52 | (unsigned int)p[0]); |
53 | } | 53 | } |
54 | 54 | ||
55 | int64_t Read8(void* pv) { | 55 | int64_t Read8(const void* pv) { |
56 | unsigned char* p = reinterpret_cast<unsigned char*>(pv); | 56 | const unsigned char* p = reinterpret_cast<const unsigned char*>(pv); |
57 | return (int64_t)(((uint64_t)p[7] << 56) | | 57 | return (int64_t)(((uint64_t)p[7] << 56) | |
58 | ((uint64_t)p[6] << 48) | | 58 | ((uint64_t)p[6] << 48) | |
59 | ((uint64_t)p[5] << 40) | | 59 | ((uint64_t)p[5] << 40) | |
diff --git a/applypatch/utils.h b/applypatch/utils.h index 1c34edd9..c7c8e90e 100644 --- a/applypatch/utils.h +++ b/applypatch/utils.h | |||
@@ -24,8 +24,8 @@ | |||
24 | 24 | ||
25 | void Write4(int value, FILE* f); | 25 | void Write4(int value, FILE* f); |
26 | void Write8(int64_t value, FILE* f); | 26 | void Write8(int64_t value, FILE* f); |
27 | int Read2(void* p); | 27 | int Read2(const void* p); |
28 | int Read4(void* p); | 28 | int Read4(const void* p); |
29 | int64_t Read8(void* p); | 29 | int64_t Read8(const void* p); |
30 | 30 | ||
31 | #endif // _BUILD_TOOLS_APPLYPATCH_UTILS_H | 31 | #endif // _BUILD_TOOLS_APPLYPATCH_UTILS_H |
diff --git a/edify/edify_parser.cpp b/edify/edify_parser.cpp index 1b89cf21..908fcf13 100644 --- a/edify/edify_parser.cpp +++ b/edify/edify_parser.cpp | |||
@@ -66,12 +66,12 @@ int main(int argc, char** argv) { | |||
66 | ExprDump(0, root, buffer); | 66 | ExprDump(0, root, buffer); |
67 | 67 | ||
68 | State state(buffer, nullptr); | 68 | State state(buffer, nullptr); |
69 | char* result = Evaluate(&state, root); | 69 | std::string result; |
70 | if (result == NULL) { | 70 | if (!Evaluate(&state, root, &result)) { |
71 | printf("result was NULL, message is: %s\n", | 71 | printf("result was NULL, message is: %s\n", |
72 | (state.errmsg.empty() ? "(NULL)" : state.errmsg.c_str())); | 72 | (state.errmsg.empty() ? "(NULL)" : state.errmsg.c_str())); |
73 | } else { | 73 | } else { |
74 | printf("result is [%s]\n", result); | 74 | printf("result is [%s]\n", result.c_str()); |
75 | } | 75 | } |
76 | } | 76 | } |
77 | return 0; | 77 | return 0; |
diff --git a/edify/expr.cpp b/edify/expr.cpp index 4000bc4d..ec240975 100644 --- a/edify/expr.cpp +++ b/edify/expr.cpp | |||
@@ -22,184 +22,164 @@ | |||
22 | #include <string.h> | 22 | #include <string.h> |
23 | #include <unistd.h> | 23 | #include <unistd.h> |
24 | 24 | ||
25 | #include <memory> | ||
25 | #include <string> | 26 | #include <string> |
26 | #include <unordered_map> | 27 | #include <unordered_map> |
28 | #include <vector> | ||
27 | 29 | ||
30 | #include <android-base/parseint.h> | ||
28 | #include <android-base/stringprintf.h> | 31 | #include <android-base/stringprintf.h> |
29 | #include <android-base/strings.h> | 32 | #include <android-base/strings.h> |
30 | 33 | ||
31 | // Functions should: | 34 | // Functions should: |
32 | // | 35 | // |
33 | // - return a malloc()'d string | 36 | // - return a malloc()'d string |
34 | // - if Evaluate() on any argument returns NULL, return NULL. | 37 | // - if Evaluate() on any argument returns nullptr, return nullptr. |
35 | 38 | ||
36 | int BooleanString(const char* s) { | 39 | static bool BooleanString(const std::string& s) { |
37 | return s[0] != '\0'; | 40 | return !s.empty(); |
38 | } | 41 | } |
39 | 42 | ||
40 | char* Evaluate(State* state, Expr* expr) { | 43 | bool Evaluate(State* state, Expr* expr, std::string* result) { |
41 | Value* v = expr->fn(expr->name, state, expr->argc, expr->argv); | 44 | if (result == nullptr) { |
42 | if (v == NULL) return NULL; | 45 | return false; |
46 | } | ||
47 | |||
48 | std::unique_ptr<Value> v(expr->fn(expr->name, state, expr->argc, expr->argv)); | ||
49 | if (!v) { | ||
50 | return false; | ||
51 | } | ||
43 | if (v->type != VAL_STRING) { | 52 | if (v->type != VAL_STRING) { |
44 | ErrorAbort(state, kArgsParsingFailure, "expecting string, got value type %d", v->type); | 53 | ErrorAbort(state, kArgsParsingFailure, "expecting string, got value type %d", v->type); |
45 | FreeValue(v); | 54 | return false; |
46 | return NULL; | ||
47 | } | 55 | } |
48 | char* result = v->data; | 56 | |
49 | free(v); | 57 | *result = v->data; |
50 | return result; | 58 | return true; |
51 | } | 59 | } |
52 | 60 | ||
53 | Value* EvaluateValue(State* state, Expr* expr) { | 61 | Value* EvaluateValue(State* state, Expr* expr) { |
54 | return expr->fn(expr->name, state, expr->argc, expr->argv); | 62 | return expr->fn(expr->name, state, expr->argc, expr->argv); |
55 | } | 63 | } |
56 | 64 | ||
57 | Value* StringValue(char* str) { | 65 | Value* StringValue(const char* str) { |
58 | if (str == NULL) return NULL; | 66 | if (str == nullptr) { |
59 | Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value))); | 67 | return nullptr; |
60 | v->type = VAL_STRING; | 68 | } |
61 | v->size = strlen(str); | 69 | return new Value(VAL_STRING, str); |
62 | v->data = str; | ||
63 | return v; | ||
64 | } | 70 | } |
65 | 71 | ||
66 | void FreeValue(Value* v) { | 72 | Value* StringValue(const std::string& str) { |
67 | if (v == NULL) return; | 73 | return StringValue(str.c_str()); |
68 | free(v->data); | ||
69 | free(v); | ||
70 | } | 74 | } |
71 | 75 | ||
72 | Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { | 76 | Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { |
73 | if (argc == 0) { | 77 | if (argc == 0) { |
74 | return StringValue(strdup("")); | 78 | return StringValue(""); |
75 | } | 79 | } |
76 | char** strings = reinterpret_cast<char**>(malloc(argc * sizeof(char*))); | 80 | std::string result; |
77 | int i; | 81 | for (int i = 0; i < argc; ++i) { |
78 | for (i = 0; i < argc; ++i) { | 82 | std::string str; |
79 | strings[i] = NULL; | 83 | if (!Evaluate(state, argv[i], &str)) { |
80 | } | 84 | return nullptr; |
81 | char* result = NULL; | ||
82 | int length = 0; | ||
83 | for (i = 0; i < argc; ++i) { | ||
84 | strings[i] = Evaluate(state, argv[i]); | ||
85 | if (strings[i] == NULL) { | ||
86 | goto done; | ||
87 | } | 85 | } |
88 | length += strlen(strings[i]); | 86 | result += str; |
89 | } | 87 | } |
90 | 88 | ||
91 | result = reinterpret_cast<char*>(malloc(length+1)); | ||
92 | int p; | ||
93 | p = 0; | ||
94 | for (i = 0; i < argc; ++i) { | ||
95 | strcpy(result+p, strings[i]); | ||
96 | p += strlen(strings[i]); | ||
97 | } | ||
98 | result[p] = '\0'; | ||
99 | |||
100 | done: | ||
101 | for (i = 0; i < argc; ++i) { | ||
102 | free(strings[i]); | ||
103 | } | ||
104 | free(strings); | ||
105 | return StringValue(result); | 89 | return StringValue(result); |
106 | } | 90 | } |
107 | 91 | ||
108 | Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { | 92 | Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { |
109 | if (argc != 2 && argc != 3) { | 93 | if (argc != 2 && argc != 3) { |
110 | state->errmsg = "ifelse expects 2 or 3 arguments"; | 94 | state->errmsg = "ifelse expects 2 or 3 arguments"; |
111 | return NULL; | 95 | return nullptr; |
112 | } | 96 | } |
113 | char* cond = Evaluate(state, argv[0]); | 97 | |
114 | if (cond == NULL) { | 98 | std::string cond; |
115 | return NULL; | 99 | if (!Evaluate(state, argv[0], &cond)) { |
100 | return nullptr; | ||
116 | } | 101 | } |
117 | 102 | ||
118 | if (BooleanString(cond) == true) { | 103 | if (!cond.empty()) { |
119 | free(cond); | ||
120 | return EvaluateValue(state, argv[1]); | 104 | return EvaluateValue(state, argv[1]); |
121 | } else { | 105 | } else if (argc == 3) { |
122 | if (argc == 3) { | 106 | return EvaluateValue(state, argv[2]); |
123 | free(cond); | ||
124 | return EvaluateValue(state, argv[2]); | ||
125 | } else { | ||
126 | return StringValue(cond); | ||
127 | } | ||
128 | } | 107 | } |
108 | |||
109 | return StringValue(""); | ||
129 | } | 110 | } |
130 | 111 | ||
131 | Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { | 112 | Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { |
132 | char* msg = NULL; | 113 | std::string msg; |
133 | if (argc > 0) { | 114 | if (argc > 0 && Evaluate(state, argv[0], &msg)) { |
134 | msg = Evaluate(state, argv[0]); | ||
135 | } | ||
136 | if (msg) { | ||
137 | state->errmsg = msg; | 115 | state->errmsg = msg; |
138 | } else { | 116 | } else { |
139 | state->errmsg = "called abort()"; | 117 | state->errmsg = "called abort()"; |
140 | } | 118 | } |
141 | return NULL; | 119 | return nullptr; |
142 | } | 120 | } |
143 | 121 | ||
144 | Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { | 122 | Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { |
145 | int i; | 123 | for (int i = 0; i < argc; ++i) { |
146 | for (i = 0; i < argc; ++i) { | 124 | std::string result; |
147 | char* v = Evaluate(state, argv[i]); | 125 | if (!Evaluate(state, argv[i], &result)) { |
148 | if (v == NULL) { | 126 | return nullptr; |
149 | return NULL; | ||
150 | } | 127 | } |
151 | int b = BooleanString(v); | 128 | if (result.empty()) { |
152 | free(v); | ||
153 | if (!b) { | ||
154 | int len = argv[i]->end - argv[i]->start; | 129 | int len = argv[i]->end - argv[i]->start; |
155 | state->errmsg = "assert failed: " + state->script.substr(argv[i]->start, len); | 130 | state->errmsg = "assert failed: " + state->script.substr(argv[i]->start, len); |
156 | return NULL; | 131 | return nullptr; |
157 | } | 132 | } |
158 | } | 133 | } |
159 | return StringValue(strdup("")); | 134 | return StringValue(""); |
160 | } | 135 | } |
161 | 136 | ||
162 | Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { | 137 | Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { |
163 | char* val = Evaluate(state, argv[0]); | 138 | std::string val; |
164 | if (val == NULL) { | 139 | if (!Evaluate(state, argv[0], &val)) { |
165 | return NULL; | 140 | return nullptr; |
141 | } | ||
142 | |||
143 | int v; | ||
144 | if (!android::base::ParseInt(val.c_str(), &v, 0)) { | ||
145 | return nullptr; | ||
166 | } | 146 | } |
167 | int v = strtol(val, NULL, 10); | ||
168 | sleep(v); | 147 | sleep(v); |
148 | |||
169 | return StringValue(val); | 149 | return StringValue(val); |
170 | } | 150 | } |
171 | 151 | ||
172 | Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { | 152 | Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { |
173 | int i; | 153 | for (int i = 0; i < argc; ++i) { |
174 | for (i = 0; i < argc; ++i) { | 154 | std::string v; |
175 | char* v = Evaluate(state, argv[i]); | 155 | if (!Evaluate(state, argv[i], &v)) { |
176 | if (v == NULL) { | 156 | return nullptr; |
177 | return NULL; | ||
178 | } | 157 | } |
179 | fputs(v, stdout); | 158 | fputs(v.c_str(), stdout); |
180 | free(v); | ||
181 | } | 159 | } |
182 | return StringValue(strdup("")); | 160 | return StringValue(""); |
183 | } | 161 | } |
184 | 162 | ||
185 | Value* LogicalAndFn(const char* name, State* state, | 163 | Value* LogicalAndFn(const char* name, State* state, |
186 | int argc, Expr* argv[]) { | 164 | int argc, Expr* argv[]) { |
187 | char* left = Evaluate(state, argv[0]); | 165 | std::string left; |
188 | if (left == NULL) return NULL; | 166 | if (!Evaluate(state, argv[0], &left)) { |
189 | if (BooleanString(left) == true) { | 167 | return nullptr; |
190 | free(left); | 168 | } |
169 | if (BooleanString(left)) { | ||
191 | return EvaluateValue(state, argv[1]); | 170 | return EvaluateValue(state, argv[1]); |
192 | } else { | 171 | } else { |
193 | return StringValue(left); | 172 | return StringValue(""); |
194 | } | 173 | } |
195 | } | 174 | } |
196 | 175 | ||
197 | Value* LogicalOrFn(const char* name, State* state, | 176 | Value* LogicalOrFn(const char* name, State* state, |
198 | int argc, Expr* argv[]) { | 177 | int argc, Expr* argv[]) { |
199 | char* left = Evaluate(state, argv[0]); | 178 | std::string left; |
200 | if (left == NULL) return NULL; | 179 | if (!Evaluate(state, argv[0], &left)) { |
201 | if (BooleanString(left) == false) { | 180 | return nullptr; |
202 | free(left); | 181 | } |
182 | if (!BooleanString(left)) { | ||
203 | return EvaluateValue(state, argv[1]); | 183 | return EvaluateValue(state, argv[1]); |
204 | } else { | 184 | } else { |
205 | return StringValue(left); | 185 | return StringValue(left); |
@@ -208,75 +188,75 @@ Value* LogicalOrFn(const char* name, State* state, | |||
208 | 188 | ||
209 | Value* LogicalNotFn(const char* name, State* state, | 189 | Value* LogicalNotFn(const char* name, State* state, |
210 | int argc, Expr* argv[]) { | 190 | int argc, Expr* argv[]) { |
211 | char* val = Evaluate(state, argv[0]); | 191 | std::string val; |
212 | if (val == NULL) return NULL; | 192 | if (!Evaluate(state, argv[0], &val)) { |
213 | bool bv = BooleanString(val); | 193 | return nullptr; |
214 | free(val); | 194 | } |
215 | return StringValue(strdup(bv ? "" : "t")); | 195 | |
196 | return StringValue(BooleanString(val) ? "" : "t"); | ||
216 | } | 197 | } |
217 | 198 | ||
218 | Value* SubstringFn(const char* name, State* state, | 199 | Value* SubstringFn(const char* name, State* state, |
219 | int argc, Expr* argv[]) { | 200 | int argc, Expr* argv[]) { |
220 | char* needle = Evaluate(state, argv[0]); | 201 | std::string needle; |
221 | if (needle == NULL) return NULL; | 202 | if (!Evaluate(state, argv[0], &needle)) { |
222 | char* haystack = Evaluate(state, argv[1]); | 203 | return nullptr; |
223 | if (haystack == NULL) { | 204 | } |
224 | free(needle); | 205 | |
225 | return NULL; | 206 | std::string haystack; |
207 | if (!Evaluate(state, argv[1], &haystack)) { | ||
208 | return nullptr; | ||
226 | } | 209 | } |
227 | 210 | ||
228 | char* result = strdup(strstr(haystack, needle) ? "t" : ""); | 211 | std::string result = (haystack.find(needle) != std::string::npos) ? "t" : ""; |
229 | free(needle); | ||
230 | free(haystack); | ||
231 | return StringValue(result); | 212 | return StringValue(result); |
232 | } | 213 | } |
233 | 214 | ||
234 | Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { | 215 | Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { |
235 | char* left = Evaluate(state, argv[0]); | 216 | std::string left; |
236 | if (left == NULL) return NULL; | 217 | if (!Evaluate(state, argv[0], &left)) { |
237 | char* right = Evaluate(state, argv[1]); | 218 | return nullptr; |
238 | if (right == NULL) { | 219 | } |
239 | free(left); | 220 | std::string right; |
240 | return NULL; | 221 | if (!Evaluate(state, argv[1], &right)) { |
222 | return nullptr; | ||
241 | } | 223 | } |
242 | 224 | ||
243 | char* result = strdup(strcmp(left, right) == 0 ? "t" : ""); | 225 | const char* result = (left == right) ? "t" : ""; |
244 | free(left); | ||
245 | free(right); | ||
246 | return StringValue(result); | 226 | return StringValue(result); |
247 | } | 227 | } |
248 | 228 | ||
249 | Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { | 229 | Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { |
250 | char* left = Evaluate(state, argv[0]); | 230 | std::string left; |
251 | if (left == NULL) return NULL; | 231 | if (!Evaluate(state, argv[0], &left)) { |
252 | char* right = Evaluate(state, argv[1]); | 232 | return nullptr; |
253 | if (right == NULL) { | 233 | } |
254 | free(left); | 234 | std::string right; |
255 | return NULL; | 235 | if (!Evaluate(state, argv[1], &right)) { |
236 | return nullptr; | ||
256 | } | 237 | } |
257 | 238 | ||
258 | char* result = strdup(strcmp(left, right) != 0 ? "t" : ""); | 239 | const char* result = (left != right) ? "t" : ""; |
259 | free(left); | ||
260 | free(right); | ||
261 | return StringValue(result); | 240 | return StringValue(result); |
262 | } | 241 | } |
263 | 242 | ||
264 | Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { | 243 | Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { |
265 | Value* left = EvaluateValue(state, argv[0]); | 244 | std::unique_ptr<Value> left(EvaluateValue(state, argv[0])); |
266 | if (left == NULL) return NULL; | 245 | if (!left) { |
267 | FreeValue(left); | 246 | return nullptr; |
247 | } | ||
268 | return EvaluateValue(state, argv[1]); | 248 | return EvaluateValue(state, argv[1]); |
269 | } | 249 | } |
270 | 250 | ||
271 | Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { | 251 | Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { |
272 | if (argc != 2) { | 252 | if (argc != 2) { |
273 | state->errmsg = "less_than_int expects 2 arguments"; | 253 | state->errmsg = "less_than_int expects 2 arguments"; |
274 | return NULL; | 254 | return nullptr; |
275 | } | 255 | } |
276 | 256 | ||
277 | char* left; | 257 | char* left; |
278 | char* right; | 258 | char* right; |
279 | if (ReadArgs(state, argv, 2, &left, &right) < 0) return NULL; | 259 | if (ReadArgs(state, argv, 2, &left, &right) < 0) return nullptr; |
280 | 260 | ||
281 | bool result = false; | 261 | bool result = false; |
282 | char* end; | 262 | char* end; |
@@ -298,14 +278,14 @@ Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
298 | done: | 278 | done: |
299 | free(left); | 279 | free(left); |
300 | free(right); | 280 | free(right); |
301 | return StringValue(strdup(result ? "t" : "")); | 281 | return StringValue(result ? "t" : ""); |
302 | } | 282 | } |
303 | 283 | ||
304 | Value* GreaterThanIntFn(const char* name, State* state, | 284 | Value* GreaterThanIntFn(const char* name, State* state, |
305 | int argc, Expr* argv[]) { | 285 | int argc, Expr* argv[]) { |
306 | if (argc != 2) { | 286 | if (argc != 2) { |
307 | state->errmsg = "greater_than_int expects 2 arguments"; | 287 | state->errmsg = "greater_than_int expects 2 arguments"; |
308 | return NULL; | 288 | return nullptr; |
309 | } | 289 | } |
310 | 290 | ||
311 | Expr* temp[2]; | 291 | Expr* temp[2]; |
@@ -316,7 +296,7 @@ Value* GreaterThanIntFn(const char* name, State* state, | |||
316 | } | 296 | } |
317 | 297 | ||
318 | Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { | 298 | Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { |
319 | return StringValue(strdup(name)); | 299 | return StringValue(name); |
320 | } | 300 | } |
321 | 301 | ||
322 | // ----------------------------------------------------------------- | 302 | // ----------------------------------------------------------------- |
@@ -355,6 +335,43 @@ void RegisterBuiltins() { | |||
355 | // convenience methods for functions | 335 | // convenience methods for functions |
356 | // ----------------------------------------------------------------- | 336 | // ----------------------------------------------------------------- |
357 | 337 | ||
338 | // Evaluate the expressions in argv, and put the results of strings in | ||
339 | // args. If any expression evaluates to nullptr, free the rest and return | ||
340 | // false. Return true on success. | ||
341 | bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* args) { | ||
342 | if (args == nullptr) { | ||
343 | return false; | ||
344 | } | ||
345 | for (int i = 0; i < argc; ++i) { | ||
346 | std::string var; | ||
347 | if (!Evaluate(state, argv[i], &var)) { | ||
348 | args->clear(); | ||
349 | return false; | ||
350 | } | ||
351 | args->push_back(var); | ||
352 | } | ||
353 | return true; | ||
354 | } | ||
355 | |||
356 | // Evaluate the expressions in argv, and put the results of Value* in | ||
357 | // args. If any expression evaluate to nullptr, free the rest and return | ||
358 | // false. Return true on success. | ||
359 | bool ReadValueArgs(State* state, int argc, Expr* argv[], | ||
360 | std::vector<std::unique_ptr<Value>>* args) { | ||
361 | if (args == nullptr) { | ||
362 | return false; | ||
363 | } | ||
364 | for (int i = 0; i < argc; ++i) { | ||
365 | std::unique_ptr<Value> v(EvaluateValue(state, argv[i])); | ||
366 | if (!v) { | ||
367 | args->clear(); | ||
368 | return false; | ||
369 | } | ||
370 | args->push_back(std::move(v)); | ||
371 | } | ||
372 | return true; | ||
373 | } | ||
374 | |||
358 | // Evaluate the expressions in argv, giving 'count' char* (the ... is | 375 | // Evaluate the expressions in argv, giving 'count' char* (the ... is |
359 | // zero or more char** to put them in). If any expression evaluates | 376 | // zero or more char** to put them in). If any expression evaluates |
360 | // to NULL, free the rest and return -1. Return 0 on success. | 377 | // to NULL, free the rest and return -1. Return 0 on success. |
@@ -364,8 +381,9 @@ int ReadArgs(State* state, Expr* argv[], int count, ...) { | |||
364 | va_start(v, count); | 381 | va_start(v, count); |
365 | int i; | 382 | int i; |
366 | for (i = 0; i < count; ++i) { | 383 | for (i = 0; i < count; ++i) { |
367 | args[i] = Evaluate(state, argv[i]); | 384 | std::string str; |
368 | if (args[i] == NULL) { | 385 | if (!Evaluate(state, argv[i], &str) || |
386 | (args[i] = strdup(str.c_str())) == nullptr) { | ||
369 | va_end(v); | 387 | va_end(v); |
370 | int j; | 388 | int j; |
371 | for (j = 0; j < i; ++j) { | 389 | for (j = 0; j < i; ++j) { |
@@ -385,25 +403,24 @@ int ReadArgs(State* state, Expr* argv[], int count, ...) { | |||
385 | // zero or more Value** to put them in). If any expression evaluates | 403 | // zero or more Value** to put them in). If any expression evaluates |
386 | // to NULL, free the rest and return -1. Return 0 on success. | 404 | // to NULL, free the rest and return -1. Return 0 on success. |
387 | int ReadValueArgs(State* state, Expr* argv[], int count, ...) { | 405 | int ReadValueArgs(State* state, Expr* argv[], int count, ...) { |
388 | Value** args = reinterpret_cast<Value**>(malloc(count * sizeof(Value*))); | 406 | Value** args = new Value*[count]; |
389 | va_list v; | 407 | va_list v; |
390 | va_start(v, count); | 408 | va_start(v, count); |
391 | int i; | 409 | for (int i = 0; i < count; ++i) { |
392 | for (i = 0; i < count; ++i) { | ||
393 | args[i] = EvaluateValue(state, argv[i]); | 410 | args[i] = EvaluateValue(state, argv[i]); |
394 | if (args[i] == NULL) { | 411 | if (args[i] == NULL) { |
395 | va_end(v); | 412 | va_end(v); |
396 | int j; | 413 | int j; |
397 | for (j = 0; j < i; ++j) { | 414 | for (j = 0; j < i; ++j) { |
398 | FreeValue(args[j]); | 415 | delete args[j]; |
399 | } | 416 | } |
400 | free(args); | 417 | delete[] args; |
401 | return -1; | 418 | return -1; |
402 | } | 419 | } |
403 | *(va_arg(v, Value**)) = args[i]; | 420 | *(va_arg(v, Value**)) = args[i]; |
404 | } | 421 | } |
405 | va_end(v); | 422 | va_end(v); |
406 | free(args); | 423 | delete[] args; |
407 | return 0; | 424 | return 0; |
408 | } | 425 | } |
409 | 426 | ||
@@ -413,12 +430,11 @@ int ReadValueArgs(State* state, Expr* argv[], int count, ...) { | |||
413 | // strings it contains. | 430 | // strings it contains. |
414 | char** ReadVarArgs(State* state, int argc, Expr* argv[]) { | 431 | char** ReadVarArgs(State* state, int argc, Expr* argv[]) { |
415 | char** args = (char**)malloc(argc * sizeof(char*)); | 432 | char** args = (char**)malloc(argc * sizeof(char*)); |
416 | int i = 0; | 433 | for (int i = 0; i < argc; ++i) { |
417 | for (i = 0; i < argc; ++i) { | 434 | std::string str; |
418 | args[i] = Evaluate(state, argv[i]); | 435 | if (!Evaluate(state, argv[i], &str) || |
419 | if (args[i] == NULL) { | 436 | (args[i] = strdup(str.c_str())) == nullptr) { |
420 | int j; | 437 | for (int j = 0; j < i; ++j) { |
421 | for (j = 0; j < i; ++j) { | ||
422 | free(args[j]); | 438 | free(args[j]); |
423 | } | 439 | } |
424 | free(args); | 440 | free(args); |
@@ -433,16 +449,16 @@ char** ReadVarArgs(State* state, int argc, Expr* argv[]) { | |||
433 | // The caller is responsible for freeing the returned array and the | 449 | // The caller is responsible for freeing the returned array and the |
434 | // Values it contains. | 450 | // Values it contains. |
435 | Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) { | 451 | Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) { |
436 | Value** args = (Value**)malloc(argc * sizeof(Value*)); | 452 | Value** args = new Value*[argc]; |
437 | int i = 0; | 453 | int i = 0; |
438 | for (i = 0; i < argc; ++i) { | 454 | for (i = 0; i < argc; ++i) { |
439 | args[i] = EvaluateValue(state, argv[i]); | 455 | args[i] = EvaluateValue(state, argv[i]); |
440 | if (args[i] == NULL) { | 456 | if (args[i] == NULL) { |
441 | int j; | 457 | int j; |
442 | for (j = 0; j < i; ++j) { | 458 | for (j = 0; j < i; ++j) { |
443 | FreeValue(args[j]); | 459 | delete args[j]; |
444 | } | 460 | } |
445 | free(args); | 461 | delete[] args; |
446 | return NULL; | 462 | return NULL; |
447 | } | 463 | } |
448 | } | 464 | } |
diff --git a/edify/expr.h b/edify/expr.h index cd6139a1..85306542 100644 --- a/edify/expr.h +++ b/edify/expr.h | |||
@@ -48,13 +48,19 @@ struct State { | |||
48 | bool is_retry = false; | 48 | bool is_retry = false; |
49 | }; | 49 | }; |
50 | 50 | ||
51 | #define VAL_STRING 1 // data will be NULL-terminated; size doesn't count null | 51 | enum ValueType { |
52 | #define VAL_BLOB 2 | 52 | VAL_INVALID = -1, |
53 | VAL_STRING = 1, | ||
54 | VAL_BLOB = 2, | ||
55 | }; | ||
53 | 56 | ||
54 | struct Value { | 57 | struct Value { |
55 | int type; | 58 | ValueType type; |
56 | ssize_t size; | 59 | std::string data; |
57 | char* data; | 60 | |
61 | Value(ValueType type, const std::string& str) : | ||
62 | type(type), | ||
63 | data(str) {} | ||
58 | }; | 64 | }; |
59 | 65 | ||
60 | struct Expr; | 66 | struct Expr; |
@@ -75,11 +81,11 @@ struct Expr { | |||
75 | Value* EvaluateValue(State* state, Expr* expr); | 81 | Value* EvaluateValue(State* state, Expr* expr); |
76 | 82 | ||
77 | // Take one of the Expr*s passed to the function as an argument, | 83 | // Take one of the Expr*s passed to the function as an argument, |
78 | // evaluate it, assert that it is a string, and return the resulting | 84 | // evaluate it, assert that it is a string, and update the result |
79 | // char*. The caller takes ownership of the returned char*. This is | 85 | // parameter. This function returns true if the evaluation succeeds. |
80 | // a convenience function for older functions that want to deal only | 86 | // This is a convenience function for older functions that want to |
81 | // with strings. | 87 | // deal only with strings. |
82 | char* Evaluate(State* state, Expr* expr); | 88 | bool Evaluate(State* state, Expr* expr, std::string* result); |
83 | 89 | ||
84 | // Glue to make an Expr out of a literal. | 90 | // Glue to make an Expr out of a literal. |
85 | Value* Literal(const char* name, State* state, int argc, Expr* argv[]); | 91 | Value* Literal(const char* name, State* state, int argc, Expr* argv[]); |
@@ -114,6 +120,17 @@ Function FindFunction(const std::string& name); | |||
114 | 120 | ||
115 | // --- convenience functions for use in functions --- | 121 | // --- convenience functions for use in functions --- |
116 | 122 | ||
123 | // Evaluate the expressions in argv, and put the results of strings in | ||
124 | // args. If any expression evaluates to nullptr, free the rest and return | ||
125 | // false. Return true on success. | ||
126 | bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* args); | ||
127 | |||
128 | // Evaluate the expressions in argv, and put the results of Value* in | ||
129 | // args. If any expression evaluate to nullptr, free the rest and return | ||
130 | // false. Return true on success. | ||
131 | bool ReadValueArgs(State* state, int argc, Expr* argv[], | ||
132 | std::vector<std::unique_ptr<Value>>* args); | ||
133 | |||
117 | // Evaluate the expressions in argv, giving 'count' char* (the ... is | 134 | // Evaluate the expressions in argv, giving 'count' char* (the ... is |
118 | // zero or more char** to put them in). If any expression evaluates | 135 | // zero or more char** to put them in). If any expression evaluates |
119 | // to NULL, free the rest and return -1. Return 0 on success. | 136 | // to NULL, free the rest and return -1. Return 0 on success. |
@@ -146,11 +163,10 @@ Value* ErrorAbort(State* state, const char* format, ...) | |||
146 | Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...) | 163 | Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...) |
147 | __attribute__((format(printf, 3, 4))); | 164 | __attribute__((format(printf, 3, 4))); |
148 | 165 | ||
149 | // Wrap a string into a Value, taking ownership of the string. | 166 | // Copying the string into a Value. |
150 | Value* StringValue(char* str); | 167 | Value* StringValue(const char* str); |
151 | 168 | ||
152 | // Free a Value object. | 169 | Value* StringValue(const std::string& str); |
153 | void FreeValue(Value* v); | ||
154 | 170 | ||
155 | int parse_string(const char* str, Expr** root, int* error_count); | 171 | int parse_string(const char* str, Expr** root, int* error_count); |
156 | 172 | ||
diff --git a/tests/component/applypatch_test.cpp b/tests/component/applypatch_test.cpp index 2f7cb02f..75f2e101 100644 --- a/tests/component/applypatch_test.cpp +++ b/tests/component/applypatch_test.cpp | |||
@@ -153,25 +153,16 @@ class ApplyPatchFullTest : public ApplyPatchCacheTest { | |||
153 | struct FileContents fc; | 153 | struct FileContents fc; |
154 | 154 | ||
155 | ASSERT_EQ(0, LoadFileContents(&rand_file[0], &fc)); | 155 | ASSERT_EQ(0, LoadFileContents(&rand_file[0], &fc)); |
156 | Value* patch1 = new Value(); | 156 | Value* patch1 = new Value(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())); |
157 | patch1->type = VAL_BLOB; | ||
158 | patch1->size = fc.data.size(); | ||
159 | patch1->data = static_cast<char*>(malloc(fc.data.size())); | ||
160 | memcpy(patch1->data, fc.data.data(), fc.data.size()); | ||
161 | patches.push_back(patch1); | 157 | patches.push_back(patch1); |
162 | 158 | ||
163 | ASSERT_EQ(0, LoadFileContents(&patch_file[0], &fc)); | 159 | ASSERT_EQ(0, LoadFileContents(&patch_file[0], &fc)); |
164 | Value* patch2 = new Value(); | 160 | Value* patch2 = new Value(VAL_BLOB, std::string(fc.data.begin(), fc.data.end())); |
165 | patch2->type = VAL_BLOB; | ||
166 | patch2->size = fc.st.st_size; | ||
167 | patch2->data = static_cast<char*>(malloc(fc.data.size())); | ||
168 | memcpy(patch2->data, fc.data.data(), fc.data.size()); | ||
169 | patches.push_back(patch2); | 161 | patches.push_back(patch2); |
170 | } | 162 | } |
171 | static void TearDownTestCase() { | 163 | static void TearDownTestCase() { |
172 | delete output_f; | 164 | delete output_f; |
173 | for (auto it = patches.begin(); it != patches.end(); ++it) { | 165 | for (auto it = patches.begin(); it != patches.end(); ++it) { |
174 | free((*it)->data); | ||
175 | delete *it; | 166 | delete *it; |
176 | } | 167 | } |
177 | patches.clear(); | 168 | patches.clear(); |
@@ -210,88 +201,87 @@ TemporaryFile* ApplyPatchFullTest::output_f; | |||
210 | std::string ApplyPatchFullTest::output_loc; | 201 | std::string ApplyPatchFullTest::output_loc; |
211 | 202 | ||
212 | TEST_F(ApplyPatchTest, CheckModeSingle) { | 203 | TEST_F(ApplyPatchTest, CheckModeSingle) { |
213 | char* s = &old_sha1[0]; | 204 | std::vector<std::string> sha1s = { old_sha1 }; |
214 | ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); | 205 | ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); |
215 | } | 206 | } |
216 | 207 | ||
217 | TEST_F(ApplyPatchTest, CheckModeMultiple) { | 208 | TEST_F(ApplyPatchTest, CheckModeMultiple) { |
218 | char* argv[3] = { | 209 | std::vector<std::string> sha1s = { |
219 | &bad_sha1_a[0], | 210 | bad_sha1_a, |
220 | &old_sha1[0], | 211 | old_sha1, |
221 | &bad_sha1_b[0] | 212 | bad_sha1_b |
222 | }; | 213 | }; |
223 | ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); | 214 | ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); |
224 | } | 215 | } |
225 | 216 | ||
226 | TEST_F(ApplyPatchTest, CheckModeFailure) { | 217 | TEST_F(ApplyPatchTest, CheckModeFailure) { |
227 | char* argv[2] = { | 218 | std::vector<std::string> sha1s = { |
228 | &bad_sha1_a[0], | 219 | bad_sha1_a, |
229 | &bad_sha1_b[0] | 220 | bad_sha1_b |
230 | }; | 221 | }; |
231 | ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); | 222 | ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); |
232 | } | 223 | } |
233 | 224 | ||
234 | TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) { | 225 | TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedSingle) { |
235 | mangle_file(old_file); | 226 | mangle_file(old_file); |
236 | char* s = &old_sha1[0]; | 227 | std::vector<std::string> sha1s = { old_sha1 }; |
237 | ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); | 228 | ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); |
238 | } | 229 | } |
239 | 230 | ||
240 | TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) { | 231 | TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedMultiple) { |
241 | mangle_file(old_file); | 232 | mangle_file(old_file); |
242 | char* argv[3] = { | 233 | std::vector<std::string> sha1s = { |
243 | &bad_sha1_a[0], | 234 | bad_sha1_a, |
244 | &old_sha1[0], | 235 | old_sha1, |
245 | &bad_sha1_b[0] | 236 | bad_sha1_b |
246 | }; | 237 | }; |
247 | ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); | 238 | ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); |
248 | } | 239 | } |
249 | 240 | ||
250 | TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) { | 241 | TEST_F(ApplyPatchCacheTest, CheckCacheCorruptedFailure) { |
251 | mangle_file(old_file); | 242 | mangle_file(old_file); |
252 | char* argv[2] = { | 243 | std::vector<std::string> sha1s = { |
253 | &bad_sha1_a[0], | 244 | bad_sha1_a, |
254 | &bad_sha1_b[0] | 245 | bad_sha1_b |
255 | }; | 246 | }; |
256 | ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); | 247 | ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); |
257 | } | 248 | } |
258 | 249 | ||
259 | TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) { | 250 | TEST_F(ApplyPatchCacheTest, CheckCacheMissingSingle) { |
260 | unlink(&old_file[0]); | 251 | unlink(&old_file[0]); |
261 | char* s = &old_sha1[0]; | 252 | std::vector<std::string> sha1s = { old_sha1 }; |
262 | ASSERT_EQ(0, applypatch_check(&old_file[0], 1, &s)); | 253 | ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); |
263 | } | 254 | } |
264 | 255 | ||
265 | TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) { | 256 | TEST_F(ApplyPatchCacheTest, CheckCacheMissingMultiple) { |
266 | unlink(&old_file[0]); | 257 | unlink(&old_file[0]); |
267 | char* argv[3] = { | 258 | std::vector<std::string> sha1s = { |
268 | &bad_sha1_a[0], | 259 | bad_sha1_a, |
269 | &old_sha1[0], | 260 | old_sha1, |
270 | &bad_sha1_b[0] | 261 | bad_sha1_b |
271 | }; | 262 | }; |
272 | ASSERT_EQ(0, applypatch_check(&old_file[0], 3, argv)); | 263 | ASSERT_EQ(0, applypatch_check(&old_file[0], sha1s)); |
273 | } | 264 | } |
274 | 265 | ||
275 | TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) { | 266 | TEST_F(ApplyPatchCacheTest, CheckCacheMissingFailure) { |
276 | unlink(&old_file[0]); | 267 | unlink(&old_file[0]); |
277 | char* argv[2] = { | 268 | std::vector<std::string> sha1s = { |
278 | &bad_sha1_a[0], | 269 | bad_sha1_a, |
279 | &bad_sha1_b[0] | 270 | bad_sha1_b |
280 | }; | 271 | }; |
281 | ASSERT_NE(0, applypatch_check(&old_file[0], 2, argv)); | 272 | ASSERT_NE(0, applypatch_check(&old_file[0], sha1s)); |
282 | } | 273 | } |
283 | 274 | ||
284 | TEST_F(ApplyPatchFullTest, ApplyInPlace) { | 275 | TEST_F(ApplyPatchFullTest, ApplyInPlace) { |
285 | std::vector<char*> sha1s; | 276 | std::vector<std::string> sha1s = { |
286 | sha1s.push_back(&bad_sha1_a[0]); | 277 | bad_sha1_a, |
287 | sha1s.push_back(&old_sha1[0]); | 278 | old_sha1 |
288 | 279 | }; | |
289 | int ap_result = applypatch(&old_file[0], | 280 | int ap_result = applypatch(&old_file[0], |
290 | "-", | 281 | "-", |
291 | &new_sha1[0], | 282 | &new_sha1[0], |
292 | new_size, | 283 | new_size, |
293 | 2, | 284 | sha1s, |
294 | sha1s.data(), | ||
295 | patches.data(), | 285 | patches.data(), |
296 | nullptr); | 286 | nullptr); |
297 | ASSERT_EQ(0, ap_result); | 287 | ASSERT_EQ(0, ap_result); |
@@ -301,8 +291,7 @@ TEST_F(ApplyPatchFullTest, ApplyInPlace) { | |||
301 | "-", | 291 | "-", |
302 | &new_sha1[0], | 292 | &new_sha1[0], |
303 | new_size, | 293 | new_size, |
304 | 2, | 294 | sha1s, |
305 | sha1s.data(), | ||
306 | patches.data(), | 295 | patches.data(), |
307 | nullptr); | 296 | nullptr); |
308 | ASSERT_EQ(0, ap_result); | 297 | ASSERT_EQ(0, ap_result); |
@@ -310,15 +299,15 @@ TEST_F(ApplyPatchFullTest, ApplyInPlace) { | |||
310 | } | 299 | } |
311 | 300 | ||
312 | TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { | 301 | TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { |
313 | std::vector<char*> sha1s; | 302 | std::vector<std::string> sha1s = { |
314 | sha1s.push_back(&bad_sha1_a[0]); | 303 | bad_sha1_a, |
315 | sha1s.push_back(&old_sha1[0]); | 304 | old_sha1 |
305 | }; | ||
316 | int ap_result = applypatch(&old_file[0], | 306 | int ap_result = applypatch(&old_file[0], |
317 | &output_loc[0], | 307 | &output_loc[0], |
318 | &new_sha1[0], | 308 | &new_sha1[0], |
319 | new_size, | 309 | new_size, |
320 | 2, | 310 | sha1s, |
321 | sha1s.data(), | ||
322 | patches.data(), | 311 | patches.data(), |
323 | nullptr); | 312 | nullptr); |
324 | ASSERT_EQ(0, ap_result); | 313 | ASSERT_EQ(0, ap_result); |
@@ -327,8 +316,7 @@ TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { | |||
327 | &output_loc[0], | 316 | &output_loc[0], |
328 | &new_sha1[0], | 317 | &new_sha1[0], |
329 | new_size, | 318 | new_size, |
330 | 2, | 319 | sha1s, |
331 | sha1s.data(), | ||
332 | patches.data(), | 320 | patches.data(), |
333 | nullptr); | 321 | nullptr); |
334 | ASSERT_EQ(0, ap_result); | 322 | ASSERT_EQ(0, ap_result); |
@@ -337,15 +325,15 @@ TEST_F(ApplyPatchFullTest, ApplyInNewLocation) { | |||
337 | 325 | ||
338 | TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) { | 326 | TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) { |
339 | mangle_file(old_file); | 327 | mangle_file(old_file); |
340 | std::vector<char*> sha1s; | 328 | std::vector<std::string> sha1s = { |
341 | sha1s.push_back(&bad_sha1_a[0]); | 329 | bad_sha1_a, |
342 | sha1s.push_back(&old_sha1[0]); | 330 | old_sha1 |
331 | }; | ||
343 | int ap_result = applypatch(&old_file[0], | 332 | int ap_result = applypatch(&old_file[0], |
344 | &output_loc[0], | 333 | &output_loc[0], |
345 | &new_sha1[0], | 334 | &new_sha1[0], |
346 | new_size, | 335 | new_size, |
347 | 2, | 336 | sha1s, |
348 | sha1s.data(), | ||
349 | patches.data(), | 337 | patches.data(), |
350 | nullptr); | 338 | nullptr); |
351 | ASSERT_EQ(0, ap_result); | 339 | ASSERT_EQ(0, ap_result); |
@@ -354,8 +342,7 @@ TEST_F(ApplyPatchFullTest, ApplyCorruptedInNewLocation) { | |||
354 | &output_loc[0], | 342 | &output_loc[0], |
355 | &new_sha1[0], | 343 | &new_sha1[0], |
356 | new_size, | 344 | new_size, |
357 | 2, | 345 | sha1s, |
358 | sha1s.data(), | ||
359 | patches.data(), | 346 | patches.data(), |
360 | nullptr); | 347 | nullptr); |
361 | ASSERT_EQ(0, ap_result); | 348 | ASSERT_EQ(0, ap_result); |
@@ -366,15 +353,15 @@ TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) { | |||
366 | mangle_file(old_file); | 353 | mangle_file(old_file); |
367 | mangle_file(cache_file); | 354 | mangle_file(cache_file); |
368 | 355 | ||
369 | std::vector<char*> sha1s; | 356 | std::vector<std::string> sha1s = { |
370 | sha1s.push_back(&bad_sha1_a[0]); | 357 | bad_sha1_a, |
371 | sha1s.push_back(&old_sha1[0]); | 358 | old_sha1 |
359 | }; | ||
372 | int ap_result = applypatch(&old_file[0], | 360 | int ap_result = applypatch(&old_file[0], |
373 | &output_loc[0], | 361 | &output_loc[0], |
374 | &new_sha1[0], | 362 | &new_sha1[0], |
375 | new_size, | 363 | new_size, |
376 | 2, | 364 | sha1s, |
377 | sha1s.data(), | ||
378 | patches.data(), | 365 | patches.data(), |
379 | nullptr); | 366 | nullptr); |
380 | ASSERT_NE(0, ap_result); | 367 | ASSERT_NE(0, ap_result); |
@@ -383,8 +370,7 @@ TEST_F(ApplyPatchDoubleCacheTest, ApplyDoubleCorruptedInNewLocation) { | |||
383 | &output_loc[0], | 370 | &output_loc[0], |
384 | &new_sha1[0], | 371 | &new_sha1[0], |
385 | new_size, | 372 | new_size, |
386 | 2, | 373 | sha1s, |
387 | sha1s.data(), | ||
388 | patches.data(), | 374 | patches.data(), |
389 | nullptr); | 375 | nullptr); |
390 | ASSERT_NE(0, ap_result); | 376 | ASSERT_NE(0, ap_result); |
diff --git a/tests/component/edify_test.cpp b/tests/component/edify_test.cpp index a4dbb9fb..287e40cc 100644 --- a/tests/component/edify_test.cpp +++ b/tests/component/edify_test.cpp | |||
@@ -28,15 +28,15 @@ static void expect(const char* expr_str, const char* expected) { | |||
28 | 28 | ||
29 | State state(expr_str, nullptr); | 29 | State state(expr_str, nullptr); |
30 | 30 | ||
31 | char* result = Evaluate(&state, e); | 31 | std::string result; |
32 | bool status = Evaluate(&state, e, &result); | ||
32 | 33 | ||
33 | if (expected == nullptr) { | 34 | if (expected == nullptr) { |
34 | EXPECT_EQ(nullptr, result); | 35 | EXPECT_FALSE(status); |
35 | } else { | 36 | } else { |
36 | EXPECT_STREQ(expected, result); | 37 | EXPECT_STREQ(expected, result.c_str()); |
37 | } | 38 | } |
38 | 39 | ||
39 | free(result); | ||
40 | } | 40 | } |
41 | 41 | ||
42 | class EdifyTest : public ::testing::Test { | 42 | class EdifyTest : public ::testing::Test { |
diff --git a/tests/component/updater_test.cpp b/tests/component/updater_test.cpp index 64a6b37c..a859f11c 100644 --- a/tests/component/updater_test.cpp +++ b/tests/component/updater_test.cpp | |||
@@ -32,12 +32,13 @@ static void expect(const char* expected, const char* expr_str, CauseCode cause_c | |||
32 | 32 | ||
33 | State state(expr_str, nullptr); | 33 | State state(expr_str, nullptr); |
34 | 34 | ||
35 | char* result = Evaluate(&state, e); | 35 | std::string result; |
36 | bool status = Evaluate(&state, e, &result); | ||
36 | 37 | ||
37 | if (expected == nullptr) { | 38 | if (expected == nullptr) { |
38 | EXPECT_EQ(nullptr, result); | 39 | EXPECT_FALSE(status); |
39 | } else { | 40 | } else { |
40 | EXPECT_STREQ(expected, result); | 41 | EXPECT_STREQ(expected, result.c_str()); |
41 | } | 42 | } |
42 | 43 | ||
43 | // Error code is set in updater/updater.cpp only, by parsing State.errmsg. | 44 | // Error code is set in updater/updater.cpp only, by parsing State.errmsg. |
@@ -46,7 +47,6 @@ static void expect(const char* expected, const char* expr_str, CauseCode cause_c | |||
46 | // Cause code should always be available. | 47 | // Cause code should always be available. |
47 | EXPECT_EQ(cause_code, state.cause_code); | 48 | EXPECT_EQ(cause_code, state.cause_code); |
48 | 49 | ||
49 | free(result); | ||
50 | } | 50 | } |
51 | 51 | ||
52 | class UpdaterTest : public ::testing::Test { | 52 | class UpdaterTest : public ::testing::Test { |
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp index 433d9802..5f9b437f 100644 --- a/updater/blockimg.cpp +++ b/updater/blockimg.cpp | |||
@@ -1216,7 +1216,7 @@ static int PerformCommandDiff(CommandParameters& params) { | |||
1216 | 1216 | ||
1217 | size_t len; | 1217 | size_t len; |
1218 | if (!android::base::ParseUint(params.tokens[params.cpos++].c_str(), &len)) { | 1218 | if (!android::base::ParseUint(params.tokens[params.cpos++].c_str(), &len)) { |
1219 | fprintf(stderr, "invalid patch offset\n"); | 1219 | fprintf(stderr, "invalid patch len\n"); |
1220 | return -1; | 1220 | return -1; |
1221 | } | 1221 | } |
1222 | 1222 | ||
@@ -1248,10 +1248,8 @@ static int PerformCommandDiff(CommandParameters& params) { | |||
1248 | if (status == 0) { | 1248 | if (status == 0) { |
1249 | fprintf(stderr, "patching %zu blocks to %zu\n", blocks, tgt.size); | 1249 | fprintf(stderr, "patching %zu blocks to %zu\n", blocks, tgt.size); |
1250 | 1250 | ||
1251 | Value patch_value; | 1251 | Value patch_value(VAL_BLOB, |
1252 | patch_value.type = VAL_BLOB; | 1252 | std::string(reinterpret_cast<const char*>(params.patch_start + offset), len)); |
1253 | patch_value.size = len; | ||
1254 | patch_value.data = (char*) (params.patch_start + offset); | ||
1255 | 1253 | ||
1256 | RangeSinkState rss(tgt); | 1254 | RangeSinkState rss(tgt); |
1257 | rss.fd = params.fd; | 1255 | rss.fd = params.fd; |
@@ -1398,64 +1396,62 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg | |||
1398 | Value* patch_data_fn = nullptr; | 1396 | Value* patch_data_fn = nullptr; |
1399 | if (ReadValueArgs(state, argv, 4, &blockdev_filename, &transfer_list_value, | 1397 | if (ReadValueArgs(state, argv, 4, &blockdev_filename, &transfer_list_value, |
1400 | &new_data_fn, &patch_data_fn) < 0) { | 1398 | &new_data_fn, &patch_data_fn) < 0) { |
1401 | return StringValue(strdup("")); | 1399 | return StringValue(""); |
1402 | } | 1400 | } |
1403 | std::unique_ptr<Value, decltype(&FreeValue)> blockdev_filename_holder(blockdev_filename, | 1401 | std::unique_ptr<Value> blockdev_filename_holder(blockdev_filename); |
1404 | FreeValue); | 1402 | std::unique_ptr<Value> transfer_list_value_holder(transfer_list_value); |
1405 | std::unique_ptr<Value, decltype(&FreeValue)> transfer_list_value_holder(transfer_list_value, | 1403 | std::unique_ptr<Value> new_data_fn_holder(new_data_fn); |
1406 | FreeValue); | 1404 | std::unique_ptr<Value> patch_data_fn_holder(patch_data_fn); |
1407 | std::unique_ptr<Value, decltype(&FreeValue)> new_data_fn_holder(new_data_fn, FreeValue); | ||
1408 | std::unique_ptr<Value, decltype(&FreeValue)> patch_data_fn_holder(patch_data_fn, FreeValue); | ||
1409 | 1405 | ||
1410 | if (blockdev_filename->type != VAL_STRING) { | 1406 | if (blockdev_filename->type != VAL_STRING) { |
1411 | ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string", | 1407 | ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string", |
1412 | name); | 1408 | name); |
1413 | return StringValue(strdup("")); | 1409 | return StringValue(""); |
1414 | } | 1410 | } |
1415 | if (transfer_list_value->type != VAL_BLOB) { | 1411 | if (transfer_list_value->type != VAL_BLOB) { |
1416 | ErrorAbort(state, kArgsParsingFailure, "transfer_list argument to %s must be blob", name); | 1412 | ErrorAbort(state, kArgsParsingFailure, "transfer_list argument to %s must be blob", name); |
1417 | return StringValue(strdup("")); | 1413 | return StringValue(""); |
1418 | } | 1414 | } |
1419 | if (new_data_fn->type != VAL_STRING) { | 1415 | if (new_data_fn->type != VAL_STRING) { |
1420 | ErrorAbort(state, kArgsParsingFailure, "new_data_fn argument to %s must be string", name); | 1416 | ErrorAbort(state, kArgsParsingFailure, "new_data_fn argument to %s must be string", name); |
1421 | return StringValue(strdup("")); | 1417 | return StringValue(""); |
1422 | } | 1418 | } |
1423 | if (patch_data_fn->type != VAL_STRING) { | 1419 | if (patch_data_fn->type != VAL_STRING) { |
1424 | ErrorAbort(state, kArgsParsingFailure, "patch_data_fn argument to %s must be string", | 1420 | ErrorAbort(state, kArgsParsingFailure, "patch_data_fn argument to %s must be string", |
1425 | name); | 1421 | name); |
1426 | return StringValue(strdup("")); | 1422 | return StringValue(""); |
1427 | } | 1423 | } |
1428 | 1424 | ||
1429 | UpdaterInfo* ui = reinterpret_cast<UpdaterInfo*>(state->cookie); | 1425 | UpdaterInfo* ui = reinterpret_cast<UpdaterInfo*>(state->cookie); |
1430 | 1426 | ||
1431 | if (ui == nullptr) { | 1427 | if (ui == nullptr) { |
1432 | return StringValue(strdup("")); | 1428 | return StringValue(""); |
1433 | } | 1429 | } |
1434 | 1430 | ||
1435 | FILE* cmd_pipe = ui->cmd_pipe; | 1431 | FILE* cmd_pipe = ui->cmd_pipe; |
1436 | ZipArchive* za = ui->package_zip; | 1432 | ZipArchive* za = ui->package_zip; |
1437 | 1433 | ||
1438 | if (cmd_pipe == nullptr || za == nullptr) { | 1434 | if (cmd_pipe == nullptr || za == nullptr) { |
1439 | return StringValue(strdup("")); | 1435 | return StringValue(""); |
1440 | } | 1436 | } |
1441 | 1437 | ||
1442 | const ZipEntry* patch_entry = mzFindZipEntry(za, patch_data_fn->data); | 1438 | const ZipEntry* patch_entry = mzFindZipEntry(za, patch_data_fn->data.c_str()); |
1443 | if (patch_entry == nullptr) { | 1439 | if (patch_entry == nullptr) { |
1444 | fprintf(stderr, "%s(): no file \"%s\" in package", name, patch_data_fn->data); | 1440 | fprintf(stderr, "%s(): no file \"%s\" in package", name, patch_data_fn->data.c_str()); |
1445 | return StringValue(strdup("")); | 1441 | return StringValue(""); |
1446 | } | 1442 | } |
1447 | 1443 | ||
1448 | params.patch_start = ui->package_zip_addr + mzGetZipEntryOffset(patch_entry); | 1444 | params.patch_start = ui->package_zip_addr + mzGetZipEntryOffset(patch_entry); |
1449 | const ZipEntry* new_entry = mzFindZipEntry(za, new_data_fn->data); | 1445 | const ZipEntry* new_entry = mzFindZipEntry(za, new_data_fn->data.c_str()); |
1450 | if (new_entry == nullptr) { | 1446 | if (new_entry == nullptr) { |
1451 | fprintf(stderr, "%s(): no file \"%s\" in package", name, new_data_fn->data); | 1447 | fprintf(stderr, "%s(): no file \"%s\" in package", name, new_data_fn->data.c_str()); |
1452 | return StringValue(strdup("")); | 1448 | return StringValue(""); |
1453 | } | 1449 | } |
1454 | 1450 | ||
1455 | params.fd.reset(TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data, O_RDWR))); | 1451 | params.fd.reset(TEMP_FAILURE_RETRY(ota_open(blockdev_filename->data.c_str(), O_RDWR))); |
1456 | if (params.fd == -1) { | 1452 | if (params.fd == -1) { |
1457 | fprintf(stderr, "open \"%s\" failed: %s\n", blockdev_filename->data, strerror(errno)); | 1453 | fprintf(stderr, "open \"%s\" failed: %s\n", blockdev_filename->data.c_str(), strerror(errno)); |
1458 | return StringValue(strdup("")); | 1454 | return StringValue(""); |
1459 | } | 1455 | } |
1460 | 1456 | ||
1461 | if (params.canwrite) { | 1457 | if (params.canwrite) { |
@@ -1471,24 +1467,21 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg | |||
1471 | int error = pthread_create(¶ms.thread, &attr, unzip_new_data, ¶ms.nti); | 1467 | int error = pthread_create(¶ms.thread, &attr, unzip_new_data, ¶ms.nti); |
1472 | if (error != 0) { | 1468 | if (error != 0) { |
1473 | fprintf(stderr, "pthread_create failed: %s\n", strerror(error)); | 1469 | fprintf(stderr, "pthread_create failed: %s\n", strerror(error)); |
1474 | return StringValue(strdup("")); | 1470 | return StringValue(""); |
1475 | } | 1471 | } |
1476 | } | 1472 | } |
1477 | 1473 | ||
1478 | // Copy all the lines in transfer_list_value into std::string for | 1474 | std::vector<std::string> lines = android::base::Split(transfer_list_value->data, "\n"); |
1479 | // processing. | ||
1480 | const std::string transfer_list(transfer_list_value->data, transfer_list_value->size); | ||
1481 | std::vector<std::string> lines = android::base::Split(transfer_list, "\n"); | ||
1482 | if (lines.size() < 2) { | 1475 | if (lines.size() < 2) { |
1483 | ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zd]\n", | 1476 | ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zd]\n", |
1484 | lines.size()); | 1477 | lines.size()); |
1485 | return StringValue(strdup("")); | 1478 | return StringValue(""); |
1486 | } | 1479 | } |
1487 | 1480 | ||
1488 | // First line in transfer list is the version number | 1481 | // First line in transfer list is the version number |
1489 | if (!android::base::ParseInt(lines[0].c_str(), ¶ms.version, 1, 4)) { | 1482 | if (!android::base::ParseInt(lines[0].c_str(), ¶ms.version, 1, 4)) { |
1490 | fprintf(stderr, "unexpected transfer list version [%s]\n", lines[0].c_str()); | 1483 | fprintf(stderr, "unexpected transfer list version [%s]\n", lines[0].c_str()); |
1491 | return StringValue(strdup("")); | 1484 | return StringValue(""); |
1492 | } | 1485 | } |
1493 | 1486 | ||
1494 | fprintf(stderr, "blockimg version is %d\n", params.version); | 1487 | fprintf(stderr, "blockimg version is %d\n", params.version); |
@@ -1497,11 +1490,11 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg | |||
1497 | int total_blocks; | 1490 | int total_blocks; |
1498 | if (!android::base::ParseInt(lines[1].c_str(), &total_blocks, 0)) { | 1491 | if (!android::base::ParseInt(lines[1].c_str(), &total_blocks, 0)) { |
1499 | ErrorAbort(state, kArgsParsingFailure, "unexpected block count [%s]\n", lines[1].c_str()); | 1492 | ErrorAbort(state, kArgsParsingFailure, "unexpected block count [%s]\n", lines[1].c_str()); |
1500 | return StringValue(strdup("")); | 1493 | return StringValue(""); |
1501 | } | 1494 | } |
1502 | 1495 | ||
1503 | if (total_blocks == 0) { | 1496 | if (total_blocks == 0) { |
1504 | return StringValue(strdup("t")); | 1497 | return StringValue("t"); |
1505 | } | 1498 | } |
1506 | 1499 | ||
1507 | size_t start = 2; | 1500 | size_t start = 2; |
@@ -1509,7 +1502,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg | |||
1509 | if (lines.size() < 4) { | 1502 | if (lines.size() < 4) { |
1510 | ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zu]\n", | 1503 | ErrorAbort(state, kArgsParsingFailure, "too few lines in the transfer list [%zu]\n", |
1511 | lines.size()); | 1504 | lines.size()); |
1512 | return StringValue(strdup("")); | 1505 | return StringValue(""); |
1513 | } | 1506 | } |
1514 | 1507 | ||
1515 | // Third line is how many stash entries are needed simultaneously | 1508 | // Third line is how many stash entries are needed simultaneously |
@@ -1520,12 +1513,12 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg | |||
1520 | if (!android::base::ParseInt(lines[3].c_str(), &stash_max_blocks, 0)) { | 1513 | if (!android::base::ParseInt(lines[3].c_str(), &stash_max_blocks, 0)) { |
1521 | ErrorAbort(state, kArgsParsingFailure, "unexpected maximum stash blocks [%s]\n", | 1514 | ErrorAbort(state, kArgsParsingFailure, "unexpected maximum stash blocks [%s]\n", |
1522 | lines[3].c_str()); | 1515 | lines[3].c_str()); |
1523 | return StringValue(strdup("")); | 1516 | return StringValue(""); |
1524 | } | 1517 | } |
1525 | 1518 | ||
1526 | int res = CreateStash(state, stash_max_blocks, blockdev_filename->data, params.stashbase); | 1519 | int res = CreateStash(state, stash_max_blocks, blockdev_filename->data.c_str(), params.stashbase); |
1527 | if (res == -1) { | 1520 | if (res == -1) { |
1528 | return StringValue(strdup("")); | 1521 | return StringValue(""); |
1529 | } | 1522 | } |
1530 | 1523 | ||
1531 | params.createdstash = res; | 1524 | params.createdstash = res; |
@@ -1589,7 +1582,7 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg | |||
1589 | fprintf(stderr, "stashed %zu blocks\n", params.stashed); | 1582 | fprintf(stderr, "stashed %zu blocks\n", params.stashed); |
1590 | fprintf(stderr, "max alloc needed was %zu\n", params.buffer.size()); | 1583 | fprintf(stderr, "max alloc needed was %zu\n", params.buffer.size()); |
1591 | 1584 | ||
1592 | const char* partition = strrchr(blockdev_filename->data, '/'); | 1585 | const char* partition = strrchr(blockdev_filename->data.c_str(), '/'); |
1593 | if (partition != nullptr && *(partition+1) != 0) { | 1586 | if (partition != nullptr && *(partition+1) != 0) { |
1594 | fprintf(cmd_pipe, "log bytes_written_%s: %zu\n", partition + 1, | 1587 | fprintf(cmd_pipe, "log bytes_written_%s: %zu\n", partition + 1, |
1595 | params.written * BLOCKSIZE); | 1588 | params.written * BLOCKSIZE); |
@@ -1623,7 +1616,7 @@ pbiudone: | |||
1623 | state->cause_code = failure_type; | 1616 | state->cause_code = failure_type; |
1624 | } | 1617 | } |
1625 | 1618 | ||
1626 | return StringValue(rc == 0 ? strdup("t") : strdup("")); | 1619 | return StringValue(rc == 0 ? "t" : ""); |
1627 | } | 1620 | } |
1628 | 1621 | ||
1629 | // The transfer list is a text file containing commands to | 1622 | // The transfer list is a text file containing commands to |
@@ -1721,27 +1714,26 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[]) | |||
1721 | Value* ranges; | 1714 | Value* ranges; |
1722 | 1715 | ||
1723 | if (ReadValueArgs(state, argv, 2, &blockdev_filename, &ranges) < 0) { | 1716 | if (ReadValueArgs(state, argv, 2, &blockdev_filename, &ranges) < 0) { |
1724 | return StringValue(strdup("")); | 1717 | return StringValue(""); |
1725 | } | 1718 | } |
1726 | std::unique_ptr<Value, decltype(&FreeValue)> ranges_holder(ranges, FreeValue); | 1719 | std::unique_ptr<Value> ranges_holder(ranges); |
1727 | std::unique_ptr<Value, decltype(&FreeValue)> blockdev_filename_holder(blockdev_filename, | 1720 | std::unique_ptr<Value> blockdev_filename_holder(blockdev_filename); |
1728 | FreeValue); | ||
1729 | 1721 | ||
1730 | if (blockdev_filename->type != VAL_STRING) { | 1722 | if (blockdev_filename->type != VAL_STRING) { |
1731 | ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string", | 1723 | ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string", |
1732 | name); | 1724 | name); |
1733 | return StringValue(strdup("")); | 1725 | return StringValue(""); |
1734 | } | 1726 | } |
1735 | if (ranges->type != VAL_STRING) { | 1727 | if (ranges->type != VAL_STRING) { |
1736 | ErrorAbort(state, kArgsParsingFailure, "ranges argument to %s must be string", name); | 1728 | ErrorAbort(state, kArgsParsingFailure, "ranges argument to %s must be string", name); |
1737 | return StringValue(strdup("")); | 1729 | return StringValue(""); |
1738 | } | 1730 | } |
1739 | 1731 | ||
1740 | android::base::unique_fd fd(ota_open(blockdev_filename->data, O_RDWR)); | 1732 | android::base::unique_fd fd(ota_open(blockdev_filename->data.c_str(), O_RDWR)); |
1741 | if (fd == -1) { | 1733 | if (fd == -1) { |
1742 | ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", blockdev_filename->data, | 1734 | ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", |
1743 | strerror(errno)); | 1735 | blockdev_filename->data.c_str(), strerror(errno)); |
1744 | return StringValue(strdup("")); | 1736 | return StringValue(""); |
1745 | } | 1737 | } |
1746 | 1738 | ||
1747 | RangeSet rs; | 1739 | RangeSet rs; |
@@ -1753,16 +1745,16 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[]) | |||
1753 | std::vector<uint8_t> buffer(BLOCKSIZE); | 1745 | std::vector<uint8_t> buffer(BLOCKSIZE); |
1754 | for (size_t i = 0; i < rs.count; ++i) { | 1746 | for (size_t i = 0; i < rs.count; ++i) { |
1755 | if (!check_lseek(fd, (off64_t)rs.pos[i*2] * BLOCKSIZE, SEEK_SET)) { | 1747 | if (!check_lseek(fd, (off64_t)rs.pos[i*2] * BLOCKSIZE, SEEK_SET)) { |
1756 | ErrorAbort(state, kLseekFailure, "failed to seek %s: %s", blockdev_filename->data, | 1748 | ErrorAbort(state, kLseekFailure, "failed to seek %s: %s", |
1757 | strerror(errno)); | 1749 | blockdev_filename->data.c_str(), strerror(errno)); |
1758 | return StringValue(strdup("")); | 1750 | return StringValue(""); |
1759 | } | 1751 | } |
1760 | 1752 | ||
1761 | for (size_t j = rs.pos[i*2]; j < rs.pos[i*2+1]; ++j) { | 1753 | for (size_t j = rs.pos[i*2]; j < rs.pos[i*2+1]; ++j) { |
1762 | if (read_all(fd, buffer, BLOCKSIZE) == -1) { | 1754 | if (read_all(fd, buffer, BLOCKSIZE) == -1) { |
1763 | ErrorAbort(state, kFreadFailure, "failed to read %s: %s", blockdev_filename->data, | 1755 | ErrorAbort(state, kFreadFailure, "failed to read %s: %s", |
1764 | strerror(errno)); | 1756 | blockdev_filename->data.c_str(), strerror(errno)); |
1765 | return StringValue(strdup("")); | 1757 | return StringValue(""); |
1766 | } | 1758 | } |
1767 | 1759 | ||
1768 | SHA1_Update(&ctx, buffer.data(), BLOCKSIZE); | 1760 | SHA1_Update(&ctx, buffer.data(), BLOCKSIZE); |
@@ -1771,7 +1763,7 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[]) | |||
1771 | uint8_t digest[SHA_DIGEST_LENGTH]; | 1763 | uint8_t digest[SHA_DIGEST_LENGTH]; |
1772 | SHA1_Final(digest, &ctx); | 1764 | SHA1_Final(digest, &ctx); |
1773 | 1765 | ||
1774 | return StringValue(strdup(print_sha1(digest).c_str())); | 1766 | return StringValue(print_sha1(digest)); |
1775 | } | 1767 | } |
1776 | 1768 | ||
1777 | // This function checks if a device has been remounted R/W prior to an incremental | 1769 | // This function checks if a device has been remounted R/W prior to an incremental |
@@ -1785,27 +1777,27 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[]) | |||
1785 | if (ReadValueArgs(state, argv, 1, &arg_filename) < 0) { | 1777 | if (ReadValueArgs(state, argv, 1, &arg_filename) < 0) { |
1786 | return nullptr; | 1778 | return nullptr; |
1787 | } | 1779 | } |
1788 | std::unique_ptr<Value, decltype(&FreeValue)> filename(arg_filename, FreeValue); | 1780 | std::unique_ptr<Value> filename(arg_filename); |
1789 | 1781 | ||
1790 | if (filename->type != VAL_STRING) { | 1782 | if (filename->type != VAL_STRING) { |
1791 | ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name); | 1783 | ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name); |
1792 | return StringValue(strdup("")); | 1784 | return StringValue(""); |
1793 | } | 1785 | } |
1794 | 1786 | ||
1795 | android::base::unique_fd fd(ota_open(arg_filename->data, O_RDONLY)); | 1787 | android::base::unique_fd fd(ota_open(arg_filename->data.c_str(), O_RDONLY)); |
1796 | if (fd == -1) { | 1788 | if (fd == -1) { |
1797 | ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", arg_filename->data, | 1789 | ErrorAbort(state, kFileOpenFailure, "open \"%s\" failed: %s", arg_filename->data.c_str(), |
1798 | strerror(errno)); | 1790 | strerror(errno)); |
1799 | return StringValue(strdup("")); | 1791 | return StringValue(""); |
1800 | } | 1792 | } |
1801 | 1793 | ||
1802 | RangeSet blk0 {1 /*count*/, 1/*size*/, std::vector<size_t> {0, 1}/*position*/}; | 1794 | RangeSet blk0 {1 /*count*/, 1/*size*/, std::vector<size_t> {0, 1}/*position*/}; |
1803 | std::vector<uint8_t> block0_buffer(BLOCKSIZE); | 1795 | std::vector<uint8_t> block0_buffer(BLOCKSIZE); |
1804 | 1796 | ||
1805 | if (ReadBlocks(blk0, block0_buffer, fd) == -1) { | 1797 | if (ReadBlocks(blk0, block0_buffer, fd) == -1) { |
1806 | ErrorAbort(state, kFreadFailure, "failed to read %s: %s", arg_filename->data, | 1798 | ErrorAbort(state, kFreadFailure, "failed to read %s: %s", arg_filename->data.c_str(), |
1807 | strerror(errno)); | 1799 | strerror(errno)); |
1808 | return StringValue(strdup("")); | 1800 | return StringValue(""); |
1809 | } | 1801 | } |
1810 | 1802 | ||
1811 | // https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout | 1803 | // https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout |
@@ -1823,7 +1815,7 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[]) | |||
1823 | uiPrintf(state, "Last remount happened on %s", ctime(&mount_time)); | 1815 | uiPrintf(state, "Last remount happened on %s", ctime(&mount_time)); |
1824 | } | 1816 | } |
1825 | 1817 | ||
1826 | return StringValue(strdup("t")); | 1818 | return StringValue("t"); |
1827 | } | 1819 | } |
1828 | 1820 | ||
1829 | 1821 | ||
@@ -1835,40 +1827,40 @@ Value* BlockImageRecoverFn(const char* name, State* state, int argc, Expr* argv[ | |||
1835 | return NULL; | 1827 | return NULL; |
1836 | } | 1828 | } |
1837 | 1829 | ||
1838 | std::unique_ptr<Value, decltype(&FreeValue)> filename(arg_filename, FreeValue); | 1830 | std::unique_ptr<Value> filename(arg_filename); |
1839 | std::unique_ptr<Value, decltype(&FreeValue)> ranges(arg_ranges, FreeValue); | 1831 | std::unique_ptr<Value> ranges(arg_ranges); |
1840 | 1832 | ||
1841 | if (filename->type != VAL_STRING) { | 1833 | if (filename->type != VAL_STRING) { |
1842 | ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name); | 1834 | ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name); |
1843 | return StringValue(strdup("")); | 1835 | return StringValue(""); |
1844 | } | 1836 | } |
1845 | if (ranges->type != VAL_STRING) { | 1837 | if (ranges->type != VAL_STRING) { |
1846 | ErrorAbort(state, kArgsParsingFailure, "ranges argument to %s must be string", name); | 1838 | ErrorAbort(state, kArgsParsingFailure, "ranges argument to %s must be string", name); |
1847 | return StringValue(strdup("")); | 1839 | return StringValue(""); |
1848 | } | 1840 | } |
1849 | 1841 | ||
1850 | // Output notice to log when recover is attempted | 1842 | // Output notice to log when recover is attempted |
1851 | fprintf(stderr, "%s image corrupted, attempting to recover...\n", filename->data); | 1843 | fprintf(stderr, "%s image corrupted, attempting to recover...\n", filename->data.c_str()); |
1852 | 1844 | ||
1853 | // When opened with O_RDWR, libfec rewrites corrupted blocks when they are read | 1845 | // When opened with O_RDWR, libfec rewrites corrupted blocks when they are read |
1854 | fec::io fh(filename->data, O_RDWR); | 1846 | fec::io fh(filename->data.c_str(), O_RDWR); |
1855 | 1847 | ||
1856 | if (!fh) { | 1848 | if (!fh) { |
1857 | ErrorAbort(state, kLibfecFailure, "fec_open \"%s\" failed: %s", filename->data, | 1849 | ErrorAbort(state, kLibfecFailure, "fec_open \"%s\" failed: %s", filename->data.c_str(), |
1858 | strerror(errno)); | 1850 | strerror(errno)); |
1859 | return StringValue(strdup("")); | 1851 | return StringValue(""); |
1860 | } | 1852 | } |
1861 | 1853 | ||
1862 | if (!fh.has_ecc() || !fh.has_verity()) { | 1854 | if (!fh.has_ecc() || !fh.has_verity()) { |
1863 | ErrorAbort(state, kLibfecFailure, "unable to use metadata to correct errors"); | 1855 | ErrorAbort(state, kLibfecFailure, "unable to use metadata to correct errors"); |
1864 | return StringValue(strdup("")); | 1856 | return StringValue(""); |
1865 | } | 1857 | } |
1866 | 1858 | ||
1867 | fec_status status; | 1859 | fec_status status; |
1868 | 1860 | ||
1869 | if (!fh.get_status(status)) { | 1861 | if (!fh.get_status(status)) { |
1870 | ErrorAbort(state, kLibfecFailure, "failed to read FEC status"); | 1862 | ErrorAbort(state, kLibfecFailure, "failed to read FEC status"); |
1871 | return StringValue(strdup("")); | 1863 | return StringValue(""); |
1872 | } | 1864 | } |
1873 | 1865 | ||
1874 | RangeSet rs; | 1866 | RangeSet rs; |
@@ -1885,8 +1877,8 @@ Value* BlockImageRecoverFn(const char* name, State* state, int argc, Expr* argv[ | |||
1885 | 1877 | ||
1886 | if (fh.pread(buffer, BLOCKSIZE, (off64_t)j * BLOCKSIZE) != BLOCKSIZE) { | 1878 | if (fh.pread(buffer, BLOCKSIZE, (off64_t)j * BLOCKSIZE) != BLOCKSIZE) { |
1887 | ErrorAbort(state, kLibfecFailure, "failed to recover %s (block %zu): %s", | 1879 | ErrorAbort(state, kLibfecFailure, "failed to recover %s (block %zu): %s", |
1888 | filename->data, j, strerror(errno)); | 1880 | filename->data.c_str(), j, strerror(errno)); |
1889 | return StringValue(strdup("")); | 1881 | return StringValue(""); |
1890 | } | 1882 | } |
1891 | 1883 | ||
1892 | // If we want to be able to recover from a situation where rewriting a corrected | 1884 | // If we want to be able to recover from a situation where rewriting a corrected |
@@ -1901,8 +1893,8 @@ Value* BlockImageRecoverFn(const char* name, State* state, int argc, Expr* argv[ | |||
1901 | // read and check if the errors field value has increased. | 1893 | // read and check if the errors field value has increased. |
1902 | } | 1894 | } |
1903 | } | 1895 | } |
1904 | fprintf(stderr, "...%s image recovered successfully.\n", filename->data); | 1896 | fprintf(stderr, "...%s image recovered successfully.\n", filename->data.c_str()); |
1905 | return StringValue(strdup("t")); | 1897 | return StringValue("t"); |
1906 | } | 1898 | } |
1907 | 1899 | ||
1908 | void RegisterBlockImageFunctions() { | 1900 | void RegisterBlockImageFunctions() { |
diff --git a/updater/install.cpp b/updater/install.cpp index 3546968d..d723b388 100644 --- a/updater/install.cpp +++ b/updater/install.cpp | |||
@@ -116,7 +116,7 @@ static int make_parents(char* name) { | |||
116 | // | 116 | // |
117 | // fs_type="ext4" partition_type="EMMC" location=device | 117 | // fs_type="ext4" partition_type="EMMC" location=device |
118 | Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) { | 118 | Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) { |
119 | char* result = NULL; | 119 | char* result = nullptr; |
120 | if (argc != 4 && argc != 5) { | 120 | if (argc != 4 && argc != 5) { |
121 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 4-5 args, got %d", name, argc); | 121 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 4-5 args, got %d", name, argc); |
122 | } | 122 | } |
@@ -197,7 +197,7 @@ done: | |||
197 | 197 | ||
198 | // is_mounted(mount_point) | 198 | // is_mounted(mount_point) |
199 | Value* IsMountedFn(const char* name, State* state, int argc, Expr* argv[]) { | 199 | Value* IsMountedFn(const char* name, State* state, int argc, Expr* argv[]) { |
200 | char* result = NULL; | 200 | char* result = nullptr; |
201 | if (argc != 1) { | 201 | if (argc != 1) { |
202 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %d", name, argc); | 202 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %d", name, argc); |
203 | } | 203 | } |
@@ -227,7 +227,7 @@ done: | |||
227 | 227 | ||
228 | 228 | ||
229 | Value* UnmountFn(const char* name, State* state, int argc, Expr* argv[]) { | 229 | Value* UnmountFn(const char* name, State* state, int argc, Expr* argv[]) { |
230 | char* result = NULL; | 230 | char* result = nullptr; |
231 | if (argc != 1) { | 231 | if (argc != 1) { |
232 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %d", name, argc); | 232 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %d", name, argc); |
233 | } | 233 | } |
@@ -284,7 +284,7 @@ static int exec_cmd(const char* path, char* const argv[]) { | |||
284 | // if fs_size > 0, that is the size to use | 284 | // if fs_size > 0, that is the size to use |
285 | // if fs_size < 0, then reserve that many bytes at the end of the partition (not for "f2fs") | 285 | // if fs_size < 0, then reserve that many bytes at the end of the partition (not for "f2fs") |
286 | Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { | 286 | Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { |
287 | char* result = NULL; | 287 | char* result = nullptr; |
288 | if (argc != 5) { | 288 | if (argc != 5) { |
289 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 5 args, got %d", name, argc); | 289 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 5 args, got %d", name, argc); |
290 | } | 290 | } |
@@ -358,7 +358,7 @@ done: | |||
358 | } | 358 | } |
359 | 359 | ||
360 | Value* RenameFn(const char* name, State* state, int argc, Expr* argv[]) { | 360 | Value* RenameFn(const char* name, State* state, int argc, Expr* argv[]) { |
361 | char* result = NULL; | 361 | char* result = nullptr; |
362 | if (argc != 2) { | 362 | if (argc != 2) { |
363 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %d", name, argc); | 363 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 2 args, got %d", name, argc); |
364 | } | 364 | } |
@@ -397,15 +397,10 @@ done: | |||
397 | } | 397 | } |
398 | 398 | ||
399 | Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) { | 399 | Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) { |
400 | char** paths = reinterpret_cast<char**>(malloc(argc * sizeof(char*))); | 400 | std::vector<std::string> paths; |
401 | for (int i = 0; i < argc; ++i) { | 401 | for (int i = 0; i < argc; ++i) { |
402 | paths[i] = Evaluate(state, argv[i]); | 402 | if (!Evaluate(state, argv[i], &paths[i])) { |
403 | if (paths[i] == NULL) { | 403 | return nullptr; |
404 | for (int j = 0; j < i; ++j) { | ||
405 | free(paths[j]); | ||
406 | } | ||
407 | free(paths); | ||
408 | return NULL; | ||
409 | } | 404 | } |
410 | } | 405 | } |
411 | 406 | ||
@@ -413,15 +408,12 @@ Value* DeleteFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
413 | 408 | ||
414 | int success = 0; | 409 | int success = 0; |
415 | for (int i = 0; i < argc; ++i) { | 410 | for (int i = 0; i < argc; ++i) { |
416 | if ((recursive ? dirUnlinkHierarchy(paths[i]) : unlink(paths[i])) == 0) | 411 | if ((recursive ? dirUnlinkHierarchy(paths[i].c_str()) : unlink(paths[i].c_str())) == 0) { |
417 | ++success; | 412 | ++success; |
418 | free(paths[i]); | 413 | } |
419 | } | 414 | } |
420 | free(paths); | ||
421 | 415 | ||
422 | char buffer[10]; | 416 | return StringValue(android::base::StringPrintf("%d", success)); |
423 | sprintf(buffer, "%d", success); | ||
424 | return StringValue(strdup(buffer)); | ||
425 | } | 417 | } |
426 | 418 | ||
427 | 419 | ||
@@ -483,7 +475,7 @@ Value* PackageExtractDirFn(const char* name, State* state, | |||
483 | NULL, NULL, sehandle); | 475 | NULL, NULL, sehandle); |
484 | free(zip_path); | 476 | free(zip_path); |
485 | free(dest_path); | 477 | free(dest_path); |
486 | return StringValue(strdup(success ? "t" : "")); | 478 | return StringValue(success ? "t" : ""); |
487 | } | 479 | } |
488 | 480 | ||
489 | 481 | ||
@@ -536,7 +528,7 @@ Value* PackageExtractFileFn(const char* name, State* state, | |||
536 | done2: | 528 | done2: |
537 | free(zip_path); | 529 | free(zip_path); |
538 | free(dest_path); | 530 | free(dest_path); |
539 | return StringValue(strdup(success ? "t" : "")); | 531 | return StringValue(success ? "t" : ""); |
540 | } else { | 532 | } else { |
541 | // The one-argument version returns the contents of the file | 533 | // The one-argument version returns the contents of the file |
542 | // as the result. | 534 | // as the result. |
@@ -544,10 +536,7 @@ Value* PackageExtractFileFn(const char* name, State* state, | |||
544 | char* zip_path; | 536 | char* zip_path; |
545 | if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL; | 537 | if (ReadArgs(state, argv, 1, &zip_path) < 0) return NULL; |
546 | 538 | ||
547 | Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value))); | 539 | Value* v = new Value(VAL_INVALID, ""); |
548 | v->type = VAL_BLOB; | ||
549 | v->size = -1; | ||
550 | v->data = NULL; | ||
551 | 540 | ||
552 | ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip; | 541 | ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip; |
553 | const ZipEntry* entry = mzFindZipEntry(za, zip_path); | 542 | const ZipEntry* entry = mzFindZipEntry(za, zip_path); |
@@ -556,23 +545,16 @@ Value* PackageExtractFileFn(const char* name, State* state, | |||
556 | goto done1; | 545 | goto done1; |
557 | } | 546 | } |
558 | 547 | ||
559 | v->size = mzGetZipEntryUncompLen(entry); | 548 | v->data.resize(mzGetZipEntryUncompLen(entry)); |
560 | v->data = reinterpret_cast<char*>(malloc(v->size)); | ||
561 | if (v->data == NULL) { | ||
562 | printf("%s: failed to allocate %zd bytes for %s\n", | ||
563 | name, v->size, zip_path); | ||
564 | goto done1; | ||
565 | } | ||
566 | |||
567 | success = mzExtractZipEntryToBuffer(za, entry, | 549 | success = mzExtractZipEntryToBuffer(za, entry, |
568 | (unsigned char *)v->data); | 550 | reinterpret_cast<unsigned char *>(&v->data[0])); |
569 | 551 | ||
570 | done1: | 552 | done1: |
571 | free(zip_path); | 553 | free(zip_path); |
572 | if (!success) { | 554 | if (!success) { |
573 | free(v->data); | 555 | v->data.clear(); |
574 | v->data = NULL; | 556 | } else { |
575 | v->size = -1; | 557 | v->type = VAL_BLOB; |
576 | } | 558 | } |
577 | return v; | 559 | return v; |
578 | } | 560 | } |
@@ -584,13 +566,13 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
584 | if (argc == 0) { | 566 | if (argc == 0) { |
585 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1+ args, got %d", name, argc); | 567 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1+ args, got %d", name, argc); |
586 | } | 568 | } |
587 | char* target; | 569 | std::string target; |
588 | target = Evaluate(state, argv[0]); | 570 | if (!Evaluate(state, argv[0], &target)) { |
589 | if (target == NULL) return NULL; | 571 | return nullptr; |
572 | } | ||
590 | 573 | ||
591 | char** srcs = ReadVarArgs(state, argc-1, argv+1); | 574 | char** srcs = ReadVarArgs(state, argc-1, argv+1); |
592 | if (srcs == NULL) { | 575 | if (srcs == NULL) { |
593 | free(target); | ||
594 | return NULL; | 576 | return NULL; |
595 | } | 577 | } |
596 | 578 | ||
@@ -606,12 +588,12 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
606 | } | 588 | } |
607 | if (make_parents(srcs[i])) { | 589 | if (make_parents(srcs[i])) { |
608 | printf("%s: failed to symlink %s to %s: making parents failed\n", | 590 | printf("%s: failed to symlink %s to %s: making parents failed\n", |
609 | name, srcs[i], target); | 591 | name, srcs[i], target.c_str()); |
610 | ++bad; | 592 | ++bad; |
611 | } | 593 | } |
612 | if (symlink(target, srcs[i]) < 0) { | 594 | if (symlink(target.c_str(), srcs[i]) < 0) { |
613 | printf("%s: failed to symlink %s to %s: %s\n", | 595 | printf("%s: failed to symlink %s to %s: %s\n", |
614 | name, srcs[i], target, strerror(errno)); | 596 | name, srcs[i], target.c_str(), strerror(errno)); |
615 | ++bad; | 597 | ++bad; |
616 | } | 598 | } |
617 | free(srcs[i]); | 599 | free(srcs[i]); |
@@ -620,7 +602,7 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
620 | if (bad) { | 602 | if (bad) { |
621 | return ErrorAbort(state, kSymlinkFailure, "%s: some symlinks failed", name); | 603 | return ErrorAbort(state, kSymlinkFailure, "%s: some symlinks failed", name); |
622 | } | 604 | } |
623 | return StringValue(strdup("")); | 605 | return StringValue(""); |
624 | } | 606 | } |
625 | 607 | ||
626 | struct perm_parsed_args { | 608 | struct perm_parsed_args { |
@@ -883,20 +865,20 @@ done: | |||
883 | return ErrorAbort(state, kSetMetadataFailure, "%s: some changes failed", name); | 865 | return ErrorAbort(state, kSetMetadataFailure, "%s: some changes failed", name); |
884 | } | 866 | } |
885 | 867 | ||
886 | return StringValue(strdup("")); | 868 | return StringValue(""); |
887 | } | 869 | } |
888 | 870 | ||
889 | Value* GetPropFn(const char* name, State* state, int argc, Expr* argv[]) { | 871 | Value* GetPropFn(const char* name, State* state, int argc, Expr* argv[]) { |
890 | if (argc != 1) { | 872 | if (argc != 1) { |
891 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %d", name, argc); | 873 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects 1 arg, got %d", name, argc); |
892 | } | 874 | } |
893 | char* key = Evaluate(state, argv[0]); | 875 | std::string key; |
894 | if (key == NULL) return NULL; | 876 | if (!Evaluate(state, argv[0], &key)) { |
895 | 877 | return nullptr; | |
878 | } | ||
896 | std::string value = android::base::GetProperty(key, ""); | 879 | std::string value = android::base::GetProperty(key, ""); |
897 | free(key); | ||
898 | 880 | ||
899 | return StringValue(strdup(value.c_str())); | 881 | return StringValue(value); |
900 | } | 882 | } |
901 | 883 | ||
902 | 884 | ||
@@ -1015,7 +997,7 @@ Value* ApplyPatchSpaceFn(const char* name, State* state, | |||
1015 | return nullptr; | 997 | return nullptr; |
1016 | } | 998 | } |
1017 | 999 | ||
1018 | return StringValue(strdup(CacheSizeCheck(bytes) ? "" : "t")); | 1000 | return StringValue(CacheSizeCheck(bytes) ? "" : "t"); |
1019 | } | 1001 | } |
1020 | 1002 | ||
1021 | // apply_patch(file, size, init_sha1, tgt_sha1, patch) | 1003 | // apply_patch(file, size, init_sha1, tgt_sha1, patch) |
@@ -1047,17 +1029,16 @@ Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1047 | } | 1029 | } |
1048 | 1030 | ||
1049 | int patchcount = (argc-4) / 2; | 1031 | int patchcount = (argc-4) / 2; |
1050 | std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc-4, argv+4), | 1032 | std::unique_ptr<Value*> arg_values(ReadValueVarArgs(state, argc-4, argv+4)); |
1051 | free); | ||
1052 | if (!arg_values) { | 1033 | if (!arg_values) { |
1053 | return nullptr; | 1034 | return nullptr; |
1054 | } | 1035 | } |
1055 | std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patch_shas; | 1036 | std::vector<std::unique_ptr<Value>> patch_shas; |
1056 | std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> patches; | 1037 | std::vector<std::unique_ptr<Value>> patches; |
1057 | // Protect values by unique_ptrs first to get rid of memory leak. | 1038 | // Protect values by unique_ptrs first to get rid of memory leak. |
1058 | for (int i = 0; i < patchcount * 2; i += 2) { | 1039 | for (int i = 0; i < patchcount * 2; i += 2) { |
1059 | patch_shas.emplace_back(arg_values.get()[i], FreeValue); | 1040 | patch_shas.emplace_back(arg_values.get()[i]); |
1060 | patches.emplace_back(arg_values.get()[i+1], FreeValue); | 1041 | patches.emplace_back(arg_values.get()[i+1]); |
1061 | } | 1042 | } |
1062 | 1043 | ||
1063 | for (int i = 0; i < patchcount; ++i) { | 1044 | for (int i = 0; i < patchcount; ++i) { |
@@ -1071,7 +1052,7 @@ Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1071 | } | 1052 | } |
1072 | } | 1053 | } |
1073 | 1054 | ||
1074 | std::vector<char*> patch_sha_str; | 1055 | std::vector<std::string> patch_sha_str; |
1075 | std::vector<Value*> patch_ptrs; | 1056 | std::vector<Value*> patch_ptrs; |
1076 | for (int i = 0; i < patchcount; ++i) { | 1057 | for (int i = 0; i < patchcount; ++i) { |
1077 | patch_sha_str.push_back(patch_shas[i]->data); | 1058 | patch_sha_str.push_back(patch_shas[i]->data); |
@@ -1080,9 +1061,9 @@ Value* ApplyPatchFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1080 | 1061 | ||
1081 | int result = applypatch(source_filename, target_filename, | 1062 | int result = applypatch(source_filename, target_filename, |
1082 | target_sha1, target_size, | 1063 | target_sha1, target_size, |
1083 | patchcount, patch_sha_str.data(), patch_ptrs.data(), NULL); | 1064 | patch_sha_str, patch_ptrs.data(), NULL); |
1084 | 1065 | ||
1085 | return StringValue(strdup(result == 0 ? "t" : "")); | 1066 | return StringValue(result == 0 ? "t" : ""); |
1086 | } | 1067 | } |
1087 | 1068 | ||
1088 | // apply_patch_check(file, [sha1_1, ...]) | 1069 | // apply_patch_check(file, [sha1_1, ...]) |
@@ -1095,21 +1076,17 @@ Value* ApplyPatchCheckFn(const char* name, State* state, | |||
1095 | 1076 | ||
1096 | char* filename; | 1077 | char* filename; |
1097 | if (ReadArgs(state, argv, 1, &filename) < 0) { | 1078 | if (ReadArgs(state, argv, 1, &filename) < 0) { |
1098 | return NULL; | 1079 | return nullptr; |
1099 | } | 1080 | } |
1100 | 1081 | ||
1101 | int patchcount = argc-1; | 1082 | std::vector<std::string> sha1s; |
1102 | char** sha1s = ReadVarArgs(state, argc-1, argv+1); | 1083 | if (!ReadArgs(state, argc-1, argv+1, &sha1s)) { |
1103 | 1084 | return nullptr; | |
1104 | int result = applypatch_check(filename, patchcount, sha1s); | ||
1105 | |||
1106 | int i; | ||
1107 | for (i = 0; i < patchcount; ++i) { | ||
1108 | free(sha1s[i]); | ||
1109 | } | 1085 | } |
1110 | free(sha1s); | ||
1111 | 1086 | ||
1112 | return StringValue(strdup(result == 0 ? "t" : "")); | 1087 | int result = applypatch_check(filename, sha1s); |
1088 | |||
1089 | return StringValue(result == 0 ? "t" : ""); | ||
1113 | } | 1090 | } |
1114 | 1091 | ||
1115 | // This is the updater side handler for ui_print() in edify script. Contents | 1092 | // This is the updater side handler for ui_print() in edify script. Contents |
@@ -1129,7 +1106,7 @@ Value* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1129 | 1106 | ||
1130 | buffer += "\n"; | 1107 | buffer += "\n"; |
1131 | uiPrint(state, buffer); | 1108 | uiPrint(state, buffer); |
1132 | return StringValue(strdup(buffer.c_str())); | 1109 | return StringValue(buffer); |
1133 | } | 1110 | } |
1134 | 1111 | ||
1135 | Value* WipeCacheFn(const char* name, State* state, int argc, Expr* argv[]) { | 1112 | Value* WipeCacheFn(const char* name, State* state, int argc, Expr* argv[]) { |
@@ -1137,7 +1114,7 @@ Value* WipeCacheFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1137 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects no args, got %d", name, argc); | 1114 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects no args, got %d", name, argc); |
1138 | } | 1115 | } |
1139 | fprintf(((UpdaterInfo*)(state->cookie))->cmd_pipe, "wipe_cache\n"); | 1116 | fprintf(((UpdaterInfo*)(state->cookie))->cmd_pipe, "wipe_cache\n"); |
1140 | return StringValue(strdup("t")); | 1117 | return StringValue("t"); |
1141 | } | 1118 | } |
1142 | 1119 | ||
1143 | Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) { | 1120 | Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) { |
@@ -1180,10 +1157,7 @@ Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1180 | free(args); | 1157 | free(args); |
1181 | free(args2); | 1158 | free(args2); |
1182 | 1159 | ||
1183 | char buffer[20]; | 1160 | return StringValue(android::base::StringPrintf("%d", status)); |
1184 | sprintf(buffer, "%d", status); | ||
1185 | |||
1186 | return StringValue(strdup(buffer)); | ||
1187 | } | 1161 | } |
1188 | 1162 | ||
1189 | // sha1_check(data) | 1163 | // sha1_check(data) |
@@ -1199,32 +1173,32 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1199 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name); | 1173 | return ErrorAbort(state, kArgsParsingFailure, "%s() expects at least 1 arg", name); |
1200 | } | 1174 | } |
1201 | 1175 | ||
1202 | std::unique_ptr<Value*, decltype(&free)> arg_values(ReadValueVarArgs(state, argc, argv), free); | 1176 | std::unique_ptr<Value*> arg_values(ReadValueVarArgs(state, argc, argv)); |
1203 | if (arg_values == nullptr) { | 1177 | if (arg_values == nullptr) { |
1204 | return nullptr; | 1178 | return nullptr; |
1205 | } | 1179 | } |
1206 | std::vector<std::unique_ptr<Value, decltype(&FreeValue)>> args; | 1180 | std::vector<std::unique_ptr<Value>> args; |
1207 | for (int i = 0; i < argc; ++i) { | 1181 | for (int i = 0; i < argc; ++i) { |
1208 | args.emplace_back(arg_values.get()[i], FreeValue); | 1182 | args.emplace_back(arg_values.get()[i]); |
1209 | } | 1183 | } |
1210 | 1184 | ||
1211 | if (args[0]->size < 0) { | 1185 | if (args[0]->type == VAL_INVALID) { |
1212 | return StringValue(strdup("")); | 1186 | return StringValue(""); |
1213 | } | 1187 | } |
1214 | uint8_t digest[SHA_DIGEST_LENGTH]; | 1188 | uint8_t digest[SHA_DIGEST_LENGTH]; |
1215 | SHA1(reinterpret_cast<uint8_t*>(args[0]->data), args[0]->size, digest); | 1189 | SHA1(reinterpret_cast<const uint8_t*>(args[0]->data.c_str()), args[0]->data.size(), digest); |
1216 | 1190 | ||
1217 | if (argc == 1) { | 1191 | if (argc == 1) { |
1218 | return StringValue(strdup(print_sha1(digest).c_str())); | 1192 | return StringValue(print_sha1(digest)); |
1219 | } | 1193 | } |
1220 | 1194 | ||
1221 | for (int i = 1; i < argc; ++i) { | 1195 | for (int i = 1; i < argc; ++i) { |
1222 | uint8_t arg_digest[SHA_DIGEST_LENGTH]; | 1196 | uint8_t arg_digest[SHA_DIGEST_LENGTH]; |
1223 | if (args[i]->type != VAL_STRING) { | 1197 | if (args[i]->type != VAL_STRING) { |
1224 | printf("%s(): arg %d is not a string; skipping", name, i); | 1198 | printf("%s(): arg %d is not a string; skipping", name, i); |
1225 | } else if (ParseSha1(args[i]->data, arg_digest) != 0) { | 1199 | } else if (ParseSha1(args[i]->data.c_str(), arg_digest) != 0) { |
1226 | // Warn about bad args and skip them. | 1200 | // Warn about bad args and skip them. |
1227 | printf("%s(): error parsing \"%s\" as sha-1; skipping", name, args[i]->data); | 1201 | printf("%s(): error parsing \"%s\" as sha-1; skipping", name, args[i]->data.c_str()); |
1228 | } else if (memcmp(digest, arg_digest, SHA_DIGEST_LENGTH) == 0) { | 1202 | } else if (memcmp(digest, arg_digest, SHA_DIGEST_LENGTH) == 0) { |
1229 | // Found a match. | 1203 | // Found a match. |
1230 | return args[i].release(); | 1204 | return args[i].release(); |
@@ -1232,7 +1206,7 @@ Value* Sha1CheckFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1232 | } | 1206 | } |
1233 | 1207 | ||
1234 | // Didn't match any of the hex strings; return false. | 1208 | // Didn't match any of the hex strings; return false. |
1235 | return StringValue(strdup("")); | 1209 | return StringValue(""); |
1236 | } | 1210 | } |
1237 | 1211 | ||
1238 | // Read a local file and return its contents (the Value* returned | 1212 | // Read a local file and return its contents (the Value* returned |
@@ -1244,21 +1218,12 @@ Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1244 | char* filename; | 1218 | char* filename; |
1245 | if (ReadArgs(state, argv, 1, &filename) < 0) return NULL; | 1219 | if (ReadArgs(state, argv, 1, &filename) < 0) return NULL; |
1246 | 1220 | ||
1247 | Value* v = static_cast<Value*>(malloc(sizeof(Value))); | 1221 | Value* v = new Value(VAL_INVALID, ""); |
1248 | if (v == nullptr) { | ||
1249 | return nullptr; | ||
1250 | } | ||
1251 | v->type = VAL_BLOB; | ||
1252 | v->size = -1; | ||
1253 | v->data = nullptr; | ||
1254 | 1222 | ||
1255 | FileContents fc; | 1223 | FileContents fc; |
1256 | if (LoadFileContents(filename, &fc) == 0) { | 1224 | if (LoadFileContents(filename, &fc) == 0) { |
1257 | v->data = static_cast<char*>(malloc(fc.data.size())); | 1225 | v->type = VAL_BLOB; |
1258 | if (v->data != nullptr) { | 1226 | v->data = std::string(fc.data.begin(), fc.data.end()); |
1259 | memcpy(v->data, fc.data.data(), fc.data.size()); | ||
1260 | v->size = fc.data.size(); | ||
1261 | } | ||
1262 | } | 1227 | } |
1263 | free(filename); | 1228 | free(filename); |
1264 | return v; | 1229 | return v; |
@@ -1326,16 +1291,19 @@ Value* SetStageFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1326 | // package installation. | 1291 | // package installation. |
1327 | FILE* f = ota_fopen(filename, "r+b"); | 1292 | FILE* f = ota_fopen(filename, "r+b"); |
1328 | fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); | 1293 | fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); |
1329 | int to_write = strlen(stagestr)+1; | 1294 | size_t to_write = strlen(stagestr) + 1; |
1330 | int max_size = sizeof(((struct bootloader_message*)0)->stage); | 1295 | size_t max_size = sizeof(((struct bootloader_message*)0)->stage); |
1331 | if (to_write > max_size) { | 1296 | if (to_write > max_size) { |
1332 | to_write = max_size; | 1297 | to_write = max_size; |
1333 | stagestr[max_size-1] = 0; | 1298 | stagestr[max_size - 1] = 0; |
1334 | } | 1299 | } |
1335 | ota_fwrite(stagestr, to_write, 1, f); | 1300 | size_t status = ota_fwrite(stagestr, to_write, 1, f); |
1336 | ota_fclose(f); | 1301 | ota_fclose(f); |
1337 | 1302 | ||
1338 | free(stagestr); | 1303 | free(stagestr); |
1304 | if (status != to_write) { | ||
1305 | return StringValue(""); | ||
1306 | } | ||
1339 | return StringValue(filename); | 1307 | return StringValue(filename); |
1340 | } | 1308 | } |
1341 | 1309 | ||
@@ -1352,11 +1320,14 @@ Value* GetStageFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1352 | char buffer[sizeof(((struct bootloader_message*)0)->stage)]; | 1320 | char buffer[sizeof(((struct bootloader_message*)0)->stage)]; |
1353 | FILE* f = ota_fopen(filename, "rb"); | 1321 | FILE* f = ota_fopen(filename, "rb"); |
1354 | fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); | 1322 | fseek(f, offsetof(struct bootloader_message, stage), SEEK_SET); |
1355 | ota_fread(buffer, sizeof(buffer), 1, f); | 1323 | size_t status = ota_fread(buffer, sizeof(buffer), 1, f); |
1356 | ota_fclose(f); | 1324 | ota_fclose(f); |
1357 | buffer[sizeof(buffer)-1] = '\0'; | 1325 | if (status != sizeof(buffer)) { |
1326 | return StringValue(""); | ||
1327 | } | ||
1358 | 1328 | ||
1359 | return StringValue(strdup(buffer)); | 1329 | buffer[sizeof(buffer)-1] = '\0'; |
1330 | return StringValue(buffer); | ||
1360 | } | 1331 | } |
1361 | 1332 | ||
1362 | Value* WipeBlockDeviceFn(const char* name, State* state, int argc, Expr* argv[]) { | 1333 | Value* WipeBlockDeviceFn(const char* name, State* state, int argc, Expr* argv[]) { |
@@ -1378,7 +1349,7 @@ Value* WipeBlockDeviceFn(const char* name, State* state, int argc, Expr* argv[]) | |||
1378 | 1349 | ||
1379 | ota_close(fd); | 1350 | ota_close(fd); |
1380 | 1351 | ||
1381 | return StringValue(strdup(success ? "t" : "")); | 1352 | return StringValue(success ? "t" : ""); |
1382 | } | 1353 | } |
1383 | 1354 | ||
1384 | Value* EnableRebootFn(const char* name, State* state, int argc, Expr* argv[]) { | 1355 | Value* EnableRebootFn(const char* name, State* state, int argc, Expr* argv[]) { |
@@ -1387,7 +1358,7 @@ Value* EnableRebootFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1387 | } | 1358 | } |
1388 | UpdaterInfo* ui = (UpdaterInfo*)(state->cookie); | 1359 | UpdaterInfo* ui = (UpdaterInfo*)(state->cookie); |
1389 | fprintf(ui->cmd_pipe, "enable_reboot\n"); | 1360 | fprintf(ui->cmd_pipe, "enable_reboot\n"); |
1390 | return StringValue(strdup("t")); | 1361 | return StringValue("t"); |
1391 | } | 1362 | } |
1392 | 1363 | ||
1393 | Value* Tune2FsFn(const char* name, State* state, int argc, Expr* argv[]) { | 1364 | Value* Tune2FsFn(const char* name, State* state, int argc, Expr* argv[]) { |
@@ -1418,7 +1389,7 @@ Value* Tune2FsFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
1418 | return ErrorAbort(state, kTune2FsFailure, "%s() returned error code %d", | 1389 | return ErrorAbort(state, kTune2FsFailure, "%s() returned error code %d", |
1419 | name, result); | 1390 | name, result); |
1420 | } | 1391 | } |
1421 | return StringValue(strdup("t")); | 1392 | return StringValue("t"); |
1422 | } | 1393 | } |
1423 | 1394 | ||
1424 | void RegisterInstallFunctions() { | 1395 | void RegisterInstallFunctions() { |
diff --git a/updater/updater.cpp b/updater/updater.cpp index c752ebbf..47696b80 100644 --- a/updater/updater.cpp +++ b/updater/updater.cpp | |||
@@ -151,13 +151,14 @@ int main(int argc, char** argv) { | |||
151 | } | 151 | } |
152 | } | 152 | } |
153 | 153 | ||
154 | char* result = Evaluate(&state, root); | 154 | std::string result; |
155 | bool status = Evaluate(&state, root, &result); | ||
155 | 156 | ||
156 | if (have_eio_error) { | 157 | if (have_eio_error) { |
157 | fprintf(cmd_pipe, "retry_update\n"); | 158 | fprintf(cmd_pipe, "retry_update\n"); |
158 | } | 159 | } |
159 | 160 | ||
160 | if (result == NULL) { | 161 | if (!status) { |
161 | if (state.errmsg.empty()) { | 162 | if (state.errmsg.empty()) { |
162 | printf("script aborted (no error message)\n"); | 163 | printf("script aborted (no error message)\n"); |
163 | fprintf(cmd_pipe, "ui_print script aborted (no error message)\n"); | 164 | fprintf(cmd_pipe, "ui_print script aborted (no error message)\n"); |
@@ -188,8 +189,7 @@ int main(int argc, char** argv) { | |||
188 | 189 | ||
189 | return 7; | 190 | return 7; |
190 | } else { | 191 | } else { |
191 | fprintf(cmd_pipe, "ui_print script succeeded: result was [%s]\n", result); | 192 | fprintf(cmd_pipe, "ui_print script succeeded: result was [%s]\n", result.c_str()); |
192 | free(result); | ||
193 | } | 193 | } |
194 | 194 | ||
195 | if (updater_info.package_zip) { | 195 | if (updater_info.package_zip) { |