|
Added
Link Here
|
| 1 |
--- src/popt.c.orig 2020-05-18 07:43:13 UTC |
| 2 |
+++ src/popt.c |
| 3 |
@@ -168,6 +168,7 @@ poptContext poptGetContext(const char * name, int argc |
| 4 |
con->os->next = 1; /* skip argv[0] */ |
| 5 |
|
| 6 |
con->leftovers = calloc( (size_t)(argc + 1), sizeof(*con->leftovers) ); |
| 7 |
+ con->allocLeftovers = argc + 1; |
| 8 |
con->options = options; |
| 9 |
con->aliases = NULL; |
| 10 |
con->numAliases = 0; |
| 11 |
@@ -1269,8 +1270,21 @@ int poptGetNextOpt(poptContext con) |
| 12 |
con->os->nextArg = xstrdup(origOptString); |
| 13 |
return 0; |
| 14 |
} |
| 15 |
- if (con->leftovers != NULL) /* XXX can't happen */ |
| 16 |
- con->leftovers[con->numLeftovers++] = origOptString; |
| 17 |
+ if (con->leftovers != NULL) { /* XXX can't happen */ |
| 18 |
+ /* One might think we can never overflow the leftovers |
| 19 |
+ array. Actually, that's true, as long as you don't |
| 20 |
+ use poptStuffArgs()... */ |
| 21 |
+ if ((con->numLeftovers + 1) >= (con->allocLeftovers)) { |
| 22 |
+ con->allocLeftovers += 10; |
| 23 |
+ con->leftovers = |
| 24 |
+ realloc(con->leftovers, |
| 25 |
+ sizeof(*con->leftovers) * con->allocLeftovers); |
| 26 |
+ } |
| 27 |
+ con->leftovers[con->numLeftovers++] |
| 28 |
+ = xstrdup(origOptString); /* so a free of a stuffed |
| 29 |
+ argv doesn't give us a |
| 30 |
+ dangling pointer */ |
| 31 |
+ } |
| 32 |
continue; |
| 33 |
} |
| 34 |
|
| 35 |
@@ -1519,6 +1533,8 @@ poptItem poptFreeItems(poptItem items, int nitems) |
| 36 |
|
| 37 |
poptContext poptFreeContext(poptContext con) |
| 38 |
{ |
| 39 |
+ int i; |
| 40 |
+ |
| 41 |
if (con == NULL) return con; |
| 42 |
poptResetContext(con); |
| 43 |
|
| 44 |
@@ -1528,7 +1544,11 @@ poptContext poptFreeContext(poptContext con) |
| 45 |
con->execs = poptFreeItems(con->execs, con->numExecs); |
| 46 |
con->numExecs = 0; |
| 47 |
|
| 48 |
+ for (i = 0; i < con->numLeftovers; i++) { |
| 49 |
+ con->leftovers[i] = _free(&con->leftovers[i]); |
| 50 |
+ } |
| 51 |
con->leftovers = _free(con->leftovers); |
| 52 |
+ |
| 53 |
con->finalArgv = _free(con->finalArgv); |
| 54 |
con->appName = _free(con->appName); |
| 55 |
con->otherHelp = _free(con->otherHelp); |