Skip to content

ESP8266WebServer doesn't encode/decode correctly #1989

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

Closed
Baumi1245 opened this issue Apr 29, 2016 · 7 comments
Closed

ESP8266WebServer doesn't encode/decode correctly #1989

Baumi1245 opened this issue Apr 29, 2016 · 7 comments

Comments

@Baumi1245
Copy link

Baumi1245 commented Apr 29, 2016

I still got a problem with this:
#454

Decoding is done to late - it only works within the argument.

pe:
String R1 = server.arg("R1");
i let me show "R1":

http://192.168.125.150/cmd?R1=1
answer = "1"

http://192.168.125.150/cmd?R1%3D1
answer = nothing

http://192.168.125.150/cmd?R1=%3D1
answer = "=1"

%3d is decodet to "=" but not at the place i need it.
http://192.168.125.150/cmd?R1%3D1 should work as http://192.168.125.150/cmd?R1=1
I also can´t find a workaround - server.argName is only shown if there is a "=" within the url.

This is working on different kinds of Webcams and home-automation.

Greetings from Austria, Tom.

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@thewhiterabbit
Copy link

I'm using this library with urlencode and have not had any problems with the encoding/decoding. You should not encode the '=', only the value after it, if it contains quotes, spaces or other special characters. Try using assignment like "key=" + urlencode(value);

You will need the urlencode/decode functions below included in your sketch:

String urldecode(String str)
{

String encodedString="";
char c;
char code0;
char code1;
for (int i =0; i < str.length(); i++){
    c=str.charAt(i);
  if (c == '+'){
    encodedString+=' ';  
  }else if (c == '%') {
    i++;
    code0=str.charAt(i);
    i++;
    code1=str.charAt(i);
    c = (h2int(code0) << 4) | h2int(code1);
    encodedString+=c;
  } else{

    encodedString+=c;  
  }

  yield();
}

return encodedString;
}

String urlencode(String str)
{
String encodedString="";
char c;
char code0;
char code1;
char code2;
for (int i =0; i < str.length(); i++){
c=str.charAt(i);
if (c == ' '){
encodedString+= '+';
} else if (isalnum(c)){
encodedString+=c;
} else{
code1=(c & 0xf)+'0';
if ((c & 0xf) >9){
code1=(c & 0xf) - 10 + 'A';
}
c=(c>>4)&0xf;
code0=c+'0';
if (c > 9){
code0=c - 10 + 'A';
}
code2='\0';
encodedString+='%';
encodedString+=code0;
encodedString+=code1;
//encodedString+=code2;
}
yield();
}
return encodedString;

}

unsigned char h2int(char c)
{
if (c >= '0' && c <='9'){
return((unsigned char)c - '0');
}
if (c >= 'a' && c <='f'){
return((unsigned char)c - 'a' + 10);
}
if (c >= 'A' && c <='F'){
return((unsigned char)c - 'A' + 10);
}
return(0);
}

@me-no-dev
Copy link
Collaborator

@thewhiterabbit Do not know why git closed the issue but could you please check if it's fixed now?

@me-no-dev me-no-dev reopened this Jun 30, 2016
@luc-github
Copy link
Contributor

@me-no-dev af06847 introduce a bug on my side
I use an authentication method that use redirection that work perfectly until this commit
it is like :

static const char NOT_AUTH_CS [] PROGMEM = "HTTP/1.1 301 OK\r\nLocation: /LOGIN?return=CONFIGSYS\r\nCache-Control: no-cache\r\n\r\n";
if (!web_interface->is_authenticated()) {
        web_interface->WebServer.sendContent_P(NOT_AUTH_CS);
        return;

then the login form post the hidden field

<form method="POST">
<input type="hidden" name="return"  value="CONFIGSYS">

argument is catched by

 if (web_interface->WebServer.hasArg("return")) {
        sReturn = web_interface->WebServer.urlDecode(web_interface->WebServer.arg("return"));

if password match then redirect according return argument

if (web_interface->AddAuthIP(current_auth)) {
                String header = F("HTTP/1.1 301 OK\r\nSet-Cookie: ESPSESSIONID=1");
                header+="\r\nLocation: /";
                header+=sReturn;
                header.concat(F("\r\nCache-Control: no-cache\r\n\r\n"));
                web_interface->WebServer.sendContent(header);
                return;
            }

but with this commit (af06847 ) now argument is strangely catched and got with orignal url :
http://192.168.1.61/LOGIN?return=CONFIGSYS
a redirection
http://192.168.1.61/CONFIGSYSreturn=CONFIGSYS
then if another try occurs http://192.168.1.61/CONFIGSYSreturn=CONFIGSYSreturn=CONFIGSYS

it looks like the argument is polluted

Sorry I did not dig more

@me-no-dev
Copy link
Collaborator

Looks like a mistake on my end. I have removed the line that properly stitches get and post args before parsing them. Added back in #2222 which I'll merge as soon as the check passes. Good catch @luc-github

@me-no-dev
Copy link
Collaborator

@luc-github no need to urlDecode in your code anymore, unless you have double encoded arguments.

@luc-github
Copy link
Contributor

@me-no-dev thanks a lot 🎆
yes you are right thanks a lot for pointing out, will remove it

igrr pushed a commit to esp8266/ESPWebServer that referenced this issue Jun 29, 2017
* fix urlDecode points

Fixes:

esp8266/Arduino#1989
esp8266/Arduino#2198

* Add missing separator between get and plain post arguments
@Jeroen88
Copy link
Contributor

According to https://www.ietf.org/rfc/rfc3986.txt this bugfix is incorrect. The separator should be missed if it is percent-encoded!

Excerpt of rfc3986:
2.2. Reserved Characters

URIs include components and subcomponents that are delimited by
characters in the "reserved" set. These characters are called
"reserved" because they may (or may not) be defined as delimiters by
the generic syntax, by each scheme-specific syntax, or by the
implementation-specific syntax of a URI's dereferencing algorithm.
If data for a URI component would conflict with a reserved
character's purpose as a delimiter, then the conflicting data must be
percent-encoded before the URI is formed.

  reserved    = gen-delims / sub-delims

  gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"

  sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
              / "*" / "+" / "," / ";" / "="

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants