-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Request: Add success/fail flag for webserver parse arguments #6884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I've been looking at the code a bit more and also came up with some other use cases which may explain a number of issues I've seen. The arguments which are parsed are kept in an array, which is deleted as soon as the next request comes in.
In the webserver, you have to register some URLs and their function to handle the URL. As it is implemented right now is not the correct way as it does happen sometimes that values of one request are mixed with other values, or some other processes allocate memory where there was once a parsed argument. |
Does anyone have a comment on my suggestions? |
@TD-er the webserver internals are a heavy legacy to carry. @darkain had fully rewritten it and I then tried to bring it here but I am now late behind recent updates (templatization) #5636. What can be done
I think the AsyncHttpServer approach is better in term of memory than trying to do that. |
I was afraid you were going to say something like that. So then we're kinda back at the original idea of having a flag to detect whether things were not parsed. |
For the same reasons we cannot get rid of the current Webserver.
Please allow time for that (if you want us to check this out). |
On my node (running the latest core version as of yesterday), I have really low free RAM, but this may also happen on nodes with more fragmented memory or for long POST requests.
What I'm seeing is that when submitting form data, not all form elements will be complete.
As far as I know there is no easy check to see if the web arg parsing was successful.
ESP8266WebServerTemplate<ServerType>::_parseArgumentsPrivate
does seem to parse the form data and create an array of_currentArgs
containing a key and value string.So far so good, but sometimes I am missing a key or its value is incomplete.
The
storeArgHandler
handler given to this parser function would be the ideal place to check if a result was successful, since it does know how long the strings should be when stored.The
ESP8266WebServerTemplate<ServerType>::urlDecode
function should be changed to not return a String, but filling one and also be responsible of calling reserve as soon as it knows how long the string will be. (will cause less heap fragmentation also, but may need to check the string twice)This will make it quite clear very soon if an alloc (after calling the
reserve()
) was successful.If not, then there is no use to continue.
So it does also make sense to return a bool.
This makes it also clear
void operator() (String& key, String& value, const String& data, int equal_index, int pos, int key_end_pos, int next_index)
should return a bool.ESP8266WebServerTemplate<ServerType>::_parseArgumentsPrivate
should then return -1 on an error and its result should be dealt with here:While we're at it, I also noticed the
_parseArgumentsPrivate
function is also called with anullArgHandler
, to determine the number of arguments.It calls this handler using this code:
RequestArgument& arg = _currentArgs[arg_total]; handler(arg.key, arg.value, data, equal_index, pos, key_end_pos, next_index);
But
_currentArgs
is deleted (though not set tonullptr
).Can this cause a crash when the former address for
_currentArgs
is been re-used for something else and we're addressing it like this?I do get the use of a
nullArgHandler
, but wouldn't it make more sense to use it as a pointer which can be null? Then we can test for it and not address an array which has just been deleted.A last point I was wondering.
Is it needed to store the
plain
form element, which does contain the same information as was submitted?If so, then wouldn't it make more sense to just store the offsets in this plain string (& decoded length) and decode it again as soon as an element is requested?
Now the data is stored twice in memory.
The text was updated successfully, but these errors were encountered: