| File: | argv-array.c |
| Location: | line 20, column 29 |
| Description: | Array access (via field 'argv') results in a null pointer dereference |
| 1 | #include "cache.h" | |||
| 2 | #include "argv-array.h" | |||
| 3 | #include "strbuf.h" | |||
| 4 | ||||
| 5 | const char *empty_argv[] = { NULL((void*)0) }; | |||
| 6 | ||||
| 7 | void argv_array_init(struct argv_array *array) | |||
| 8 | { | |||
| 9 | array->argv = empty_argv; | |||
| 10 | array->argc = 0; | |||
| 11 | array->alloc = 0; | |||
| 12 | } | |||
| 13 | ||||
| 14 | static void argv_array_push_nodup(struct argv_array *array, const char *value) | |||
| 15 | { | |||
| 16 | if (array->argv == empty_argv) | |||
| 17 | array->argv = NULL((void*)0); | |||
| 18 | ||||
| 19 | ALLOC_GROW(array->argv, array->argc + 2, array->alloc)do { if ((array->argc + 2) > array->alloc) { if (((( array->alloc)+16)*3/2) < (array->argc + 2)) array-> alloc = (array->argc + 2); else array->alloc = (((array ->alloc)+16)*3/2); (array->argv) = xrealloc((array-> argv), st_mult(sizeof(*(array->argv)), (array->alloc))) ; } } while (0); | |||
| 20 | array->argv[array->argc++] = value; | |||
| ||||
| 21 | array->argv[array->argc] = NULL((void*)0); | |||
| 22 | } | |||
| 23 | ||||
| 24 | void argv_array_push(struct argv_array *array, const char *value) | |||
| 25 | { | |||
| 26 | argv_array_push_nodup(array, xstrdup(value)); | |||
| 27 | } | |||
| 28 | ||||
| 29 | void argv_array_pushf(struct argv_array *array, const char *fmt, ...) | |||
| 30 | { | |||
| 31 | va_list ap; | |||
| 32 | struct strbuf v = STRBUF_INIT{ 0, 0, strbuf_slopbuf }; | |||
| 33 | ||||
| 34 | va_start(ap, fmt)__builtin_va_start(ap, fmt); | |||
| 35 | strbuf_vaddf(&v, fmt, ap); | |||
| 36 | va_end(ap)__builtin_va_end(ap); | |||
| 37 | ||||
| 38 | argv_array_push_nodup(array, strbuf_detach(&v, NULL((void*)0))); | |||
| ||||
| 39 | } | |||
| 40 | ||||
| 41 | void argv_array_pushl(struct argv_array *array, ...) | |||
| 42 | { | |||
| 43 | va_list ap; | |||
| 44 | const char *arg; | |||
| 45 | ||||
| 46 | va_start(ap, array)__builtin_va_start(ap, array); | |||
| 47 | while((arg = va_arg(ap, const char *)__builtin_va_arg(ap, const char *))) | |||
| 48 | argv_array_push(array, arg); | |||
| 49 | va_end(ap)__builtin_va_end(ap); | |||
| 50 | } | |||
| 51 | ||||
| 52 | void argv_array_pushv(struct argv_array *array, const char **argv) | |||
| 53 | { | |||
| 54 | for (; *argv; argv++) | |||
| 55 | argv_array_push(array, *argv); | |||
| 56 | } | |||
| 57 | ||||
| 58 | void argv_array_pop(struct argv_array *array) | |||
| 59 | { | |||
| 60 | if (!array->argc) | |||
| 61 | return; | |||
| 62 | free((char *)array->argv[array->argc - 1]); | |||
| 63 | array->argv[array->argc - 1] = NULL((void*)0); | |||
| 64 | array->argc--; | |||
| 65 | } | |||
| 66 | ||||
| 67 | void argv_array_clear(struct argv_array *array) | |||
| 68 | { | |||
| 69 | if (array->argv != empty_argv) { | |||
| 70 | int i; | |||
| 71 | for (i = 0; i < array->argc; i++) | |||
| 72 | free((char *)array->argv[i]); | |||
| 73 | free(array->argv); | |||
| 74 | } | |||
| 75 | argv_array_init(array); | |||
| 76 | } | |||
| 77 | ||||
| 78 | const char **argv_array_detach(struct argv_array *array) | |||
| 79 | { | |||
| 80 | if (array->argv == empty_argv) | |||
| 81 | return xcalloc(1, sizeof(const char *)); | |||
| 82 | else { | |||
| 83 | const char **ret = array->argv; | |||
| 84 | argv_array_init(array); | |||
| 85 | return ret; | |||
| 86 | } | |||
| 87 | } |