[mod-xhtml-neg-cvs] mod_xhtml_neg-2.0 mod_xhtml_neg.c,1.23,1.24
Brought to you by:
run2000
From: <ru...@us...> - 2004-04-11 00:16:29
|
Update of /cvsroot/mod-xhtml-neg/mod_xhtml_neg-2.0 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17036 Modified Files: mod_xhtml_neg.c Log Message: Parse q-values more in keeping with RFC2616. This now always works the same way regardless of system locale. Index: mod_xhtml_neg.c =================================================================== RCS file: /cvsroot/mod-xhtml-neg/mod_xhtml_neg-2.0/mod_xhtml_neg.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** mod_xhtml_neg.c 2 Apr 2004 10:41:19 -0000 1.23 --- mod_xhtml_neg.c 11 Apr 2004 00:02:55 -0000 1.24 *************** *** 77,81 **** * @author Nicholas Cull <ru...@us...> * @date 1 March 2004 ! * @version 0.93 * * @history --- 77,81 ---- * @author Nicholas Cull <ru...@us...> * @date 1 March 2004 ! * @version 0.94 * * @history *************** *** 87,90 **** --- 87,91 ---- * 0.92 Pick up the AddDefaultCharset directive from the Apache core \n * 0.93 Use a better hash function for ETag uniqueness \n + * 0.94 Parse q-values correctly irrespective of system locale \n * * @directive *************** *** 496,499 **** --- 497,567 ---- } + /* + * Taken from a mod_negotiation fix on the Apache 2.1 branch. + */ + + /** + * Parse quality value. atof(3) is not well-usable here, because it depends + * on the locale (argh). + * + * However, RFC 2616 states: \n + * 3.9 Quality Values + * + * [...] HTTP/1.1 applications MUST NOT generate more than three digits + * after the decimal point. User configuration of these values SHOULD also + * be limited in this fashion. + * + * qvalue = ( "0" [ "." 0*3DIGIT ] ) + * | ( "1" [ "." 0*3("0") ] ) + * + * This is quite easy. If the supplied string doesn't match the above + * definition (loosely), we simply return 1 (same as if there's no q-value) + * + * @param string a string containing a q-value to be parsed + * @return the parsed q-value, truncated to three decimal places if necessary + */ + + static float mod_xhtml_atoq(const char *string) + { + if (mod_xhtml_strempty(string)) { + return 1.0f; + } + + while (*string && apr_isspace(*string)) { + ++string; + } + + /* Be tolerant and accept qvalues without leading zero + * (also for backwards compat, where atof() was in use) + * This also handles the 1.0 case. + */ + if (*string != '.' && *string++ != '0') { + return 1.0f; + } + + if (*string == '.') { + /* Better only one division later, than dealing with fscking + * IEEE format 0.1 factors ... + */ + int i = 0; + + if (*++string >= '0' && *string <= '9') { + i += (*string - '0') * 100; + + if (*++string >= '0' && *string <= '9') { + i += (*string - '0') * 10; + + if (*++string > '0' && *string <= '9') { + i += (*string - '0'); + } + } + } + + return (float)i / 1000.0f; + } + + return 0.0f; + } + /** * This naughty function goes digging into the Apache http_core module *************** *** 850,854 **** if (parm[0] == 'q' && (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0'))) { ! result->q_value = (float)atof(cp); } else if (mod_xhtml_strcmp(parm, "charset") == 0) { --- 918,922 ---- if (parm[0] == 'q' && (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0'))) { ! result->q_value = (float)mod_xhtml_atoq(cp); } else if (mod_xhtml_strcmp(parm, "charset") == 0) { |