]> granicus.if.org Git - php/commitdiff
Separate implementation of mb_{en,de}code_numericentity
authorAlex Dowad <alexinbeijing@gmail.com>
Fri, 3 Jul 2020 19:52:27 +0000 (21:52 +0200)
committerAlex Dowad <alexinbeijing@gmail.com>
Mon, 31 Aug 2020 21:16:28 +0000 (23:16 +0200)
Rather than using a magic boolean parameter to choose different behavior of
the subfunction, inline it. The code size doesn't really grow anyways. And
soon these will be trimmed down more.

ext/mbstring/mbstring.c

index e84f78bb3a989e92af566dc587c7457654783a62..0f5e91a4d4cffc7d88b9584069ac8a6222f918a6 100644 (file)
@@ -3281,64 +3281,62 @@ PHP_FUNCTION(mb_convert_variables)
 }
 /* }}} */
 
-/* {{{ HTML numeric entity */
-/* {{{ static void php_mb_numericentity_exec() */
-static void
-php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type)
+/* HTML numeric entities */
+
+/* Convert PHP array to data structure required by mbfl_html_numeric_entity */
+static int* make_conversion_map(HashTable *target_hash, int *convmap_size)
+{
+       zval *hash_entry;
+
+       int n_elems = zend_hash_num_elements(target_hash);
+       if (n_elems % 4 != 0) {
+               zend_argument_value_error(2, "must have a multiple of 4 elements");
+               return NULL;
+       }
+
+       int *convmap = (int *)safe_emalloc(n_elems, sizeof(int), 0);
+       int *mapelm = convmap;
+       int mapsize = 0;
+
+       ZEND_HASH_FOREACH_VAL(target_hash, hash_entry) {
+               *mapelm++ = zval_get_long(hash_entry);
+               mapsize++;
+       } ZEND_HASH_FOREACH_END();
+
+       *convmap_size = mapsize / 4;
+       return convmap;
+}
+
+/* {{{ Converts specified characters to HTML numeric entities */
+PHP_FUNCTION(mb_encode_numericentity)
 {
        char *str = NULL;
-       size_t str_len;
        zend_string *encoding = NULL;
-       zval *hash_entry;
+       int mapsize;
        HashTable *target_hash;
-       int i, *convmap, *mapelm, mapsize=0;
        zend_bool is_hex = 0;
        mbfl_string string, result, *ret;
 
-       if (type == 0) {
-               ZEND_PARSE_PARAMETERS_START(2, 4)
-                       Z_PARAM_STRING(str, str_len)
-                       Z_PARAM_ARRAY_HT(target_hash)
-                       Z_PARAM_OPTIONAL
-                       Z_PARAM_STR(encoding)
-                       Z_PARAM_BOOL(is_hex)
-               ZEND_PARSE_PARAMETERS_END();
-       } else {
-               ZEND_PARSE_PARAMETERS_START(2, 3)
-                       Z_PARAM_STRING(str, str_len)
-                       Z_PARAM_ARRAY_HT(target_hash)
-                       Z_PARAM_OPTIONAL
-                       Z_PARAM_STR(encoding)
-               ZEND_PARSE_PARAMETERS_END();
-       }
+       ZEND_PARSE_PARAMETERS_START(2, 4)
+               Z_PARAM_STRING(str, string.len)
+               Z_PARAM_ARRAY_HT(target_hash)
+               Z_PARAM_OPTIONAL
+               Z_PARAM_STR(encoding)
+               Z_PARAM_BOOL(is_hex)
+       ZEND_PARSE_PARAMETERS_END();
 
        string.val = (unsigned char *)str;
-       string.len = str_len;
        string.encoding = php_mb_get_encoding(encoding, 3);
        if (!string.encoding) {
                RETURN_THROWS();
        }
 
-       if (type == 0 && is_hex) {
-               type = 2; /* output in hex format */
-       }
-
-       /* conversion map */
-       i = zend_hash_num_elements(target_hash);
-       if (i % 4 != 0) {
-               zend_argument_value_error(2, "must have a multiple of 4 elements");
+       int *convmap = make_conversion_map(target_hash, &mapsize);
+       if (convmap == NULL) {
                RETURN_THROWS();
        }
-       convmap = (int *)safe_emalloc(i, sizeof(int), 0);
-       mapelm = convmap;
-       mapsize = 0;
-       ZEND_HASH_FOREACH_VAL(target_hash, hash_entry) {
-               *mapelm++ = zval_get_long(hash_entry);
-               mapsize++;
-       } ZEND_HASH_FOREACH_END();
-       mapsize /= 4;
 
-       ret = mbfl_html_numeric_entity(&string, &result, convmap, mapsize, type);
+       ret = mbfl_html_numeric_entity(&string, &result, convmap, mapsize, is_hex ? 2 : 0);
        ZEND_ASSERT(ret != NULL);
        // TODO: avoid reallocation ???
        RETVAL_STRINGL((char *)ret->val, ret->len);
@@ -3347,20 +3345,41 @@ php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAMETERS, int type)
 }
 /* }}} */
 
-/* {{{ Converts specified characters to HTML numeric entities */
-PHP_FUNCTION(mb_encode_numericentity)
-{
-       php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
-}
-/* }}} */
-
 /* {{{ Converts HTML numeric entities to character code */
 PHP_FUNCTION(mb_decode_numericentity)
 {
-       php_mb_numericentity_exec(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
+       char *str = NULL;
+       zend_string *encoding = NULL;
+       int mapsize;
+       HashTable *target_hash;
+       mbfl_string string, result, *ret;
+
+       ZEND_PARSE_PARAMETERS_START(2, 3)
+               Z_PARAM_STRING(str, string.len)
+               Z_PARAM_ARRAY_HT(target_hash)
+               Z_PARAM_OPTIONAL
+               Z_PARAM_STR(encoding)
+       ZEND_PARSE_PARAMETERS_END();
+
+       string.val = (unsigned char *)str;
+       string.encoding = php_mb_get_encoding(encoding, 3);
+       if (!string.encoding) {
+               RETURN_THROWS();
+       }
+
+       int *convmap = make_conversion_map(target_hash, &mapsize);
+       if (convmap == NULL) {
+               RETURN_THROWS();
+       }
+
+       ret = mbfl_html_numeric_entity(&string, &result, convmap, mapsize, 1);
+       ZEND_ASSERT(ret != NULL);
+       // TODO: avoid reallocation ???
+       RETVAL_STRINGL((char *)ret->val, ret->len);
+       efree(ret->val);
+       efree((void *)convmap);
 }
 /* }}} */
-/* }}} */
 
 /* {{{ Sends an email message with MIME scheme */