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