Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ MBString:
. Improved performance of array functions with callbacks
(array_find, array_filter, array_map, usort, ...).
. Improved performance of urlencode() and rawurlencode().
. Improved unpack() performance with nameless repetitions by avoiding
creating temporary strings and reparsing them.

- XMLReader:
. Improved property access performance.
Expand Down
38 changes: 20 additions & 18 deletions ext/standard/pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -885,12 +885,15 @@ PHP_FUNCTION(unpack)
if ((inputpos + size) <= inputlen) {

zend_string* real_name;
zend_long long_key = 0;
zval val;

if (repetitions == 1 && namelen > 0) {
/* Use a part of the formatarg argument directly as the name. */
real_name = zend_string_init_fast(name, namelen);

} else if (namelen == 0) {
real_name = NULL;
long_key = i + 1;
} else {
/* Need to add the 1-based element number to the name */
char buf[MAX_LENGTH_OF_LONG + 1];
Expand All @@ -912,7 +915,6 @@ PHP_FUNCTION(unpack)
size = len;

ZVAL_STRINGL(&val, &input[inputpos], len);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}
case 'A': {
Expand All @@ -939,7 +941,6 @@ PHP_FUNCTION(unpack)
}

ZVAL_STRINGL(&val, &input[inputpos], len + 1);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}
/* New option added for Z to remain in-line with the Perl implementation */
Expand All @@ -964,7 +965,6 @@ PHP_FUNCTION(unpack)
len = s;

ZVAL_STRINGL(&val, &input[inputpos], len);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}

Expand All @@ -979,7 +979,9 @@ PHP_FUNCTION(unpack)


if (size > INT_MAX / 2) {
zend_string_release(real_name);
if (real_name) {
zend_string_release_ex(real_name, false);
}
zend_argument_value_error(1, "repeater must be less than or equal to %d", INT_MAX / 2);
RETURN_THROWS();
}
Expand Down Expand Up @@ -1016,7 +1018,6 @@ PHP_FUNCTION(unpack)
ZSTR_VAL(buf)[len] = '\0';

ZVAL_STR(&val, buf);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}

Expand All @@ -1026,7 +1027,6 @@ PHP_FUNCTION(unpack)
zend_long v = (type == 'c') ? (int8_t) x : x;

ZVAL_LONG(&val, v);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}

Expand All @@ -1046,7 +1046,6 @@ PHP_FUNCTION(unpack)
}

ZVAL_LONG(&val, v);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}

Expand All @@ -1062,7 +1061,6 @@ PHP_FUNCTION(unpack)
}

ZVAL_LONG(&val, v);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}

Expand All @@ -1082,8 +1080,6 @@ PHP_FUNCTION(unpack)
}

ZVAL_LONG(&val, v);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);

break;
}

Expand All @@ -1104,7 +1100,6 @@ PHP_FUNCTION(unpack)
}

ZVAL_LONG(&val, v);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}
#endif
Expand All @@ -1124,7 +1119,6 @@ PHP_FUNCTION(unpack)
}

ZVAL_DOUBLE(&val, v);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}

Expand All @@ -1143,13 +1137,12 @@ PHP_FUNCTION(unpack)
}

ZVAL_DOUBLE(&val, v);
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
break;
}

case 'x':
/* Do nothing with input, just skip it */
break;
goto no_output;

case 'X':
if (inputpos < size) {
Expand All @@ -1160,7 +1153,7 @@ PHP_FUNCTION(unpack)
php_error_docref(NULL, E_WARNING, "Type %c: outside of string", type);
}
}
break;
goto no_output;

case '@':
if (repetitions <= inputlen) {
Expand All @@ -1170,10 +1163,19 @@ PHP_FUNCTION(unpack)
}

i = repetitions - 1; /* Done, break out of for loop */
break;
goto no_output;
}

zend_string_release(real_name);
if (real_name) {
zend_symtable_update(Z_ARRVAL_P(return_value), real_name, &val);
} else {
zend_hash_index_update(Z_ARRVAL_P(return_value), long_key, &val);
}

no_output:
if (real_name) {
zend_string_release_ex(real_name, false);
}

inputpos += size;
if (inputpos < 0) {
Expand Down
Loading