There is a small error in the browscap.ini in PHP4.3.2 RC and PHP 5 which
makes thedetection of for example Internet Explorer wrong:
This is a example from browscap.ini:
>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IE 5.5
>[IE 5.5]
>browser=IE
>version=5.5
>majorver=5
>minorver=5
>css=2
>frames=True
>iframes=True
>tables=True
>cookies=True
>backgroundsounds=True
>vbscript=True
>javascript=True
>javaapplets=True
>activexcontrols=True
>ak=False
>sk=False
>cdf=True
>aol=False
>beta=False
>win16=False
>crawler=False
>stripper=False
>wap=False
>netclr=False
>
>[Mozilla/4.0 (compatible; MSIE 5.5*;*AOL *Win 9x 4.90*)*]
>parent=IE 5.5
>platform=WinME
>aol=True
The problem is now: If the client sends as User agent: "Mozilla/4.0
(compatible; MSIE 5.5; AOL Win 9x 4.90)" the browscap.c scans the ini file
until it finds the first match. In the above example the regex created from
[IE 5.5] is "IE 5\.5", the second one "Mozilla/4\.0 (compatible; MSIE
5.5.*;*AOL .*Win 9x 4\.90.*).*", but the first one matches first to the
user agent, which does not give the platform back to the php script.
The error is that the pattern must match the WHOLE string!
So I modified the browscap.c file that it adds a ^ at the beginning of
regex and a $ at the end of regex. After that all browsers are detected
exactly like in ASP. Browsers with errors are: IE, Konqueror, some spiders...
The modification looks like that:
>/* {{{ convert_browscap_pattern
> */
>static void convert_browscap_pattern(zval *pattern)
>{
> register int i, j;
> char *t;
>
> for (i=0; i<Z_STRLEN_P(pattern); i++) {
> if (Z_STRVAL_P(pattern)[i]=='*' ||
> Z_STRVAL_P(pattern)[i]=='?' || Z_STRVAL_P(pattern)[i]=='.') {
> break;
> }
> }
>
> if (i==Z_STRLEN_P(pattern)) { /* no wildcards */
> Z_STRVAL_P(pattern) = zend_strndup(Z_STRVAL_P(pattern),
> Z_STRLEN_P(pattern));
> return;
> }
>
> t = (char *) malloc(Z_STRLEN_P(pattern)*2 + 3);
> t[0]='^';
>
> for (i=0, j=1; i<Z_STRLEN_P(pattern); i++, j++) {
> switch (Z_STRVAL_P(pattern)[i]) {
> case '?':
> t[j] = '.';
> break;
> case '*':
> t[j++] = '.';
> t[j] = '*';
> break;
> case '.':
> t[j++] = '\\';
> t[j] = '.';
> break;
> default:
> t[j] = Z_STRVAL_P(pattern)[i];
> break;
> }
> }
>
> if (j && (t[j-1] == '.')) {
> t[j++] = '*';
> }
>
> t[j++]='$';
>
> t[j]=0;
> Z_STRVAL_P(pattern) = t;
> Z_STRLEN_P(pattern) = j;
>}
>/* }}} */
If you also think thats right can you give my thetaphi@php.net CVS account
write access to ext/standard, i will then submit the modifications?
Uwe