]> granicus.if.org Git - php/commitdiff
MFB: Fixed bug #44938 (gettext functions crash with overly long domain).
authorIlia Alshanetsky <iliaa@php.net>
Wed, 29 Oct 2008 20:41:43 +0000 (20:41 +0000)
committerIlia Alshanetsky <iliaa@php.net>
Wed, 29 Oct 2008 20:41:43 +0000 (20:41 +0000)
NEWS
ext/gettext/gettext.c

diff --git a/NEWS b/NEWS
index 4d3919826660514adac7ba88a2918fbb792c8747..312bef1b80d2adc3e7906e6257ba68958a9c2db0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@ PHP                                                                        NEWS
   dynamicly created property). (Felipe)
 - Fixed bug #45529 (new DateTimeZone() and date_create()->getTimezone() behave
   different). (Derick)
+- Fixed bug #44938 (gettext functions crash with overly long domain).
+  (Christian Schneider, Ilia)
 - Fixed bug #43452 (strings containing a weekday, or a number plus weekday
   behaved incorrect of the current day-of-week was the same as the one in the
   phrase).(Derick)
index 63786bfa8789355e1885daff39704c44b4f6f2a4..f10b0f3b4f2a23892ff20c29a117142bcf1e3bd0 100644 (file)
@@ -144,6 +144,13 @@ zend_module_entry php_gettext_module_entry = {
 ZEND_GET_MODULE(php_gettext)
 #endif
 
+#define PHP_GETTEXT_MAX_DOMAIN_LENGTH 1024
+#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; \
+       }
+
 PHP_MINFO_FUNCTION(php_gettext)
 {
        php_info_print_table_start();
@@ -155,18 +162,17 @@ PHP_MINFO_FUNCTION(php_gettext)
    Set the textdomain to "domain". Returns the current domain */
 PHP_NAMED_FUNCTION(zif_textdomain)
 {
-       zval **domain;
-       char *domain_name, *retval;
-       char *val;
+       char *domain, *domain_name, *retval;
+       int domain_len;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &domain) == FAILURE) {
-               WRONG_PARAM_COUNT;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &domain, &domain_len) == FAILURE) {
+               return;
        }
-       convert_to_string_ex(domain);
 
-       val = Z_STRVAL_PP(domain);
-       if (strcmp(val, "") && strcmp(val, "0")) {
-               domain_name = val;
+       PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+
+       if (strcmp(domain, "") && strcmp(domain, "0")) {
+               domain_name = domain;
        } else {
                domain_name = NULL;
        }
@@ -181,15 +187,14 @@ PHP_NAMED_FUNCTION(zif_textdomain)
    Return the translation of msgid for the current domain, or msgid unaltered if a translation does not exist */
 PHP_NAMED_FUNCTION(zif_gettext)
 {
-       zval **msgid;
-       char *msgstr;
+       char *msgid, *msgstr;
+       int msgid_len;
 
-       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &msgid) == FAILURE) {
-               WRONG_PARAM_COUNT;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &msgid, &msgid_len) == FAILURE) {
+               return;
        }
-       convert_to_string_ex(msgid);
 
-       msgstr = gettext(Z_STRVAL_PP(msgid));
+       msgstr = gettext(msgid);
 
        RETURN_STRING(msgstr, 1);
 }
@@ -199,16 +204,16 @@ PHP_NAMED_FUNCTION(zif_gettext)
    Return the translation of msgid for domain_name, or msgid unaltered if a translation does not exist */
 PHP_NAMED_FUNCTION(zif_dgettext)
 {
-       zval **domain_name, **msgid;
-       char *msgstr;
+       char *domain, *msgid, *msgstr;
+       int domain_len, msgid_len;
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &domain_name, &msgid) == FAILURE) {
-               WRONG_PARAM_COUNT;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &msgid, &msgid_len) == FAILURE)        {
+               return;
        }
-       convert_to_string_ex(domain_name);
-       convert_to_string_ex(msgid);
 
-       msgstr = dgettext(Z_STRVAL_PP(domain_name), Z_STRVAL_PP(msgid));
+       PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+
+       msgstr = dgettext(domain, msgid);
 
        RETURN_STRING(msgstr, 1);
 }
