Bug 17564

Summary: Somtimes mod_negotiation fails select right variant
Product: Apache httpd-1.3 Reporter: Maxim Zakharov <maxime>
Component: Other modsAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: CLOSED FIXED    
Severity: normal CC: utx
Priority: P3    
Version: 1.3.27   
Target Milestone: ---   
Hardware: PC   
OS: FreeBSD   

Description Maxim Zakharov 2003-03-01 19:43:01 UTC
Sometimes mod_negotiation fails to select right veriant. At once after restart
it works, but after several page reloads it get 406 Not Acceptaple. This hapens
if, for exaple, browse send following headers

Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
Accept-Charset: KOI8-R, utf-8;q=0.66, *;q=0.66
Accept-Language: ru, en;q=0.66, fr;q=0.33

After server restart atof at line 392 of mod_negotiation.c:
 result->quality = (float)atof(cp);
works right

text/html Quality: 0.9 -> 0.900000
text/plain Quality: 0.8 -> 0.800000
image/gif Quality: 0.2 -> 0.200000
*/* Quality: 0.1 -> 0.100000
compress Quality: 0.9 -> 0.900000
en Quality: 0.66 -> 0.660000
fr Quality: 0.33 -> 0.330000
utf-8 Quality: 0.66 -> 0.660000
* Quality: 0.66 -> 0.660000

(value before '->' is string passed as argument for atof function, value after -
is a value returned by atof)

Buf after i get 406 (Not Acceptable) it look like
text/html Quality: 0.9 -> 0,000000
text/plain Quality: 0.8 -> 0,000000
image/gif Quality: 0.2 -> 0,000000
*/* Quality: 0.1 -> 0,000000
compress Quality: 0.9 -> 0,000000
en Quality: 0.66 -> 0,000000
fr Quality: 0.33 -> 0,000000
utf-8 Quality: 0.66 -> 0,000000
* Quality: 0.66 -> 0,000000

If i change atof call at line 392 for this function:

static float ap_atoq(const char *str) {
  float result1 = atof(str);
  float result2 = 0.0;
  char *p = strchr(str, '.'), *d;
  
  if (p != NULL) {
    *p = ',';
    result2 = atof(str);
  } else {
    d = strchr(str, ',');
    if (d != NULL) {
      *d = '.';
      result2 = atof(str);
    }
  }
  if (result2 > result1) return result2;
  return result1;
}

it seems all work fine.

Probably, httpd-2.0 is also affected.
Comment 1 André Malo 2003-03-08 18:16:26 UTC
I'm not sure whether I fully understand your report.
Why should we parse wrong numbers with commas in it?

...err, I think, I start to understand. The atof function is dependent on some
locale settings?
Comment 2 Maxim Zakharov 2003-03-08 18:43:40 UTC
In some locales (include russian), comma is used as decimal point separator.
Thus atof function under such locales is false to parse right variant weight
with dot as desimal point separator.
Comment 3 André Malo 2003-03-11 00:28:25 UTC
Well, I've fixed the problem by dropping atof() entirely (and writing our own
more RFC compliant version).
The fix currently applies to version 2.1 (main dev branch) and is proposed for
backport.

Thanks for your report and thanks for using Apache!
Comment 4 André Malo 2003-05-13 00:55:21 UTC
*** Bug 9427 has been marked as a duplicate of this bug. ***
Comment 5 Joshua Slive 2003-05-24 18:06:35 UTC
Sounds fixed to me.