Branch: Tag:

2016-10-28

2016-10-28 13:43:49 by Henrik Grubbström (Grubba) <grubba@grubba.org>

HTTP [Pike 8.0]: Survive invalidly %-encoded requests again.

Roxen.http_decode_string() in Pike 8.0 throws errors for invalidly
%-encoded strings.

Behavior is now as follows:

* Invalidly %-encoded query-variables or cookies -- assume that the
erroneous query-variable or cookie was sent unencoded.

* Invalidly %-encoded path -- generate a bad request (400) error.

Fixes [bug 7818 (#7818)].

2:   // Modified by Francesco Chemolli to add throttling capabilities.   // Copyright © 1996 - 2004, Roxen IS.    - constant cvs_version = "$Id: http.pike,v 1.590 2009/03/21 18:25:14 mast Exp $"; + constant cvs_version = "$Id$";   // #define REQUEST_DEBUG   #define MAGIC_ERROR   
483: Inside #if 0
   while(sizeof(c) && c[0]==' ') c=c[1..];    if(sscanf(c, "%s=%s", name, value) == 2)    { +  // NB: Assume invalidly %-encoded values are unencoded. +  // Fixes [bug 7818]. +  catch {    value=http_decode_string(value); -  +  }; +  catch {    name=http_decode_string(name); -  +  };    cookies[ name ]=value;   #ifdef OLD_RXML_CONFIG    if( (name == "RoxenConfig") && strlen(value) )
570:    if (query)    split_query_vars (query, vars);    +  if (mixed err = catch { +  f = http_decode_string(f); +  }) { +  report_debug("Client %O sent an invalidly %%-encoded query: %O: %s", +  client_var->fullname, f, describe_error(err)); +  return invalid_request(); +  } +     if (sizeof (vars)) {    decode_query: {    if (input_charset) {    if (mixed err = catch { -  f = decode_query_charset (_Roxen.http_decode_string (f), -  vars, input_charset); +  f = decode_query_charset(f, vars, input_charset);    }) {    report_debug ("Client %O sent query %O which failed to decode "    "with its own charset %O: %s",
586:    else break decode_query;    }    -  f = decode_query_charset (_Roxen.http_decode_string (f), -  vars, "roxen-http-default"); +  f = decode_query_charset(f, vars, "roxen-http-default");    }       if (input_charset && misc->post_variables) {
632:    // No variables to decode, only the path. Optimize    // decode_query with "roxen-http-default" since we know    // there's no magic_roxen_automatic_charset_variable. -  f = http_decode_string (f); +     if (input_charset) {    if (mixed err = catch {    f = Roxen.get_decoder_for_client_charset (input_charset) (f);
1666:   #endif /* INTERNAL_ERROR_DEBUG */   }    + protected int(1..1) invalid_request() + { +  file = Roxen.http_low_answer(400, "<html><body><h1>Client error: Invalid request.</h1></body></html>\n"); +  roxen.handle(send_result); +  return 1; + } +    // This macro ensures that something gets reported even when the very   // call to internal_error() fails. That happens eg when this_object()   // has been destructed.