Skip to content

Commit 4787753

Browse files
committed
fix parseArgument
1 parent d17ffc2 commit 4787753

File tree

2 files changed

+65
-57
lines changed

2 files changed

+65
-57
lines changed

libraries/ESP8266WebServer/src/ESP8266WebServer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ class ESP8266WebServer
142142
void _handleRequest();
143143
void _finalizeResponse();
144144
bool _parseRequest(WiFiClient& client);
145-
void _parseArguments(String data);
145+
int _parseArguments(const String& data, bool store = true);
146146
static String _responseCodeToString(int code);
147147
bool _parseForm(WiFiClient& client, String boundary, uint32_t len);
148148
bool _parseFormUploadAborted();

libraries/ESP8266WebServer/src/Parsing.cpp

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -270,79 +270,87 @@ bool ESP8266WebServer::_collectHeader(const char* headerName, const char* header
270270
return false;
271271
}
272272

273-
void ESP8266WebServer::_parseArguments(String data) {
273+
int ESP8266WebServer::_parseArguments(const String& data, bool store) {
274+
// when store is true, a recursive call
275+
// with store=false is recursively called first
276+
// to evaluate the number of arguments
277+
// should we use a vector instead?
278+
274279
#ifdef DEBUG_ESP_HTTP_SERVER
275280
DEBUG_OUTPUT.print("args: ");
276281
DEBUG_OUTPUT.println(data);
277282
#endif
278-
if (_currentArgs)
279-
delete[] _currentArgs;
280-
_currentArgs = 0;
281-
if (data.length() == 0) {
282-
_currentArgCount = 0;
283-
_currentArgs = new RequestArgument[1];
284-
return;
283+
284+
if (store) {
285+
if (_currentArgs)
286+
delete[] _currentArgs;
287+
_currentArgs = 0;
285288
}
286-
_currentArgCount = 1;
287289

288-
for (int i = 0; i < (int)data.length(); ) {
289-
i = data.indexOf('&', i);
290-
if (i == -1)
291-
break;
292-
++i;
293-
++_currentArgCount;
290+
if (store) {
291+
_currentArgCount = _parseArguments(data, false);
292+
_currentArgs = new RequestArgument[_currentArgCount+1];
294293
}
295-
#ifdef DEBUG_ESP_HTTP_SERVER
296-
DEBUG_OUTPUT.print("args count: ");
297-
DEBUG_OUTPUT.println(_currentArgCount);
298-
#endif
299294

300-
_currentArgs = new RequestArgument[_currentArgCount+1];
301-
int pos = 0;
302-
int iarg;
303-
for (iarg = 0; iarg < _currentArgCount;) {
304-
int equal_sign_index = data.indexOf('=', pos);
305-
int next_arg_index = data.indexOf('&', pos);
306-
#ifdef DEBUG_ESP_HTTP_SERVER
307-
DEBUG_OUTPUT.print("pos ");
308-
DEBUG_OUTPUT.print(pos);
309-
DEBUG_OUTPUT.print("=@ ");
310-
DEBUG_OUTPUT.print(equal_sign_index);
311-
DEBUG_OUTPUT.print(" &@ ");
312-
DEBUG_OUTPUT.println(next_arg_index);
313-
#endif
314-
if ((equal_sign_index == -1) || ((equal_sign_index > next_arg_index) && (next_arg_index != -1))) {
315-
#ifdef DEBUG_ESP_HTTP_SERVER
316-
DEBUG_OUTPUT.print("arg missing value: ");
317-
DEBUG_OUTPUT.println(iarg);
318-
#endif
319-
if (next_arg_index == -1)
295+
size_t pos = 0;
296+
int arg_total = 0;
297+
298+
while (true) {
299+
300+
// skip empty expression
301+
while (data[pos] == '&' || data[pos] == ';')
302+
if (++pos >= data.length())
320303
break;
321-
pos = next_arg_index + 1;
322-
continue;
323-
}
324-
RequestArgument& arg = _currentArgs[iarg];
325-
arg.key = urlDecode(data.substring(pos, equal_sign_index));
326-
arg.value = urlDecode(data.substring(equal_sign_index + 1, next_arg_index));
304+
305+
// locate separators
306+
int equal_index = data.indexOf('=', pos);
307+
int keyEndPos = equal_index;
308+
int next_index = data.indexOf('&', pos);
309+
int next_index2 = data.indexOf(';', pos);
310+
if ((next_index == -1) || (next_index2 != -1 && next_index2 < next_index))
311+
next_index = next_index2;
312+
if ((keyEndPos == -1) || ((keyEndPos > next_index) && (next_index != -1)))
313+
keyEndPos = next_index;
314+
if (keyEndPos == -1)
315+
keyEndPos = data.length();
316+
keyEndPos--;
317+
318+
// handle key/value
319+
if (keyEndPos >= (int)pos) {
320+
// do not store or count empty ending key ("url?x=y;")
321+
322+
if (store) {
323+
RequestArgument& arg = _currentArgs[arg_total];
324+
arg.key = urlDecode(data.substring(pos, keyEndPos));
325+
if ((equal_index != -1) && ((equal_index < next_index - 1) || (next_index == -1)))
326+
arg.value = urlDecode(data.substring(equal_index + 1, next_index - 1));
327327
#ifdef DEBUG_ESP_HTTP_SERVER
328-
DEBUG_OUTPUT.print("arg ");
329-
DEBUG_OUTPUT.print(iarg);
330-
DEBUG_OUTPUT.print(" key: ");
331-
DEBUG_OUTPUT.print(arg.key);
332-
DEBUG_OUTPUT.print(" value: ");
333-
DEBUG_OUTPUT.println(arg.value);
328+
DEBUG_OUTPUT.print("arg ");
329+
DEBUG_OUTPUT.print(arg_total);
330+
DEBUG_OUTPUT.print(" key: ");
331+
DEBUG_OUTPUT.print(arg.key);
332+
DEBUG_OUTPUT.print(" value: ");
333+
DEBUG_OUTPUT.println(arg.value);
334334
#endif
335-
++iarg;
336-
if (next_arg_index == -1)
335+
}
336+
337+
++arg_total;
338+
pos = next_index + 1;
339+
}
340+
341+
if (next_index == -1)
337342
break;
338-
pos = next_arg_index + 1;
339343
}
340-
_currentArgCount = iarg;
344+
341345
#ifdef DEBUG_ESP_HTTP_SERVER
342346
DEBUG_OUTPUT.print("args count: ");
343-
DEBUG_OUTPUT.println(_currentArgCount);
347+
DEBUG_OUTPUT.println(arg_total);
344348
#endif
345349

350+
if (store)
351+
_currentArgCount = arg_total;
352+
353+
return arg_total;
346354
}
347355

348356
void ESP8266WebServer::_uploadWriteByte(uint8_t b){

0 commit comments

Comments
 (0)