Skip to content

Commit 72f675b

Browse files
author
Mike Gerdts
committed
exec() can now properly handle lines longer than (EXEC_INPUT_BUF-2) bytes. Lines being returned via the array that that contain only "\n" now are trimmed down to "" to be consistent with exec's whitespace trimming behavior for all other lines.
1 parent 3ff606a commit 72f675b

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

ext/standard/exec.c

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,20 @@
4141
static int _Exec(int type, char *cmd, pval *array, pval *return_value)
4242
{
4343
FILE *fp;
44-
char buf[EXEC_INPUT_BUF], *tmp=NULL;
44+
char *buf, *tmp=NULL;
45+
int buflen = 0;
4546
int t, l, ret, output=1;
4647
int overflow_limit, lcmd, ldir;
4748
char *b, *c, *d=NULL;
4849
PLS_FETCH();
4950

51+
buf = (char*) emalloc(EXEC_INPUT_BUF);
52+
if (!buf) {
53+
php3_error(E_WARNING, "Unable to emalloc %d bytes for exec buffer", EXEC_INPUT_BUF);
54+
return -1;
55+
}
56+
buflen = EXEC_INPUT_BUF;
57+
5058
if (PG(safe_mode)) {
5159
lcmd = strlen(cmd);
5260
ldir = strlen(PG(safe_mode_exec_dir));
@@ -56,6 +64,7 @@ static int _Exec(int type, char *cmd, pval *array, pval *return_value)
5664
if (c) *c = '\0';
5765
if (strstr(cmd, "..")) {
5866
php3_error(E_WARNING, "No '..' components allowed in path");
67+
efree(buf);
5968
return -1;
6069
}
6170
d = emalloc(l);
@@ -85,6 +94,7 @@ static int _Exec(int type, char *cmd, pval *array, pval *return_value)
8594
if (!fp) {
8695
php3_error(E_WARNING, "Unable to fork [%s]", d);
8796
efree(d);
97+
efree(buf);
8898
return -1;
8999
}
90100
} else { /* not safe_mode */
@@ -95,6 +105,7 @@ static int _Exec(int type, char *cmd, pval *array, pval *return_value)
95105
#endif
96106
if (!fp) {
97107
php3_error(E_WARNING, "Unable to fork [%s]", cmd);
108+
efree(buf);
98109
return -1;
99110
}
100111
}
@@ -106,7 +117,33 @@ static int _Exec(int type, char *cmd, pval *array, pval *return_value)
106117
}
107118
}
108119
if (type != 3) {
109-
while (fgets(buf, EXEC_INPUT_BUF - 1, fp)) {
120+
l=0;
121+
while ( !feof(fp) || l != 0 ) {
122+
l = 0;
123+
/* Read a line or fill the buffer, whichever comes first */
124+
do {
125+
if ( buflen <= (l+1) ) {
126+
buf = erealloc(buf, buflen + EXEC_INPUT_BUF);
127+
if ( buf == NULL ) {
128+
php3_error(E_WARNING, "Unable to erealloc %d bytes for exec buffer",
129+
buflen + EXEC_INPUT_BUF);
130+
return -1;
131+
}
132+
buflen += EXEC_INPUT_BUF;
133+
}
134+
135+
if ( fgets(&(buf[l]), buflen - l, fp) == NULL ) {
136+
/* eof */
137+
break;
138+
}
139+
l += strlen(&(buf[l]));
140+
} while ( (l > 0) && (buf[l-1] != '\n') );
141+
142+
if ( feof(fp) && (l == 0) ) {
143+
break;
144+
}
145+
146+
110147
if (type == 1) {
111148
SLS_FETCH();
112149

@@ -132,7 +169,7 @@ static int _Exec(int type, char *cmd, pval *array, pval *return_value)
132169
/* strip trailing whitespaces */
133170
l = strlen(buf);
134171
t = l;
135-
while (l && isspace((int)buf[--l]));
172+
while (l-- && isspace((int)buf[l]));
136173
if (l < t) {
137174
buf[l + 1] = '\0';
138175
}
@@ -173,6 +210,7 @@ static int _Exec(int type, char *cmd, pval *array, pval *return_value)
173210
#endif
174211

175212
if (d) efree(d);
213+
efree(buf);
176214
return ret;
177215
}
178216

0 commit comments

Comments
 (0)