@@ -218,17 +223,17 @@ PHP_NAMED_FUNCTION(zif_dgettext)
    Return the translation of msgid for domain_name and category, or msgid unaltered if a translation does not exist */
 PHP_NAMED_FUNCTION(zif_dcgettext)
 {
-       zval **domain_name, **msgid, **category;
-       char *msgstr;
+       char *domain, *msgid, *msgstr;
+       int domain_len, msgid_len;
+       long category;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &domain_name, &msgid, &category) == FAILURE) {
-               WRONG_PARAM_COUNT;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &domain, &domain_len, &msgid, &msgid_len, &category) == FAILURE) {
+               return;
        }
-       convert_to_string_ex(domain_name);
-       convert_to_string_ex(msgid);
-       convert_to_long_ex(category);
 
-       msgstr = dcgettext(Z_STRVAL_PP(domain_name), Z_STRVAL_PP(msgid), Z_LVAL_PP(category));
+       PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+
+       msgstr = dcgettext(domain, msgid, category);
 
        RETURN_STRING(msgstr, 1);
 }
@@ -238,29 +243,30 @@ PHP_NAMED_FUNCTION(zif_dcgettext)
    Bind to the text domain domain_name, looking for translations in dir. Returns the current domain */
 PHP_NAMED_FUNCTION(zif_bindtextdomain)
 {
-       zval **domain_name, **dir;
+       char *domain, *dir;
+       int domain_len, dir_len;
        char *retval, dir_name[MAXPATHLEN];
 
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &domain_name, &dir) == FAILURE) {
-               WRONG_PARAM_COUNT;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &dir, &dir_len) == FAILURE) {
+               return;
        }
-       convert_to_string_ex(domain_name);
-       convert_to_string_ex(dir);
 
-       if (Z_STRVAL_PP(domain_name)[0] == '\0') {
+       PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+
+       if (domain[0] == '\0') {
                php_error(E_WARNING, "The first parameter of bindtextdomain must not be empty");
                RETURN_FALSE;
        }
        
-       if (Z_STRVAL_PP(dir)[0] != '\0' && strcmp(Z_STRVAL_PP(dir), "0")) {
-               if (!VCWD_REALPATH(Z_STRVAL_PP(dir), dir_name)) {
+       if (dir[0] != '\0' && strcmp(dir, "0")) {
+               if (!VCWD_REALPATH(dir, dir_name)) {
                        RETURN_FALSE;
                }
        } else if (!VCWD_GETCWD(dir_name, MAXPATHLEN)) {
                RETURN_FALSE;
        }
 
-       retval = bindtextdomain(Z_STRVAL_PP(domain_name), dir_name);
+       retval = bindtextdomain(domain, dir_name);
 
        RETURN_STRING(retval, 1);
 }
@@ -271,22 +277,17 @@ PHP_NAMED_FUNCTION(zif_bindtextdomain)
    Plural version of gettext() */
 PHP_NAMED_FUNCTION(zif_ngettext)
 {
-       zval **msgid1, **msgid2, **count;
-       char *msgstr;
-
-       RETVAL_FALSE;
+       char *msgid1, *msgid2, *msgstr;
+       int msgid1_len, msgid2_len;
+       long count;
 
-       if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &msgid1, &msgid2, &count) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       } else {
-               convert_to_string_ex(msgid1);
-               convert_to_string_ex(msgid2);
-               convert_to_long_ex(count);
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssl", &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) {
+               return;
+       }
 
-               msgstr = ngettext(Z_STRVAL_PP(msgid1), Z_STRVAL_PP(msgid2), Z_LVAL_PP(count));
-               if (msgstr) {
-                       RETVAL_STRING (msgstr, 1);
-               }
+       msgstr = ngettext(msgid1, msgid2, count);
+       if (msgstr) {
+               RETVAL_STRING(msgstr, 1);
        }
 }
 /* }}} */
