diff options
author | Sami Tolvanen <samitolvanen@google.com> | 2015-05-12 13:48:46 +0200 |
---|---|---|
committer | Rom Lemarchand <romlem@google.com> | 2015-11-16 23:28:40 +0100 |
commit | 806f72f9e6ec0d15b550b79b0baa92a93fc646e3 (patch) | |
tree | 53a5974e09b65b4d68fafbe0f87097843252be35 /updater/blockimg.c | |
parent | Stop using libstdc++. (diff) | |
download | android_bootable_recovery-806f72f9e6ec0d15b550b79b0baa92a93fc646e3.tar android_bootable_recovery-806f72f9e6ec0d15b550b79b0baa92a93fc646e3.tar.gz android_bootable_recovery-806f72f9e6ec0d15b550b79b0baa92a93fc646e3.tar.bz2 android_bootable_recovery-806f72f9e6ec0d15b550b79b0baa92a93fc646e3.tar.lz android_bootable_recovery-806f72f9e6ec0d15b550b79b0baa92a93fc646e3.tar.xz android_bootable_recovery-806f72f9e6ec0d15b550b79b0baa92a93fc646e3.tar.zst android_bootable_recovery-806f72f9e6ec0d15b550b79b0baa92a93fc646e3.zip |
Diffstat (limited to 'updater/blockimg.c')
-rw-r--r-- | updater/blockimg.c | 81 |
1 files changed, 71 insertions, 10 deletions
diff --git a/updater/blockimg.c b/updater/blockimg.c index b006d10c5..e0be03917 100644 --- a/updater/blockimg.c +++ b/updater/blockimg.c @@ -61,30 +61,91 @@ typedef struct { int pos[0]; } RangeSet; +#define RANGESET_MAX_POINTS \ + ((int)((INT_MAX / sizeof(int)) - sizeof(RangeSet))) + static RangeSet* parse_range(char* text) { char* save; - int num; - num = strtol(strtok_r(text, ",", &save), NULL, 0); + char* token; + int i, num; + long int val; + RangeSet* out = NULL; + size_t bufsize; - RangeSet* out = malloc(sizeof(RangeSet) + num * sizeof(int)); - if (out == NULL) { - fprintf(stderr, "failed to allocate range of %zu bytes\n", - sizeof(RangeSet) + num * sizeof(int)); - exit(1); + if (!text) { + goto err; + } + + token = strtok_r(text, ",", &save); + + if (!token) { + goto err; + } + + val = strtol(token, NULL, 0); + + if (val < 2 || val > RANGESET_MAX_POINTS) { + goto err; + } else if (val % 2) { + goto err; // must be even + } + + num = (int) val; + bufsize = sizeof(RangeSet) + num * sizeof(int); + + out = malloc(bufsize); + + if (!out) { + fprintf(stderr, "failed to allocate range of %zu bytes\n", bufsize); + goto err; } + out->count = num / 2; out->size = 0; - int i; + for (i = 0; i < num; ++i) { - out->pos[i] = strtol(strtok_r(NULL, ",", &save), NULL, 0); - if (i%2) { + token = strtok_r(NULL, ",", &save); + + if (!token) { + goto err; + } + + val = strtol(token, NULL, 0); + + if (val < 0 || val > INT_MAX) { + goto err; + } + + out->pos[i] = (int) val; + + if (i % 2) { + if (out->pos[i - 1] >= out->pos[i]) { + goto err; // empty or negative range + } + + if (out->size > INT_MAX - out->pos[i]) { + goto err; // overflow + } + out->size += out->pos[i]; } else { + if (out->size < 0) { + goto err; + } + out->size -= out->pos[i]; } } + if (out->size <= 0) { + goto err; + } + return out; + +err: + fprintf(stderr, "failed to parse range '%s'\n", text ? text : "NULL"); + exit(1); } static int range_overlaps(RangeSet* r1, RangeSet* r2) { |