lstrojny                Thu Oct 30 14:22:21 2008 UTC

  Added files:                 
    /php-src/ext/gettext/tests  44938.phpt 

  Modified files:              
    /php-src/ext/gettext        gettext.c 
  Log:
  The real fix for the gettext overflow bug
   - The overflow issue was not limited to domains, but also present for msgids
   - [DOC] msgids are now limited to 4096 chars, domains to 1024
  
  
http://cvs.php.net/viewvc.cgi/php-src/ext/gettext/gettext.c?r1=1.59&r2=1.60&diff_format=u
Index: php-src/ext/gettext/gettext.c
diff -u php-src/ext/gettext/gettext.c:1.59 php-src/ext/gettext/gettext.c:1.60
--- php-src/ext/gettext/gettext.c:1.59  Wed Oct 29 21:02:14 2008
+++ php-src/ext/gettext/gettext.c       Thu Oct 30 14:22:21 2008
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: gettext.c,v 1.59 2008/10/29 21:02:14 iliaa Exp $ */
+/* $Id: gettext.c,v 1.60 2008/10/30 14:22:21 lstrojny Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -136,12 +136,35 @@
 #endif
 
 #define PHP_GETTEXT_MAX_DOMAIN_LENGTH 1024
+#define PHP_GETTEXT_MAX_MSGID_LENGTH 4096
+
 #define PHP_GETTEXT_DOMAIN_LENGTH_CHECK \
        if (domain_len > PHP_GETTEXT_MAX_DOMAIN_LENGTH) { \
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "domain passed too 
long"); \
                RETURN_FALSE; \
        }
 
+#define PHP_GETTEXT_MSGID_LENGTH_CHECK \
+       char *check_name = "msgid"; \
+       int check_len   = msgid_len; \
+       PHP_GETTEXT_LENGTH_CHECK
+
+#define PHP_GETTEXT_LENGTH_CHECK \
+       if (check_len > PHP_GETTEXT_MAX_MSGID_LENGTH) { \
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s passed too 
long", check_name); \
+               RETURN_FALSE; \
+       }
+
+#define PHP_GETTEXT_MULTI_MSGID_LENGTH_CHECK \
+       int check_len; \
+       char *check_name; \
+       check_name = "msgid1"; \
+       check_len = msgid_len1; \
+       PHP_GETTEXT_LENGTH_CHECK \
+       check_name = "msgid2"; \
+       check_len = msgid_len2; \
+       PHP_GETTEXT_LENGTH_CHECK
+
 PHP_MINFO_FUNCTION(php_gettext)
 {
        php_info_print_table_start();
@@ -184,10 +207,13 @@
 {
        char *msgid_str;
        int msgid_len;
-       
+
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s&", 
&msgid_str, &msgid_len, UG(ascii_conv))) {
                return;
        }
+
+       PHP_GETTEXT_MSGID_LENGTH_CHECK
+
        RETURN_STRING(gettext(msgid_str), ZSTR_DUPLICATE);
 }
 /* }}} */
@@ -204,6 +230,7 @@
        }
 
        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+       PHP_GETTEXT_MSGID_LENGTH_CHECK
 
        RETURN_STRING(dgettext(domain_str, msgid_str), ZSTR_DUPLICATE);
 }
@@ -222,6 +249,7 @@
        }
 
        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+       PHP_GETTEXT_MSGID_LENGTH_CHECK
 
        RETURN_STRING(dcgettext(domain_str, msgid_str, category), 
ZSTR_DUPLICATE);
 }
@@ -263,11 +291,13 @@
        char *msgid_str1, *msgid_str2, *msgstr;
        int msgid_len1, msgid_len2;
        long count;
-       
+
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
"s&s&l", &msgid_str1, &msgid_len1, UG(ascii_conv), &msgid_str2, &msgid_len2, 
UG(ascii_conv), &count)) {
                RETURN_FALSE;
        }
-       
+
+       PHP_GETTEXT_MULTI_MSGID_LENGTH_CHECK
+
        if ((msgstr = ngettext(msgid_str1, msgid_str2, count))) {
                RETURN_STRING(msgstr, ZSTR_DUPLICATE);
        } else {
@@ -291,6 +321,7 @@
        }
 
        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+       PHP_GETTEXT_MULTI_MSGID_LENGTH_CHECK
 
        if ((msgstr = dngettext(domain_str, msgid_str1, msgid_str2, count))) {
                RETURN_STRING(msgstr, ZSTR_DUPLICATE);
@@ -315,6 +346,7 @@
        }
 
        PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+       PHP_GETTEXT_MULTI_MSGID_LENGTH_CHECK
 
        if ((msgstr = dcngettext(domain_str, msgid_str1, msgid_str2, count, 
category))) {
                RETURN_STRING(msgstr, ZSTR_DUPLICATE);

http://cvs.php.net/viewvc.cgi/php-src/ext/gettext/tests/44938.phpt?view=markup&rev=1.1
Index: php-src/ext/gettext/tests/44938.phpt
+++ php-src/ext/gettext/tests/44938.phpt
--TEST--
#44938: gettext functions crash with overlong strings
--SKIPIF--
<?php
if (!extension_loaded("gettext")) {
        die("skip\n");
}
--FILE--
<?php
$overflown = str_repeat('C', 8476509);
$msgid     = "msgid";
$domain    = "domain";
$category  = "cat";

var_dump(bindtextdomain($overflown, 'path'));

var_dump(dngettext($overflown, $msgid, $msgid, 1));
var_dump(dngettext($domain, $overflown, $msgid, 1));
var_dump(dngettext($domain, $msgid, $overflown, 1));

var_dump(gettext($overflown));

var_dump(ngettext($overflown, $msgid, -1));
var_dump(ngettext($msgid, $overflown, -1));

var_dump(dcgettext($overflown, $msgid, -1));
var_dump(dcgettext($domain, $overflown, -1));

var_dump(dcngettext($overflown, $msgid, $msgid, -1, -1));
var_dump(dcngettext($domain, $overflown, $msgid, -1, -1));
var_dump(dcngettext($domain, $msgid, $overflown, -1, -1));

var_dump(dgettext($overflown, $msgid));
var_dump(dgettext($domain, $overflown));

var_dump(textdomain($overflown));
?>
==DONE==
--EXPECTF--

Warning: bindtextdomain(): domain passed too long in %s on line %d
bool(false)

Warning: dngettext(): domain passed too long in %s on line %d
bool(false)

Warning: dngettext(): msgid1 passed too long in %s on line %d
bool(false)

Warning: dngettext(): msgid2 passed too long in %s on line %d
bool(false)

Warning: gettext(): msgid passed too long in %s on line %d
bool(false)

Warning: ngettext(): msgid1 passed too long in %s on line %d
bool(false)

Warning: ngettext(): msgid2 passed too long in %s on line %d
bool(false)

Warning: dcgettext(): domain passed too long in %s on line %d
bool(false)

Warning: dcgettext(): msgid passed too long in %s on line %d
bool(false)

Warning: dcngettext(): domain passed too long in %s on line %d
bool(false)

Warning: dcngettext(): msgid1 passed too long in %s on line %d
bool(false)

Warning: dcngettext(): msgid2 passed too long in %s on line %d
bool(false)

Warning: dgettext(): domain passed too long in %s on line %d
bool(false)

Warning: dgettext(): msgid passed too long in %s on line %d
bool(false)

Warning: textdomain(): domain passed too long in %s on line %d
bool(false)
==DONE==



-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to