@@ -297,24 +298,20 @@ PHP_NAMED_FUNCTION(zif_ngettext)
    Plural version of dgettext() */
 PHP_NAMED_FUNCTION(zif_dngettext)
 {
-       zval **domain, **msgid1, **msgid2, **count;
+       char *domain, *msgid1, *msgid2, *msgstr = NULL;
+       int domain_len, msgid1_len, msgid2_len;
+       long count;
+       
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssl", &domain, &domain_len,
+               &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count) == FAILURE) {
+               return;
+       }
 
-       RETVAL_FALSE;
+       PHP_GETTEXT_DOMAIN_LENGTH_CHECK
 
-       if (ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &domain, &msgid1, &msgid2, &count) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       } else {
-               char *msgstr;
-               
-               convert_to_string_ex(domain);
-               convert_to_string_ex(msgid1);
-               convert_to_string_ex(msgid2);
-               convert_to_long_ex(count);
-
-               msgstr = dngettext(Z_STRVAL_PP(domain), Z_STRVAL_PP(msgid1), Z_STRVAL_PP(msgid2), Z_LVAL_PP(count));
-               if (msgstr) {
-                       RETVAL_STRING(msgstr, 1);
-               }
+       msgstr = dngettext(domain, msgid1, msgid2, count);
+       if (msgstr) {
+               RETVAL_STRING(msgstr, 1);
        }
 }
 /* }}} */
@@ -325,26 +322,23 @@ PHP_NAMED_FUNCTION(zif_dngettext)
    Plural version of dcgettext() */                                                            
 PHP_NAMED_FUNCTION(zif_dcngettext)
 {
-       zval **domain, **msgid1, **msgid2, **count, **category;
+       char *domain, *msgid1, *msgid2, *msgstr = NULL;
+       int domain_len, msgid1_len, msgid2_len;
+       long count, category;
 
        RETVAL_FALSE;
 
-       if (ZEND_NUM_ARGS() != 5 || zend_get_parameters_ex(5, &domain, &msgid1, &msgid2, &count, &category) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       } else {
-               char* msgstr = NULL;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssll", &domain, &domain_len,
+               &msgid1, &msgid1_len, &msgid2, &msgid2_len, &count, &category) == FAILURE) {
+               return;
+       }
 
-               convert_to_string_ex(domain);
-               convert_to_string_ex(msgid1);
-               convert_to_string_ex(msgid2);
-               convert_to_long_ex(count);
-               convert_to_long_ex(category);
+       PHP_GETTEXT_DOMAIN_LENGTH_CHECK
 
-               msgstr = dcngettext(Z_STRVAL_PP(domain), Z_STRVAL_PP(msgid1), Z_STRVAL_PP(msgid2), Z_LVAL_PP(count), Z_LVAL_PP(category));
+       msgstr = dcngettext(domain, msgid1, msgid2, count, category);
 
-               if (msgstr) {
-                       RETVAL_STRING(msgstr, 1);
-               }
+       if (msgstr) {
+               RETVAL_STRING(msgstr, 1);
        }
 }
 /* }}} */
@@ -356,22 +350,21 @@ PHP_NAMED_FUNCTION(zif_dcngettext)
    Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. */
 PHP_NAMED_FUNCTION(zif_bind_textdomain_codeset)
 {
-       zval **domain, **codeset;
-       char *retval;
-       
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &domain, &codeset) == FAILURE) {
-               WRONG_PARAM_COUNT;
-       } else {
-               convert_to_string_ex(domain);
-               convert_to_string_ex(codeset);
-               
-               retval = bind_textdomain_codeset(Z_STRVAL_PP(domain), Z_STRVAL_PP(codeset));
+       char *domain, *codeset, *retval = NULL;
+       int domain_len, codeset_len;
 
-               if (!retval) {
-                       RETURN_FALSE;
-               }
-               RETURN_STRING(retval, 1);
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &domain, &domain_len, &codeset, &codeset_len) == FAILURE) {
+               return;
        }
+
+       PHP_GETTEXT_DOMAIN_LENGTH_CHECK
+
+       retval = bind_textdomain_codeset(domain, codeset);
+
+       if (!retval) {
+               RETURN_FALSE;
+       }
+       RETURN_STRING(retval, 1);
 }
 /* }}} */
 #endif