browscap.ini module error + fix

From: Date: Sun, 27 Apr 2003 10:59:21 +0000
Subject: browscap.ini module error + fix
Groups: php.internals 
Request: Send a blank email to internals+get-1048@lists.php.net to get a copy of this message
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

« previous php.internals (#1048) next »