mirror of
https://github.com/php/php-src.git
synced 2024-11-25 19:05:31 +08:00
Merge branch 'PHP-7.0' of https://github.com/php/php-src into PHP-7.0
This commit is contained in:
commit
daf3d0c875
@ -53,7 +53,7 @@ install-headers:
|
||||
paths="$$paths $(INSTALL_ROOT)$(phpincludedir)/$$i"; \
|
||||
done; \
|
||||
$(mkinstalldirs) $$paths && \
|
||||
echo "Installing header files: $(INSTALL_ROOT)$(phpincludedir)/" && \
|
||||
echo "Installing header files: $(INSTALL_ROOT)$(phpincludedir)/" && \
|
||||
for i in `echo $(INSTALL_HEADERS)`; do \
|
||||
if test "$(PHP_PECL_EXTENSION)"; then \
|
||||
src=`echo $$i | $(SED) -e "s#ext/$(PHP_PECL_EXTENSION)/##g"`; \
|
||||
|
109
NEWS
109
NEWS
@ -2,25 +2,69 @@ PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? 2016 PHP 7.0.4
|
||||
|
||||
- Core:
|
||||
. Fixed bug (Low probability segfault in zend_arena). (Laruence)
|
||||
. Fixed bug #71485 (Return typehint on interanal func causes Fatal error
|
||||
when it throws exception). (Laruence)
|
||||
. Fixed bug #71474 (Crash because of VM stack corruption on Magento2).
|
||||
(Dmitry)
|
||||
. Fixed bug #71450 (An integer overflow bug in php_str_to_str_ex()). (Stas)
|
||||
. Fixed bug #71449 (An integer overflow bug in php_implode()). (Stas)
|
||||
. Fixed bug #71443 (Segfault using built-in webserver with intl using
|
||||
symfony). (Laruence)
|
||||
. Fixed bug #71442 (forward_static_call crash). (Laruence)
|
||||
. Fixed bug #71441 (Typehinted Generator with return in try/finally crashes).
|
||||
(Bob)
|
||||
. Fixed bug #71529 (Variable references on array elements don't work when
|
||||
using count). (Nikita)
|
||||
|
||||
- PCRE:
|
||||
. Fixed bug #71537 (PCRE segfault from Opcache). (Laruence)
|
||||
|
||||
- CURL:
|
||||
. Fixed bug #71523 (Copied handle with new option CURLOPT_HTTPHEADER crashes
|
||||
while curl_multi_exec). (Laruence)
|
||||
. Fixed memory leak in curl_getinfo(). (Leigh)
|
||||
|
||||
- Fileinfo:
|
||||
. Fixed bug #71434 (finfo throws notice for specific python file). (Laruence)
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #62172 (FPM not working with Apache httpd 2.4 balancer/fcgi
|
||||
setup). (Matt Haught, Remi)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #70720 (strip_tags improper php code parsing). (Julien)
|
||||
|
||||
- XMLRPC:
|
||||
. Fixed bug #71501 (xmlrpc_encode_request ignores encoding option). (Hieu Le)
|
||||
|
||||
- Zip:
|
||||
. Fixed bug #71561 (NULL pointer dereference in Zip::ExtractTo). (Laruence)
|
||||
|
||||
04 Feb 2016 PHP 7.0.3
|
||||
|
||||
- Core:
|
||||
. Fixed bug #71336 (Wrong is_ref on properties as exposed via
|
||||
get_object_vars()). (Laruence)
|
||||
. Fixed bug #71248 (Wrong interface is enforced). (Dmitry)
|
||||
. Fixed bug #71300 (Segfault in zend_fetch_string_offset). (Laruence)
|
||||
. Added support for new HTTP 451 code. (Julien)
|
||||
. Fixed bug #71039 (exec functions ignore length but look for NULL
|
||||
termination). (Anatol)
|
||||
. Fixed bug #71089 (No check to duplicate zend_extension). (Remi)
|
||||
. Fixed bug #71201 (round() segfault on 64-bit builds). (Anatol)
|
||||
. Fixed bug #71221 (Null pointer deref (segfault) in get_defined_vars via
|
||||
ob_start). (hugh at allthethings dot co dot nz)
|
||||
. Fixed bug #71201 (round() segfault on 64-bit builds). (Anatol)
|
||||
. Added support for new HTTP 451 code. (Julien)
|
||||
. Fixed Bug #71275 (Bad method called on cloning an object having a trait).
|
||||
(Bob)
|
||||
. Fixed bug #71248 (Wrong interface is enforced). (Dmitry)
|
||||
. Fixed bug #71273 (A wrong ext directory setup in php.ini leads to crash).
|
||||
(Anatol)
|
||||
. Fixed Bug #71275 (Bad method called on cloning an object having a trait).
|
||||
(Bob)
|
||||
. Fixed bug #71297 (Memory leak with consecutive yield from). (Bob)
|
||||
. Fixed bug #71300 (Segfault in zend_fetch_string_offset). (Laruence)
|
||||
. Fixed bug #71314 (var_export(INF) prints INF.0). (Andrea)
|
||||
. Fixed bug #71323 (Output of stream_get_meta_data can be falsified by its
|
||||
input). (Leo Gaspard)
|
||||
. Fixed bug #71336 (Wrong is_ref on properties as exposed via
|
||||
get_object_vars()). (Laruence)
|
||||
. Fixed bug #71459 (Integer overflow in iptcembed()). (Stas)
|
||||
|
||||
- Apache2handler:
|
||||
. Fix >2G Content-Length headers in apache2handler. (Adam Harvey)
|
||||
@ -30,6 +74,9 @@ PHP NEWS
|
||||
. Fixed bug #71225 (curl_setopt() fails to set CURLOPT_POSTFIELDS with
|
||||
reference to CURLFile). (Laruence)
|
||||
|
||||
- GD:
|
||||
. Improved fix for bug #70976. (Remi)
|
||||
|
||||
- Interbase:
|
||||
. Fixed Bug #71305 (Crash when optional resource is omitted).
|
||||
(Laruence, Anatol)
|
||||
@ -38,9 +85,21 @@ PHP NEWS
|
||||
. Fixed bug #71249 (ldap_mod_replace/ldap_mod_add store value as string
|
||||
"Array"). (Laruence)
|
||||
|
||||
- mbsgring:
|
||||
- mbstring:
|
||||
. Fixed bug #71397 (mb_send_mail segmentation fault). (Andrea, Yasuo)
|
||||
|
||||
- OpenSSL:
|
||||
. Fixed bug #71475 (openssl_seal() uninitialized memory usage). (Stas)
|
||||
|
||||
- PCRE:
|
||||
. Upgraded pcrelib to 8.38.
|
||||
|
||||
- Phar:
|
||||
. Fixed bug #71354 (Heap corruption in tar/zip/phar parser). (Stas)
|
||||
. Fixed bug #71391 (NULL Pointer Dereference in phar_tar_setupmetadata()).
|
||||
(Stas)
|
||||
. Fixed bug #71488 (Stack overflow when decompressing tar archives). (Stas)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug #70979 (crash with bad soap request). (Anatol)
|
||||
|
||||
@ -49,16 +108,10 @@ PHP NEWS
|
||||
(Laruence)
|
||||
. Fixed bug #71202 (Autoload function registered by another not activated
|
||||
immediately). (Laruence)
|
||||
|
||||
- Session:
|
||||
. Improved fix for bug #68063 (Empty session IDs do still start sessions). (Yasuo)
|
||||
. Fixed bug #69111 (Crash in SessionHandler::read()) (Yasuo)
|
||||
. Fixed bug #71038 (session_start() returns TRUE on failure).
|
||||
Session save handlers must return 'string' always for successful read.
|
||||
i.e. Non-existing session read must return empty string. PHP 7.0 is made
|
||||
not to tolerate buggy return value. (Yasuo)
|
||||
. Fixed bug #71394 (session_regenerate_id() must close opened session on errors).
|
||||
(Yasuo)
|
||||
. Fixed bug #71311 (Use-after-free vulnerability in SPL(ArrayObject,
|
||||
unserialize)). (Sean Heelan)
|
||||
. Fixed bug #71313 (Use-after-free vulnerability in SPL(SplObjectStorage,
|
||||
unserialize)). (Sean Heelan)
|
||||
|
||||
- Standard:
|
||||
. Fixed bug #71287 (Error message contains hexadecimal instead of decimal
|
||||
@ -73,9 +126,11 @@ PHP NEWS
|
||||
array to strings). (Laruence)
|
||||
. Fixed bug #71188 (str_replace converts integers in original $search array
|
||||
to strings). (Laruence)
|
||||
. Fixed bug #70720 (strip_tags improper php code parsing). (Julien)
|
||||
. Fixed bug #71132, #71197 (range() segfaults). (Thomas Punt)
|
||||
|
||||
- WDDX:
|
||||
. Fixed bug #71335 (Type Confusion in WDDX Packet Deserialization). (Stas)
|
||||
|
||||
07 Jan 2016 PHP 7.0.2
|
||||
|
||||
- Core:
|
||||
@ -110,10 +165,6 @@ PHP NEWS
|
||||
- Filter:
|
||||
. Fixed bug #71063 (filter_input(INPUT_ENV, ..) does not work). (Reeze Xia)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #70976 (Memory Read via gdImageRotateInterpolated Array Index
|
||||
Out of Bounds). (emmanuel dot law at gmail dot com).
|
||||
|
||||
- FPM:
|
||||
. Fixed bug #70755 (fpm_log.c memory leak and buffer overflow). (Stas)
|
||||
|
||||
@ -121,6 +172,10 @@ PHP NEWS
|
||||
. Implemented FR #55651 (Option to ignore the returned FTP PASV address).
|
||||
(abrender at elitehosts dot com)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #70976 (Memory Read via gdImageRotateInterpolated Array Index
|
||||
Out of Bounds). (emmanuel dot law at gmail dot com)
|
||||
|
||||
- Mbstring:
|
||||
. Fixed bug #71066 (mb_send_mail: Program terminated with signal SIGSEGV,
|
||||
Segmentation fault). (Laruence)
|
||||
@ -150,12 +205,12 @@ PHP NEWS
|
||||
(emmanuel dot law at gmail dot com)
|
||||
|
||||
- WDDX:
|
||||
. Fixed bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization).
|
||||
(taoguangchen at icloud dot com)
|
||||
. Fixed bug #70661 (Use After Free Vulnerability in WDDX Packet
|
||||
Deserialization). (taoguangchen at icloud dot com)
|
||||
. Fixed bug #70741 (Session WDDX Packet Deserialization Type Confusion
|
||||
Vulnerability). (taoguangchen at icloud dot com)
|
||||
|
||||
- XMLRPC
|
||||
- XMLRPC:
|
||||
. Fixed bug #70728 (Type Confusion Vulnerability in PHP_to_XMLRPC_worker).
|
||||
(Julien)
|
||||
|
||||
|
23
Zend/tests/bug71474.phpt
Normal file
23
Zend/tests/bug71474.phpt
Normal file
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #71474: Crash because of VM stack corruption on Magento2
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
function __call($name, $args) {
|
||||
$a = $b = $c = $d = $e = $f = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function test($n, $x) {
|
||||
// var_dump($n);
|
||||
if ($n > 0) {
|
||||
$x->bug();
|
||||
test($n - 1, $x);
|
||||
}
|
||||
}
|
||||
|
||||
test(3000, new foo());
|
||||
echo "OK\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
OK
|
23
Zend/tests/bug71529.phpt
Normal file
23
Zend/tests/bug71529.phpt
Normal file
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Bug #71529: Variable references on array elements don't work when using count
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = [1];
|
||||
$a[] = &$a[out(count($a) - 1)];
|
||||
var_dump($a);
|
||||
|
||||
function out($what) {
|
||||
var_dump($what);
|
||||
return $what;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(0)
|
||||
array(2) {
|
||||
[0]=>
|
||||
&int(1)
|
||||
[1]=>
|
||||
&int(1)
|
||||
}
|
29
Zend/tests/generators/bug71441.phpt
Normal file
29
Zend/tests/generators/bug71441.phpt
Normal file
@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Bug #71441 (Typehinted Generator with return in try/finally crashes)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$num = 2000; /* to be sure to be in wild memory */
|
||||
$add = str_repeat("1 +", $num);
|
||||
$gen = (eval(<<<PHP
|
||||
return function (): \Generator {
|
||||
try {
|
||||
\$a = 1;
|
||||
\$foo = \$a + $add \$a;
|
||||
return yield \$foo;
|
||||
} finally {
|
||||
print "Ok\n";
|
||||
}
|
||||
};
|
||||
PHP
|
||||
))();
|
||||
var_dump($gen->current());
|
||||
$gen->send("Success");
|
||||
var_dump($gen->getReturn());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(2002)
|
||||
Ok
|
||||
string(7) "Success"
|
||||
|
@ -966,6 +966,10 @@ ZEND_API void zend_deactivate(void) /* {{{ */
|
||||
/* shutdown_executor() takes care of its own bailout handling */
|
||||
shutdown_executor();
|
||||
|
||||
zend_try {
|
||||
zend_ini_deactivate();
|
||||
} zend_end_try();
|
||||
|
||||
zend_try {
|
||||
shutdown_compiler();
|
||||
} zend_end_try();
|
||||
@ -984,10 +988,6 @@ ZEND_API void zend_deactivate(void) /* {{{ */
|
||||
fprintf(stderr, " -------- -------- ----------- ------\n");
|
||||
fprintf(stderr, "ZVAL %8d %8d %9d %8d\n", GC_G(zval_possible_root), GC_G(zval_buffered), GC_G(zval_remove_from_buffer), GC_G(zval_marked_grey));
|
||||
#endif
|
||||
|
||||
zend_try {
|
||||
zend_ini_deactivate();
|
||||
} zend_end_try();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -103,11 +103,12 @@ static zend_always_inline void zend_arena_release(zend_arena **arena_ptr, void *
|
||||
zend_arena *arena = *arena_ptr;
|
||||
|
||||
while (UNEXPECTED((char*)checkpoint > arena->end) ||
|
||||
UNEXPECTED((char*)checkpoint < (char*)arena)) {
|
||||
UNEXPECTED((char*)checkpoint <= (char*)arena)) {
|
||||
zend_arena *prev = arena->prev;
|
||||
efree(arena);
|
||||
*arena_ptr = arena = prev;
|
||||
}
|
||||
ZEND_ASSERT((char*)checkpoint > (char*)arena && (char*)checkpoint <= arena->end);
|
||||
arena->ptr = (char*)checkpoint;
|
||||
}
|
||||
|
||||
|
@ -2589,14 +2589,17 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
|
||||
|
||||
znode target_node, source_node;
|
||||
zend_op *opline;
|
||||
uint32_t offset;
|
||||
|
||||
if (is_this_fetch(target_ast)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
|
||||
}
|
||||
zend_ensure_writable_variable(target_ast);
|
||||
|
||||
zend_compile_var(&target_node, target_ast, BP_VAR_W);
|
||||
zend_compile_var(&source_node, source_ast, BP_VAR_REF);
|
||||
offset = zend_delayed_compile_begin();
|
||||
zend_delayed_compile_var(&target_node, target_ast, BP_VAR_W);
|
||||
zend_delayed_compile_var(&source_node, source_ast, BP_VAR_REF);
|
||||
zend_delayed_compile_end(offset);
|
||||
|
||||
if (source_node.op_type != IS_VAR && zend_is_call(source_ast)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use result of built-in function in write context");
|
||||
|
@ -2118,33 +2118,35 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
|
||||
first_extra_arg = op_array->num_args;
|
||||
num_args = EX_NUM_ARGS();
|
||||
if (UNEXPECTED(num_args > first_extra_arg)) {
|
||||
zval *end, *src, *dst;
|
||||
uint32_t type_flags = 0;
|
||||
if (EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) {
|
||||
zval *end, *src, *dst;
|
||||
uint32_t type_flags = 0;
|
||||
|
||||
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
|
||||
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
|
||||
EX(opline) += first_extra_arg;
|
||||
}
|
||||
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
|
||||
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
|
||||
EX(opline) += first_extra_arg;
|
||||
}
|
||||
|
||||
/* move extra args into separate array after all CV and TMP vars */
|
||||
end = EX_VAR_NUM(first_extra_arg - 1);
|
||||
src = end + (num_args - first_extra_arg);
|
||||
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
|
||||
if (EXPECTED(src != dst)) {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
ZVAL_COPY_VALUE(dst, src);
|
||||
ZVAL_UNDEF(src);
|
||||
src--;
|
||||
dst--;
|
||||
} while (src != end);
|
||||
} else {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
src--;
|
||||
} while (src != end);
|
||||
/* move extra args into separate array after all CV and TMP vars */
|
||||
end = EX_VAR_NUM(first_extra_arg - 1);
|
||||
src = end + (num_args - first_extra_arg);
|
||||
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
|
||||
if (EXPECTED(src != dst)) {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
ZVAL_COPY_VALUE(dst, src);
|
||||
ZVAL_UNDEF(src);
|
||||
src--;
|
||||
dst--;
|
||||
} while (src != end);
|
||||
} else {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
src--;
|
||||
} while (src != end);
|
||||
}
|
||||
ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
|
||||
}
|
||||
ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
|
||||
} else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
|
||||
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
|
||||
EX(opline) += num_args;
|
||||
@ -2231,33 +2233,35 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
|
||||
first_extra_arg = op_array->num_args;
|
||||
num_args = EX_NUM_ARGS();
|
||||
if (UNEXPECTED(num_args > first_extra_arg)) {
|
||||
zval *end, *src, *dst;
|
||||
uint32_t type_flags = 0;
|
||||
if (EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) {
|
||||
zval *end, *src, *dst;
|
||||
uint32_t type_flags = 0;
|
||||
|
||||
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
|
||||
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
|
||||
EX(opline) += first_extra_arg;
|
||||
}
|
||||
if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
|
||||
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
|
||||
EX(opline) += first_extra_arg;
|
||||
}
|
||||
|
||||
/* move extra args into separate array after all CV and TMP vars */
|
||||
end = EX_VAR_NUM(first_extra_arg - 1);
|
||||
src = end + (num_args - first_extra_arg);
|
||||
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
|
||||
if (EXPECTED(src != dst)) {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
ZVAL_COPY_VALUE(dst, src);
|
||||
ZVAL_UNDEF(src);
|
||||
src--;
|
||||
dst--;
|
||||
} while (src != end);
|
||||
} else {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
src--;
|
||||
} while (src != end);
|
||||
/* move extra args into separate array after all CV and TMP vars */
|
||||
end = EX_VAR_NUM(first_extra_arg - 1);
|
||||
src = end + (num_args - first_extra_arg);
|
||||
dst = src + (op_array->last_var + op_array->T - first_extra_arg);
|
||||
if (EXPECTED(src != dst)) {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
ZVAL_COPY_VALUE(dst, src);
|
||||
ZVAL_UNDEF(src);
|
||||
src--;
|
||||
dst--;
|
||||
} while (src != end);
|
||||
} else {
|
||||
do {
|
||||
type_flags |= Z_TYPE_INFO_P(src);
|
||||
src--;
|
||||
} while (src != end);
|
||||
}
|
||||
ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
|
||||
}
|
||||
ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
|
||||
} else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
|
||||
/* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
|
||||
EX(opline) += num_args;
|
||||
|
@ -1054,6 +1054,8 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend
|
||||
|
||||
func->prototype = fbc;
|
||||
func->scope = fbc->common.scope;
|
||||
/* reserve space for arguments, local and temorary variables */
|
||||
func->T = (fbc->type == ZEND_USER_FUNCTION)? MAX(fbc->op_array.last_var + fbc->op_array.T, 2) : 2;
|
||||
func->filename = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.filename : ZSTR_EMPTY_ALLOC();
|
||||
func->line_start = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_start : 0;
|
||||
func->line_end = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_end : 0;
|
||||
|
@ -668,9 +668,13 @@ ZEND_API int pass_two(zend_op_array *op_array)
|
||||
case ZEND_VERIFY_RETURN_TYPE:
|
||||
if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
if (opline->op1_type != IS_UNUSED) {
|
||||
(opline + 1)->op1 = opline->op1;
|
||||
(opline + 1)->op1_type = opline->op1_type;
|
||||
zend_op *ret = opline;
|
||||
do ret++; while (ret->opcode != ZEND_RETURN);
|
||||
|
||||
ret->op1 = opline->op1;
|
||||
ret->op1_type = opline->op1_type;
|
||||
}
|
||||
|
||||
MAKE_NOP(opline);
|
||||
}
|
||||
break;
|
||||
|
@ -3527,7 +3527,7 @@ ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY)
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -3655,7 +3655,7 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -3786,7 +3786,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -7833,10 +7833,8 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
|
||||
{
|
||||
zend_array *args;
|
||||
zend_function *fbc = EX(func);
|
||||
zend_object *object = Z_OBJ(EX(This));
|
||||
zval *ret = EX(return_value);
|
||||
uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS);
|
||||
zend_class_entry *scope = EX(called_scope);
|
||||
uint32_t num_args = EX_NUM_ARGS();
|
||||
zend_execute_data *call;
|
||||
USE_OPLINE
|
||||
@ -7859,9 +7857,11 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
|
||||
SAVE_OPLINE();
|
||||
call = execute_data;
|
||||
execute_data = EG(current_execute_data) = EX(prev_execute_data);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
call = zend_vm_stack_push_call_frame(call_info, fbc->common.prototype, 2, scope, object);
|
||||
call->prev_execute_data = execute_data;
|
||||
|
||||
ZEND_ASSERT(zend_vm_calc_used_stack(2, fbc->common.prototype) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
|
||||
|
||||
call->func = fbc->common.prototype;
|
||||
ZEND_CALL_NUM_ARGS(call) = 2;
|
||||
|
||||
ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);
|
||||
ZVAL_ARR(ZEND_CALL_ARG(call, 2), args);
|
||||
@ -7925,7 +7925,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -7949,7 +7949,7 @@ ZEND_VM_C_LABEL(call_trampoline_end):
|
||||
opline = EX(opline);
|
||||
|
||||
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
|
||||
object = Z_OBJ(call->This);
|
||||
zend_object *object = Z_OBJ(call->This);
|
||||
OBJ_RELEASE(object);
|
||||
}
|
||||
EG(scope) = EX(func)->op_array.scope;
|
||||
|
@ -587,7 +587,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_HANDLER(ZEND_OPC
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -715,7 +715,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -846,7 +846,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPC
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -1721,10 +1721,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
||||
{
|
||||
zend_array *args;
|
||||
zend_function *fbc = EX(func);
|
||||
zend_object *object = Z_OBJ(EX(This));
|
||||
zval *ret = EX(return_value);
|
||||
uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS);
|
||||
zend_class_entry *scope = EX(called_scope);
|
||||
uint32_t num_args = EX_NUM_ARGS();
|
||||
zend_execute_data *call;
|
||||
USE_OPLINE
|
||||
@ -1747,9 +1745,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
||||
SAVE_OPLINE();
|
||||
call = execute_data;
|
||||
execute_data = EG(current_execute_data) = EX(prev_execute_data);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
call = zend_vm_stack_push_call_frame(call_info, fbc->common.prototype, 2, scope, object);
|
||||
call->prev_execute_data = execute_data;
|
||||
|
||||
ZEND_ASSERT(zend_vm_calc_used_stack(2, fbc->common.prototype) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call));
|
||||
|
||||
call->func = fbc->common.prototype;
|
||||
ZEND_CALL_NUM_ARGS(call) = 2;
|
||||
|
||||
ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name);
|
||||
ZVAL_ARR(ZEND_CALL_ARG(call, 2), args);
|
||||
@ -1813,7 +1813,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
||||
|
||||
#if ZEND_DEBUG
|
||||
ZEND_ASSERT(
|
||||
!call->func ||
|
||||
EG(exception) || !call->func ||
|
||||
!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) ||
|
||||
zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var)));
|
||||
#endif
|
||||
@ -1837,7 +1837,7 @@ call_trampoline_end:
|
||||
opline = EX(opline);
|
||||
|
||||
if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) {
|
||||
object = Z_OBJ(call->This);
|
||||
zend_object *object = Z_OBJ(call->This);
|
||||
OBJ_RELEASE(object);
|
||||
}
|
||||
EG(scope) = EX(func)->op_array.scope;
|
||||
|
@ -157,7 +157,8 @@ static void _php_curl_close(zend_resource *rsrc);
|
||||
#define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s) - 1, (zend_long) v);
|
||||
#define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s) - 1, (double) v);
|
||||
#define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s) - 1, (char *) (v ? v : ""));
|
||||
#define CAASTR(s, v) add_assoc_str_ex(return_value, s, sizeof(s) - 1, v ? v : ZSTR_EMPTY_ALLOC());
|
||||
#define CAASTR(s, v) add_assoc_str_ex(return_value, s, sizeof(s) - 1, \
|
||||
v ? zend_string_copy(v) : ZSTR_EMPTY_ALLOC());
|
||||
#define CAAZ(s, v) add_assoc_zval_ex(return_value, s, sizeof(s) -1 , (zval *) v);
|
||||
|
||||
#if defined(PHP_WIN32) || defined(__GNUC__)
|
||||
@ -1751,7 +1752,7 @@ static php_curl *alloc_curl_handle()
|
||||
memset(&ch->err, 0, sizeof(struct _php_curl_error));
|
||||
|
||||
zend_llist_init(&ch->to_free->str, sizeof(char *), (llist_dtor_func_t)curl_free_string, 0);
|
||||
zend_llist_init(&ch->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t)curl_free_post, 0);
|
||||
zend_llist_init(&ch->to_free->post, sizeof(struct HttpPost *), (llist_dtor_func_t)curl_free_post, 0);
|
||||
|
||||
ch->to_free->slist = emalloc(sizeof(HashTable));
|
||||
zend_hash_init(ch->to_free->slist, 4, NULL, curl_free_slist, 0);
|
||||
@ -2475,7 +2476,11 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
zend_hash_index_update_ptr(ch->to_free->slist, option, slist);
|
||||
if ((*ch->clone) == 1) {
|
||||
zend_hash_index_update_ptr(ch->to_free->slist, option, slist);
|
||||
} else {
|
||||
zend_hash_next_index_insert_ptr(ch->to_free->slist, slist);
|
||||
}
|
||||
|
||||
error = curl_easy_setopt(ch->cp, option, slist);
|
||||
|
||||
@ -3032,7 +3037,7 @@ PHP_FUNCTION(curl_getinfo)
|
||||
}
|
||||
#endif
|
||||
if (ch->header.str) {
|
||||
CAASTR("request_header", zend_string_copy(ch->header.str));
|
||||
CAASTR("request_header", ch->header.str);
|
||||
}
|
||||
} else {
|
||||
switch (option) {
|
||||
|
31
ext/curl/tests/bug71523.phpt
Normal file
31
ext/curl/tests/bug71523.phpt
Normal file
@ -0,0 +1,31 @@
|
||||
--TEST--
|
||||
Bug #71523 (Copied handle with new option CURLOPT_HTTPHEADER crashes while curl_multi_exec)
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("curl")) {
|
||||
exit("skip curl extension not loaded");
|
||||
}
|
||||
if (getenv("SKIP_ONLINE_TESTS")) {
|
||||
die("skip online test");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$base = curl_init('http://www.google.com/');
|
||||
curl_setopt($base, CURLOPT_RETURNTRANSFER, true);
|
||||
$mh = curl_multi_init();
|
||||
|
||||
for ($i = 0; $i < 2; ++$i) {
|
||||
$ch = curl_copy_handle($base);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Foo: Bar']);
|
||||
curl_multi_add_handle($mh, $ch);
|
||||
}
|
||||
|
||||
do {
|
||||
curl_multi_exec($mh, $active);
|
||||
} while ($active);
|
||||
?>
|
||||
okey
|
||||
--EXPECTF--
|
||||
okey
|
@ -70,7 +70,7 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
|
||||
rt->i += dst_m_corr;
|
||||
}
|
||||
|
||||
rt->days = abs(floor((one->sse - two->sse - (dst_h_corr * 3600) - (dst_m_corr * 60)) / 86400));
|
||||
rt->days = fabs(floor((one->sse - two->sse - (dst_h_corr * 3600) - (dst_m_corr * 60)) / 86400));
|
||||
|
||||
timelib_do_rel_normalize(rt->invert ? one : two, rt);
|
||||
|
||||
|
@ -1812,6 +1812,11 @@ timelib_time* timelib_strtotime(char *s, size_t len, struct timelib_error_contai
|
||||
{ \
|
||||
add_pbf_error(s, "Unexpected data found.", string, begin); \
|
||||
}
|
||||
#define TIMELIB_CHECK_SIGNED_NUMBER \
|
||||
if (strchr("-0123456789", *ptr) == NULL) \
|
||||
{ \
|
||||
add_pbf_error(s, "Unexpected data found.", string, begin); \
|
||||
}
|
||||
|
||||
static void timelib_time_reset_fields(timelib_time *time)
|
||||
{
|
||||
@ -2016,7 +2021,7 @@ timelib_time *timelib_parse_from_format(char *format, char *string, size_t len,
|
||||
timelib_eat_spaces((char **) &ptr);
|
||||
break;
|
||||
case 'U': /* epoch seconds */
|
||||
TIMELIB_CHECK_NUMBER;
|
||||
TIMELIB_CHECK_SIGNED_NUMBER;
|
||||
TIMELIB_HAVE_RELATIVE();
|
||||
tmp = timelib_get_unsigned_nr((char **) &ptr, 24);
|
||||
s->time->y = 1970;
|
||||
|
@ -65,6 +65,23 @@ timelib_time* timelib_time_clone(timelib_time *orig)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int timelib_time_compare(timelib_time *t1, timelib_time *t2)
|
||||
{
|
||||
if (t1->sse == t2->sse) {
|
||||
if (t1->f == t2->f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (t1->sse < 0) {
|
||||
return (t1->f < t2->f) ? 1 : -1;
|
||||
} else {
|
||||
return (t1->f < t2->f) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (t1->sse < t2->sse) ? -1 : 1;
|
||||
}
|
||||
|
||||
timelib_rel_time* timelib_rel_time_clone(timelib_rel_time *rel)
|
||||
{
|
||||
timelib_rel_time *tmp = timelib_rel_time_ctor();
|
||||
|
@ -138,6 +138,7 @@ timelib_time* timelib_time_ctor(void);
|
||||
void timelib_time_set_option(timelib_time* tm, int option, void* option_value);
|
||||
void timelib_time_dtor(timelib_time* t);
|
||||
timelib_time* timelib_time_clone(timelib_time* orig);
|
||||
int timelib_time_compare(timelib_time *t1, timelib_time *t2);
|
||||
|
||||
timelib_time_offset* timelib_time_offset_ctor(void);
|
||||
void timelib_time_offset_dtor(timelib_time_offset* t);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2142,7 +2142,7 @@ static int date_object_compare_date(zval *d1, zval *d2) /* {{{ */
|
||||
timelib_update_ts(o2->time, o2->time->tz_info);
|
||||
}
|
||||
|
||||
return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1);
|
||||
return timelib_time_compare(o1->time, o2->time);
|
||||
} /* }}} */
|
||||
|
||||
static HashTable *date_object_get_gc(zval *object, zval **table, int *n) /* {{{ */
|
||||
|
19
ext/date/tests/bug68078.phpt
Normal file
19
ext/date/tests/bug68078.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Comparing datetime objects should account for microseconds
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
$date1 = DateTime::createFromFormat('U.u', '1448889063.3531');
|
||||
$date2 = DateTime::createFromFormat('U.u', '1448889063.5216');
|
||||
$date3 = DateTime::createFromFormat('U.u', '1448889063.5216');
|
||||
|
||||
var_dump($date1 == $date2);
|
||||
var_dump($date1 < $date2);
|
||||
var_dump($date2 > $date1);
|
||||
var_dump($date2 == $date3);
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
19
ext/date/tests/bug68078_negative.phpt
Normal file
19
ext/date/tests/bug68078_negative.phpt
Normal file
@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Comparing datetime objects with negative timestamps should account for microseconds
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
$earlyDate1 = DateTime::createFromFormat('U.u', '1.8642')->modify('-5 seconds');
|
||||
$earlyDate2 = DateTime::createFromFormat('U.u', '1.2768')->modify('-5 seconds');
|
||||
$earlyDate3 = DateTime::createFromFormat('U.u', '1.2768')->modify('-5 seconds');
|
||||
|
||||
var_dump($earlyDate1 == $earlyDate2);
|
||||
var_dump($earlyDate1 < $earlyDate2);
|
||||
var_dump($earlyDate2 > $earlyDate1);
|
||||
var_dump($earlyDate2 == $earlyDate3);
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
@ -1,6 +1,6 @@
|
||||
diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
--- libmagic.orig/apprentice.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/apprentice.c Sun Mar 29 16:51:28 2015
|
||||
--- libmagic.orig/apprentice.c 2016-01-25 11:31:21.473017702 +0800
|
||||
+++ libmagic/apprentice.c 2016-01-25 11:41:58.210723599 +0800
|
||||
@@ -29,6 +29,8 @@
|
||||
* apprentice - make one pass through /etc/magic, learning its secrets.
|
||||
*/
|
||||
@ -815,7 +815,15 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
VERSIONNO, dbname, version);
|
||||
return -1;
|
||||
}
|
||||
@@ -2992,14 +3014,18 @@
|
||||
@@ -2983,7 +3005,6 @@
|
||||
{
|
||||
static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
|
||||
static const size_t m = sizeof(**map->magic);
|
||||
- int fd = -1;
|
||||
size_t len;
|
||||
char *dbname;
|
||||
int rv = -1;
|
||||
@@ -2992,14 +3013,18 @@
|
||||
struct magic m;
|
||||
uint32_t h[2 + MAGIC_SETS];
|
||||
} hdr;
|
||||
@ -838,7 +846,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
file_error(ms, errno, "cannot open `%s'", dbname);
|
||||
goto out;
|
||||
}
|
||||
@@ -3008,24 +3034,25 @@
|
||||
@@ -3008,24 +3033,25 @@
|
||||
hdr.h[1] = VERSIONNO;
|
||||
memcpy(hdr.h + 2, map->nmagic, nm);
|
||||
|
||||
@ -869,7 +877,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -3059,16 +3086,18 @@
|
||||
@@ -3059,16 +3085,18 @@
|
||||
q++;
|
||||
/* Compatibility with old code that looked in .mime */
|
||||
if (ms->flags & MAGIC_MIME) {
|
||||
@ -894,7 +902,7 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
|
||||
/* Compatibility with old code that looked in .mime */
|
||||
if (strstr(p, ".mime") != NULL)
|
||||
@@ -3158,7 +3187,7 @@
|
||||
@@ -3158,7 +3186,7 @@
|
||||
m->offset = swap4((uint32_t)m->offset);
|
||||
m->in_offset = swap4((uint32_t)m->in_offset);
|
||||
m->lineno = swap4((uint32_t)m->lineno);
|
||||
@ -904,8 +912,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c
|
||||
m->str_flags = swap4(m->str_flags);
|
||||
}
|
||||
diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
|
||||
--- libmagic.orig/ascmagic.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/ascmagic.c Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/ascmagic.c 2016-01-25 11:31:21.495017704 +0800
|
||||
+++ libmagic/ascmagic.c 2016-01-25 11:31:32.676017695 +0800
|
||||
@@ -139,7 +139,7 @@
|
||||
/* malloc size is a conservative overestimate; could be
|
||||
improved, or at least realloced after conversion. */
|
||||
@ -926,8 +934,8 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c
|
||||
return rv;
|
||||
}
|
||||
diff -u libmagic.orig/cdf.c libmagic/cdf.c
|
||||
--- libmagic.orig/cdf.c Thu Mar 5 15:25:12 2015
|
||||
+++ libmagic/cdf.c Sun Mar 29 16:51:28 2015
|
||||
--- libmagic.orig/cdf.c 2016-01-25 11:31:21.472017703 +0800
|
||||
+++ libmagic/cdf.c 2016-01-25 11:31:32.676017695 +0800
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "file.h"
|
||||
|
||||
@ -1093,8 +1101,8 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c
|
||||
#ifdef CDF_DEBUG
|
||||
else
|
||||
diff -u libmagic.orig/cdf.h libmagic/cdf.h
|
||||
--- libmagic.orig/cdf.h Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/cdf.h Sun Mar 29 18:04:24 2015
|
||||
--- libmagic.orig/cdf.h 2016-01-25 11:31:21.493017704 +0800
|
||||
+++ libmagic/cdf.h 2016-01-25 11:31:32.676017695 +0800
|
||||
@@ -35,10 +35,12 @@
|
||||
#ifndef _H_CDF_
|
||||
#define _H_CDF_
|
||||
@ -1123,8 +1131,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h
|
||||
void cdf_swap_header(cdf_header_t *);
|
||||
void cdf_unpack_header(cdf_header_t *, char *);
|
||||
diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
|
||||
--- libmagic.orig/cdf_time.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/cdf_time.c Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/cdf_time.c 2016-01-25 11:31:21.494017704 +0800
|
||||
+++ libmagic/cdf_time.c 2016-01-25 11:31:32.676017695 +0800
|
||||
@@ -96,7 +96,7 @@
|
||||
}
|
||||
|
||||
@ -1174,8 +1182,8 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c
|
||||
static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL;
|
||||
static const char *ref = "Sat Apr 23 01:30:00 1977";
|
||||
diff -u libmagic.orig/compress.c libmagic/compress.c
|
||||
--- libmagic.orig/compress.c Sun Mar 29 13:11:40 2015
|
||||
+++ libmagic/compress.c Sun Mar 29 18:14:23 2015
|
||||
--- libmagic.orig/compress.c 2016-01-25 11:31:21.483017704 +0800
|
||||
+++ libmagic/compress.c 2016-01-25 11:31:32.676017695 +0800
|
||||
@@ -32,10 +32,11 @@
|
||||
* uncompress(method, old, n, newch) - uncompress old into new,
|
||||
* using method, return sizeof new
|
||||
@ -1374,8 +1382,8 @@ diff -u libmagic.orig/compress.c libmagic/compress.c
|
||||
-#endif
|
||||
+#endif /* if PHP_FILEINFO_UNCOMPRESS */
|
||||
diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
|
||||
--- libmagic.orig/elfclass.h Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/elfclass.h Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/elfclass.h 2016-01-25 11:31:21.471017705 +0800
|
||||
+++ libmagic/elfclass.h 2016-01-25 11:31:32.677017695 +0800
|
||||
@@ -41,7 +41,7 @@
|
||||
return toomany(ms, "program headers", phnum);
|
||||
flags |= FLAGS_IS_CORE;
|
||||
@ -1404,8 +1412,8 @@ diff -u libmagic.orig/elfclass.h libmagic/elfclass.h
|
||||
fsize, elf_getu16(swap, elfhdr.e_machine),
|
||||
(int)elf_getu16(swap, elfhdr.e_shstrndx),
|
||||
diff -u libmagic.orig/file.h libmagic/file.h
|
||||
--- libmagic.orig/file.h Sat Feb 21 15:02:19 2015
|
||||
+++ libmagic/file.h Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/file.h 2016-01-25 11:31:21.472017703 +0800
|
||||
+++ libmagic/file.h 2016-01-25 11:31:32.677017695 +0800
|
||||
@@ -33,11 +33,9 @@
|
||||
#ifndef __file_h__
|
||||
#define __file_h__
|
||||
@ -1609,11 +1617,10 @@ diff -u libmagic.orig/file.h libmagic/file.h
|
||||
|
||||
#if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK)
|
||||
#define QUICK
|
||||
@@ -595,6 +540,14 @@
|
||||
#endif
|
||||
@@ -596,6 +541,14 @@
|
||||
#else
|
||||
#define FILE_RCSID(id)
|
||||
+#endif
|
||||
#endif
|
||||
+
|
||||
+#ifdef PHP_WIN32
|
||||
+#define FINFO_LSEEK_FUNC _lseek
|
||||
@ -1621,12 +1628,13 @@ diff -u libmagic.orig/file.h libmagic/file.h
|
||||
+#else
|
||||
+#define FINFO_LSEEK_FUNC lseek
|
||||
+#define FINFO_READ_FUNC read
|
||||
#endif
|
||||
+#endif
|
||||
#ifndef __RCSID
|
||||
#define __RCSID(a)
|
||||
#endif
|
||||
diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
|
||||
--- libmagic.orig/fsmagic.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/fsmagic.c Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/fsmagic.c 2016-01-25 11:31:21.471017705 +0800
|
||||
+++ libmagic/fsmagic.c 2016-01-25 11:31:32.677017695 +0800
|
||||
@@ -63,27 +63,21 @@
|
||||
# define minor(dev) ((dev) & 0xff)
|
||||
#endif
|
||||
@ -1977,8 +1985,8 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c
|
||||
return ret;
|
||||
}
|
||||
diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
--- libmagic.orig/funcs.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/funcs.c Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/funcs.c 2016-01-25 11:31:21.483017704 +0800
|
||||
+++ libmagic/funcs.c 2016-01-25 11:41:34.164723619 +0800
|
||||
@@ -31,7 +31,6 @@
|
||||
#endif /* lint */
|
||||
|
||||
@ -1987,7 +1995,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -42,76 +41,80 @@
|
||||
@@ -42,76 +41,79 @@
|
||||
#if defined(HAVE_WCTYPE_H)
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
@ -2040,7 +2048,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
protected int
|
||||
file_printf(struct magic_set *ms, const char *fmt, ...)
|
||||
{
|
||||
int rv;
|
||||
- int rv;
|
||||
va_list ap;
|
||||
+ int len;
|
||||
+ char *buf = NULL, *newstr;
|
||||
@ -2104,7 +2112,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
ms->event_flags |= EVENT_HAD_ERR;
|
||||
ms->error = error;
|
||||
}
|
||||
@@ -158,11 +161,9 @@
|
||||
@@ -158,11 +160,9 @@
|
||||
file_error(ms, errno, "error reading");
|
||||
}
|
||||
|
||||
@ -2118,7 +2126,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
{
|
||||
int m = 0, rv = 0, looks_text = 0;
|
||||
int mime = ms->flags & MAGIC_MIME;
|
||||
@@ -201,10 +202,10 @@
|
||||
@@ -201,10 +201,10 @@
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -2132,7 +2140,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
if ((ms->flags & MAGIC_DEBUG) != 0)
|
||||
(void)fprintf(stderr, "zmagic %d\n", m);
|
||||
goto done_encoding;
|
||||
@@ -219,12 +220,16 @@
|
||||
@@ -219,12 +219,16 @@
|
||||
}
|
||||
|
||||
/* Check if we have a CDF file */
|
||||
@ -2154,16 +2162,16 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
|
||||
/* try soft magic tests */
|
||||
if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0)
|
||||
@@ -278,16 +283,13 @@
|
||||
@@ -278,7 +282,7 @@
|
||||
if (file_printf(ms, "%s", code_mime) == -1)
|
||||
rv = -1;
|
||||
}
|
||||
-#if HAVE_FORK
|
||||
+#if PHP_FILEINFO_UNCOMPRESS
|
||||
done_encoding:
|
||||
-#endif
|
||||
#endif
|
||||
free(u8buf);
|
||||
if (rv)
|
||||
return rv;
|
||||
@@ -287,7 +291,6 @@
|
||||
|
||||
return m;
|
||||
}
|
||||
@ -2171,7 +2179,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
|
||||
protected int
|
||||
file_reset(struct magic_set *ms)
|
||||
@@ -297,11 +299,11 @@
|
||||
@@ -297,11 +300,11 @@
|
||||
return -1;
|
||||
}
|
||||
if (ms->o.buf) {
|
||||
@ -2185,7 +2193,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
ms->o.pbuf = NULL;
|
||||
}
|
||||
ms->event_flags &= ~EVENT_HAD_ERR;
|
||||
@@ -320,7 +322,7 @@
|
||||
@@ -320,7 +323,7 @@
|
||||
protected const char *
|
||||
file_getbuffer(struct magic_set *ms)
|
||||
{
|
||||
@ -2194,7 +2202,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
size_t psize, len;
|
||||
|
||||
if (ms->event_flags & EVENT_HAD_ERR)
|
||||
@@ -339,11 +341,10 @@
|
||||
@@ -339,11 +342,10 @@
|
||||
return NULL;
|
||||
}
|
||||
psize = len * 4 + 1;
|
||||
@ -2207,7 +2215,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
|
||||
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
|
||||
{
|
||||
@@ -403,8 +404,8 @@
|
||||
@@ -403,8 +405,8 @@
|
||||
if (level >= ms->c.len) {
|
||||
len = (ms->c.len += 20) * sizeof(*ms->c.li);
|
||||
ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ?
|
||||
@ -2218,7 +2226,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
if (ms->c.li == NULL) {
|
||||
file_oomem(ms, len);
|
||||
return -1;
|
||||
@@ -427,70 +428,41 @@
|
||||
@@ -427,70 +429,41 @@
|
||||
protected int
|
||||
file_replace(struct magic_set *ms, const char *pat, const char *rep)
|
||||
{
|
||||
@ -2249,7 +2257,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
+ (void)setlocale(LC_CTYPE, "C");
|
||||
+
|
||||
+ opts |= PCRE_MULTILINE;
|
||||
+ convert_libmagic_pattern(&patt, pat, strlen(pat), opts);
|
||||
+ convert_libmagic_pattern(&patt, (char*)pat, strlen(pat), opts);
|
||||
+ if ((pce = pcre_get_compiled_regex_cache(Z_STR(patt))) == NULL) {
|
||||
+ zval_ptr_dtor(&patt);
|
||||
+ rep_cnt = -1;
|
||||
@ -2300,8 +2308,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
- freelocale(rx->c_lc_ctype);
|
||||
-#endif
|
||||
-}
|
||||
+ strncpy(ms->o.buf, res->val, res->len);
|
||||
+ ms->o.buf[res->len] = '\0';
|
||||
+ strncpy(ms->o.buf, ZSTR_VAL(res), ZSTR_LEN(res));
|
||||
+ ms->o.buf[ZSTR_LEN(res)] = '\0';
|
||||
|
||||
-protected void
|
||||
-file_regerror(file_regex_t *rx, int rc, struct magic_set *ms)
|
||||
@ -2318,7 +2326,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
}
|
||||
|
||||
protected file_pushbuf_t *
|
||||
@@ -501,7 +473,7 @@
|
||||
@@ -501,7 +474,7 @@
|
||||
if (ms->event_flags & EVENT_HAD_ERR)
|
||||
return NULL;
|
||||
|
||||
@ -2327,7 +2335,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
return NULL;
|
||||
|
||||
pb->buf = ms->o.buf;
|
||||
@@ -519,8 +491,8 @@
|
||||
@@ -519,8 +492,8 @@
|
||||
char *rbuf;
|
||||
|
||||
if (ms->event_flags & EVENT_HAD_ERR) {
|
||||
@ -2338,7 +2346,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -529,7 +501,7 @@
|
||||
@@ -529,7 +502,7 @@
|
||||
ms->o.buf = pb->buf;
|
||||
ms->offset = pb->offset;
|
||||
|
||||
@ -2347,7 +2355,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
return rbuf;
|
||||
}
|
||||
|
||||
@@ -550,10 +522,11 @@
|
||||
@@ -550,10 +523,11 @@
|
||||
if (ptr >= eptr - 3)
|
||||
break;
|
||||
*ptr++ = '\\';
|
||||
@ -2363,8 +2371,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c
|
||||
}
|
||||
+
|
||||
diff -u libmagic.orig/magic.c libmagic/magic.c
|
||||
--- libmagic.orig/magic.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/magic.c Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/magic.c 2016-01-25 11:31:21.495017704 +0800
|
||||
+++ libmagic/magic.c 2016-01-25 11:31:32.677017695 +0800
|
||||
@@ -25,11 +25,6 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
@ -2753,8 +2761,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c
|
||||
public const char *
|
||||
magic_error(struct magic_set *ms)
|
||||
diff -u libmagic.orig/magic.h libmagic/magic.h
|
||||
--- libmagic.orig/magic.h Sat Feb 21 15:03:56 2015
|
||||
+++ libmagic/magic.h Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/magic.h 2016-01-25 11:31:21.471017705 +0800
|
||||
+++ libmagic/magic.h 2016-01-25 11:31:32.677017695 +0800
|
||||
@@ -88,6 +88,7 @@
|
||||
|
||||
const char *magic_getpath(const char *, int);
|
||||
@ -2772,8 +2780,8 @@ diff -u libmagic.orig/magic.h libmagic/magic.h
|
||||
int magic_errno(magic_t);
|
||||
|
||||
diff -u libmagic.orig/patchlevel.h libmagic/patchlevel.h
|
||||
--- libmagic.orig/patchlevel.h Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/patchlevel.h Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/patchlevel.h 2016-01-25 11:31:21.473017702 +0800
|
||||
+++ libmagic/patchlevel.h 2016-01-25 11:31:32.678017695 +0800
|
||||
@@ -1,34 +1,43 @@
|
||||
#define FILE_VERSION_MAJOR 5
|
||||
-#define patchlevel 6
|
||||
@ -2838,8 +2846,8 @@ diff -u libmagic.orig/patchlevel.h libmagic/patchlevel.h
|
||||
* Revision 1.69 2008/07/02 15:27:05 christos
|
||||
* welcome to 4.25
|
||||
diff -u libmagic.orig/print.c libmagic/print.c
|
||||
--- libmagic.orig/print.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/print.c Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/print.c 2016-01-25 11:31:21.495017704 +0800
|
||||
+++ libmagic/print.c 2016-01-25 11:31:32.678017695 +0800
|
||||
@@ -28,13 +28,17 @@
|
||||
/*
|
||||
* print.c - debugging printout routines
|
||||
@ -3111,8 +3119,8 @@ diff -u libmagic.orig/print.c libmagic/print.c
|
||||
if (tm == NULL)
|
||||
goto out;
|
||||
diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
|
||||
--- libmagic.orig/readcdf.c Thu Mar 5 15:25:12 2015
|
||||
+++ libmagic/readcdf.c Sun Mar 29 18:07:48 2015
|
||||
--- libmagic.orig/readcdf.c 2016-01-25 11:31:21.493017704 +0800
|
||||
+++ libmagic/readcdf.c 2016-01-25 11:31:32.678017695 +0800
|
||||
@@ -26,15 +26,21 @@
|
||||
#include "file.h"
|
||||
|
||||
@ -3237,8 +3245,8 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c
|
||||
#ifdef CDF_DEBUG
|
||||
cdf_dump_catalog(&h, &scn);
|
||||
diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
--- libmagic.orig/softmagic.c Sat Feb 21 15:02:19 2015
|
||||
+++ libmagic/softmagic.c Sun Mar 29 17:55:55 2015
|
||||
--- libmagic.orig/softmagic.c 2016-01-25 11:31:21.471017705 +0800
|
||||
+++ libmagic/softmagic.c 2016-01-25 11:44:35.541684679 +0800
|
||||
@@ -36,11 +36,19 @@
|
||||
#endif /* lint */
|
||||
|
||||
@ -3346,7 +3354,12 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
private int32_t
|
||||
mprint(struct magic_set *ms, struct magic *m)
|
||||
{
|
||||
@@ -635,14 +629,14 @@
|
||||
@@ -630,19 +624,18 @@
|
||||
t = ms->offset + sizeof(double);
|
||||
break;
|
||||
|
||||
- case FILE_SEARCH:
|
||||
case FILE_REGEX: {
|
||||
char *cp;
|
||||
int rval;
|
||||
|
||||
@ -3363,7 +3376,23 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
|
||||
if (rval == -1)
|
||||
return -1;
|
||||
@@ -879,16 +873,16 @@
|
||||
@@ -654,6 +647,15 @@
|
||||
break;
|
||||
}
|
||||
|
||||
+ case FILE_SEARCH:
|
||||
+ if (file_printf(ms, F(ms, m, "%s"), m->value.s) == -1)
|
||||
+ return -1;
|
||||
+ if ((m->str_flags & REGEX_OFFSET_START))
|
||||
+ t = ms->search.offset;
|
||||
+ else
|
||||
+ t = ms->search.offset + m->vallen;
|
||||
+ break;
|
||||
+
|
||||
case FILE_DEFAULT:
|
||||
case FILE_CLEAR:
|
||||
if (file_printf(ms, "%s", m->desc) == -1)
|
||||
@@ -879,16 +881,16 @@
|
||||
if (m->num_mask) \
|
||||
switch (m->mask_op & FILE_OPS_MASK) { \
|
||||
case FILE_OPADD: \
|
||||
@ -3384,7 +3413,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
break; \
|
||||
} \
|
||||
|
||||
@@ -1095,16 +1089,18 @@
|
||||
@@ -1095,17 +1097,26 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3394,24 +3423,33 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
- } else {
|
||||
- linecnt = 0;
|
||||
- bytecnt = m->str_range;
|
||||
- }
|
||||
+ /* bytecnt checks are to be kept for PHP, see cve-2014-3538.
|
||||
+ PCRE might get stuck if the input buffer is too big. */
|
||||
+ linecnt = m->str_range;
|
||||
+ bytecnt = linecnt * 80;
|
||||
+
|
||||
+ if (bytecnt == 0) {
|
||||
+ bytecnt = 1 << 14;
|
||||
}
|
||||
|
||||
- if (bytecnt == 0 || bytecnt > nbytes - offset)
|
||||
- bytecnt = nbytes - offset;
|
||||
+ if (bytecnt == 0) {
|
||||
+ bytecnt = 1 << 14;
|
||||
+ }
|
||||
|
||||
+ if (bytecnt > nbytes) {
|
||||
+ bytecnt = nbytes;
|
||||
+ }
|
||||
|
||||
+ if (offset > bytecnt) {
|
||||
+ offset = bytecnt;
|
||||
+ }
|
||||
+ if (s == NULL) {
|
||||
+ ms->search.s_len = 0;
|
||||
+ ms->search.s = NULL;
|
||||
+ return 0;
|
||||
+ }
|
||||
buf = RCAST(const char *, s) + offset;
|
||||
end = last = RCAST(const char *, s) + bytecnt;
|
||||
@@ -1221,9 +1217,6 @@
|
||||
/* mget() guarantees buf <= last */
|
||||
@@ -1221,9 +1232,6 @@
|
||||
m->type, m->flag, offset, o, nbytes,
|
||||
indir_level, *name_count);
|
||||
mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE));
|
||||
@ -3421,7 +3459,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
}
|
||||
|
||||
if (m->flag & INDIR) {
|
||||
@@ -1593,9 +1586,6 @@
|
||||
@@ -1593,9 +1601,6 @@
|
||||
if ((ms->flags & MAGIC_DEBUG) != 0) {
|
||||
mdebug(offset, (char *)(void *)p,
|
||||
sizeof(union VALUETYPE));
|
||||
@ -3431,7 +3469,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1676,15 +1666,15 @@
|
||||
@@ -1676,15 +1681,15 @@
|
||||
if (rv == 1) {
|
||||
if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
|
||||
file_printf(ms, F(ms, m, "%u"), offset) == -1) {
|
||||
@ -3450,7 +3488,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
return rv;
|
||||
|
||||
case FILE_USE:
|
||||
@@ -1799,6 +1789,41 @@
|
||||
@@ -1799,6 +1804,41 @@
|
||||
return file_strncmp(a, b, len, flags);
|
||||
}
|
||||
|
||||
@ -3462,29 +3500,29 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
+
|
||||
+ t = zend_string_alloc(len * 2 + 4, 0);
|
||||
+
|
||||
+ t->val[j++] = '~';
|
||||
+ ZSTR_VAL(t)[j++] = '~';
|
||||
+
|
||||
+ for (i = 0; i < len; i++, j++) {
|
||||
+ switch (val[i]) {
|
||||
+ case '~':
|
||||
+ t->val[j++] = '\\';
|
||||
+ t->val[j] = '~';
|
||||
+ ZSTR_VAL(t)[j++] = '\\';
|
||||
+ ZSTR_VAL(t)[j] = '~';
|
||||
+ break;
|
||||
+ default:
|
||||
+ t->val[j] = val[i];
|
||||
+ ZSTR_VAL(t)[j] = val[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ t->val[j++] = '~';
|
||||
+ ZSTR_VAL(t)[j++] = '~';
|
||||
+
|
||||
+ if (options & PCRE_CASELESS)
|
||||
+ t->val[j++] = 'i';
|
||||
+ ZSTR_VAL(t)[j++] = 'i';
|
||||
+
|
||||
+ if (options & PCRE_MULTILINE)
|
||||
+ t->val[j++] = 'm';
|
||||
+ ZSTR_VAL(t)[j++] = 'm';
|
||||
+
|
||||
+ t->val[j]='\0';
|
||||
+ t->len = j;
|
||||
+ ZSTR_VAL(t)[j]='\0';
|
||||
+ ZSTR_LEN(t) = j;
|
||||
+
|
||||
+ ZVAL_NEW_STR(pattern, t);
|
||||
+}
|
||||
@ -3492,7 +3530,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
private int
|
||||
magiccheck(struct magic_set *ms, struct magic *m)
|
||||
{
|
||||
@@ -1959,73 +1984,111 @@
|
||||
@@ -1959,73 +1999,77 @@
|
||||
break;
|
||||
}
|
||||
case FILE_REGEX: {
|
||||
@ -3541,7 +3579,55 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
- memcpy(copy, ms->search.s, slen);
|
||||
- copy[--slen] = '\0';
|
||||
- search = copy;
|
||||
- } else {
|
||||
+ /* pce now contains the compiled regex */
|
||||
+ zval retval;
|
||||
+ zval subpats;
|
||||
+ char *haystack;
|
||||
+
|
||||
+ ZVAL_NULL(&retval);
|
||||
+ ZVAL_NULL(&subpats);
|
||||
+
|
||||
+ /* Cut the search len from haystack, equals to REG_STARTEND */
|
||||
+ haystack = estrndup(ms->search.s, ms->search.s_len);
|
||||
+
|
||||
+ /* match v = 0, no match v = 1 */
|
||||
+ php_pcre_match_impl(pce, haystack, ms->search.s_len, &retval, &subpats, 0, 1, PREG_OFFSET_CAPTURE, 0);
|
||||
+ /* Free haystack */
|
||||
+ efree(haystack);
|
||||
+
|
||||
+ if (Z_LVAL(retval) < 0) {
|
||||
+ zval_ptr_dtor(&subpats);
|
||||
+ zval_ptr_dtor(&pattern);
|
||||
+ return -1;
|
||||
+ } else if ((Z_LVAL(retval) > 0) && (Z_TYPE(subpats) == IS_ARRAY)) {
|
||||
+ /* Need to fetch global match which equals pmatch[0] */
|
||||
+ zval *pzval;
|
||||
+ HashTable *ht = Z_ARRVAL(subpats);
|
||||
+ if ((pzval = zend_hash_index_find(ht, 0)) != NULL && Z_TYPE_P(pzval) == IS_ARRAY) {
|
||||
+ /* If everything goes according to the master plan
|
||||
+ tmpcopy now contains two elements:
|
||||
+ 0 = the match
|
||||
+ 1 = starting position of the match */
|
||||
+ zval *match, *offset;
|
||||
+ if ((match = zend_hash_index_find(Z_ARRVAL_P(pzval), 0)) &&
|
||||
+ (offset = zend_hash_index_find(Z_ARRVAL_P(pzval), 1))) {
|
||||
+ if (Z_TYPE_P(match) != IS_STRING && Z_TYPE_P(offset) != IS_LONG) {
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+ ms->search.s += Z_LVAL_P(offset); /* this is where the match starts */
|
||||
+ ms->search.offset += Z_LVAL_P(offset); /* this is where the match starts as size_t */
|
||||
+ ms->search.rm_len = Z_STRLEN_P(match) /* This is the length of the matched pattern */;
|
||||
+ v = 0;
|
||||
+ } else {
|
||||
+ goto error_out;
|
||||
+ }
|
||||
+ } else {
|
||||
+error_out:
|
||||
+ zval_ptr_dtor(&subpats);
|
||||
+ zval_ptr_dtor(&pattern);
|
||||
+ return -1;
|
||||
+ }
|
||||
} else {
|
||||
- search = ms->search.s;
|
||||
- copy = NULL;
|
||||
- }
|
||||
@ -3563,97 +3649,15 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
- (size_t)(pmatch[0].rm_eo - pmatch[0].rm_so);
|
||||
- v = 0;
|
||||
- break;
|
||||
+ /* pce now contains the compiled regex */
|
||||
+ zval retval;
|
||||
+ zval subpats;
|
||||
+ char *haystack;
|
||||
+
|
||||
+ ZVAL_NULL(&retval);
|
||||
+ ZVAL_NULL(&subpats);
|
||||
+
|
||||
+ /* Cut the search len from haystack, equals to REG_STARTEND */
|
||||
+ haystack = estrndup(ms->search.s, ms->search.s_len);
|
||||
+
|
||||
+ /* match v = 0, no match v = 1 */
|
||||
+ php_pcre_match_impl(pce, haystack, ms->search.s_len, &retval, &subpats, 1, 1, PREG_OFFSET_CAPTURE, 0);
|
||||
+ /* Free haystack */
|
||||
+ efree(haystack);
|
||||
+
|
||||
+ if (Z_LVAL(retval) < 0) {
|
||||
+ zval_ptr_dtor(&subpats);
|
||||
+ zval_ptr_dtor(&pattern);
|
||||
+ return -1;
|
||||
+ } else if ((Z_LVAL(retval) > 0) && (Z_TYPE(subpats) == IS_ARRAY)) {
|
||||
+ /* Need to fetch global match which equals pmatch[0] */
|
||||
+ zval *pzval;
|
||||
+ HashTable *ht = Z_ARRVAL(subpats);
|
||||
+ zval *pattern_match = NULL, *pattern_offset = NULL;
|
||||
+ int first = 1, inner_first;
|
||||
+
|
||||
+ ZEND_HASH_FOREACH_VAL(ht, pzval) {
|
||||
+ HashTable *inner_ht;
|
||||
+ zval *match, *offset;
|
||||
+ zval tmpcopy, matchcopy, offsetcopy;
|
||||
+
|
||||
+ if (first) {
|
||||
+ first = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+ ZVAL_DUP(&tmpcopy, pzval);
|
||||
|
||||
-
|
||||
- case REG_NOMATCH:
|
||||
- v = 1;
|
||||
v = 1;
|
||||
- break;
|
||||
+ inner_ht = Z_ARRVAL(tmpcopy);
|
||||
|
||||
-
|
||||
- default:
|
||||
- file_regerror(&rx, rc, ms);
|
||||
- v = (uint64_t)-1;
|
||||
- break;
|
||||
+ /* If everything goes according to the master plan
|
||||
+ tmpcopy now contains two elements:
|
||||
+ 0 = the match
|
||||
+ 1 = starting position of the match */
|
||||
+ inner_first = 1;
|
||||
+ ZEND_HASH_FOREACH_VAL(inner_ht, match) {
|
||||
+ if (inner_first) {
|
||||
+ inner_first = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+ ZVAL_DUP(&matchcopy, match);
|
||||
+ convert_to_string(&matchcopy);
|
||||
+ pattern_match = &matchcopy;
|
||||
+ } ZEND_HASH_FOREACH_END();
|
||||
+
|
||||
+ inner_first = 1;
|
||||
+ ZEND_HASH_FOREACH_VAL(inner_ht, offset) {
|
||||
+ if (inner_first) {
|
||||
+ inner_first = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+ ZVAL_DUP(&offsetcopy, offset);
|
||||
+ convert_to_long(&offsetcopy);
|
||||
+ pattern_offset = &offsetcopy;
|
||||
+ } ZEND_HASH_FOREACH_END();
|
||||
+
|
||||
+ zval_dtor(&tmpcopy);
|
||||
+
|
||||
+ if ((pattern_match != NULL) && (pattern_offset != NULL)) {
|
||||
+ ms->search.s += Z_LVAL_P(pattern_offset); /* this is where the match starts */
|
||||
+ ms->search.offset += Z_LVAL_P(pattern_offset); /* this is where the match starts as size_t */
|
||||
+ ms->search.rm_len = Z_STRLEN_P(pattern_match) /* This is the length of the matched pattern */;
|
||||
+ v = 0;
|
||||
+
|
||||
+ zval_ptr_dtor(pattern_match);
|
||||
+ zval_ptr_dtor(pattern_offset);
|
||||
+ } else {
|
||||
+ zval_ptr_dtor(&subpats);
|
||||
+ zval_ptr_dtor(&pattern);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ } ZEND_HASH_FOREACH_END();
|
||||
+ } else {
|
||||
+ v = 1;
|
||||
}
|
||||
+ zval_ptr_dtor(&subpats);
|
||||
+ zval_ptr_dtor(&pattern);
|
||||
@ -3665,8 +3669,8 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c
|
||||
}
|
||||
case FILE_INDIRECT:
|
||||
diff -u libmagic.orig/strcasestr.c libmagic/strcasestr.c
|
||||
--- libmagic.orig/strcasestr.c Mon Feb 9 15:48:48 2015
|
||||
+++ libmagic/strcasestr.c Wed Mar 18 20:10:15 2015
|
||||
--- libmagic.orig/strcasestr.c 2016-01-25 11:31:21.494017704 +0800
|
||||
+++ libmagic/strcasestr.c 2016-01-25 11:31:32.678017695 +0800
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
#include "file.h"
|
||||
|
@ -3005,7 +3005,6 @@ apprentice_compile(struct magic_set *ms, struct magic_map *map, const char *fn)
|
||||
{
|
||||
static const size_t nm = sizeof(*map->nmagic) * MAGIC_SETS;
|
||||
static const size_t m = sizeof(**map->magic);
|
||||
int fd = -1;
|
||||
size_t len;
|
||||
char *dbname;
|
||||
int rv = -1;
|
||||
|
@ -61,7 +61,6 @@ extern public void convert_libmagic_pattern(zval *pattern, char *val, int len, i
|
||||
protected int
|
||||
file_printf(struct magic_set *ms, const char *fmt, ...)
|
||||
{
|
||||
int rv;
|
||||
va_list ap;
|
||||
int len;
|
||||
char *buf = NULL, *newstr;
|
||||
@ -283,7 +282,9 @@ simple:
|
||||
if (file_printf(ms, "%s", code_mime) == -1)
|
||||
rv = -1;
|
||||
}
|
||||
#if PHP_FILEINFO_UNCOMPRESS
|
||||
done_encoding:
|
||||
#endif
|
||||
free(u8buf);
|
||||
if (rv)
|
||||
return rv;
|
||||
@ -438,7 +439,7 @@ file_replace(struct magic_set *ms, const char *pat, const char *rep)
|
||||
(void)setlocale(LC_CTYPE, "C");
|
||||
|
||||
opts |= PCRE_MULTILINE;
|
||||
convert_libmagic_pattern(&patt, pat, strlen(pat), opts);
|
||||
convert_libmagic_pattern(&patt, (char*)pat, strlen(pat), opts);
|
||||
if ((pce = pcre_get_compiled_regex_cache(Z_STR(patt))) == NULL) {
|
||||
zval_ptr_dtor(&patt);
|
||||
rep_cnt = -1;
|
||||
|
@ -2028,7 +2028,7 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
||||
haystack = estrndup(ms->search.s, ms->search.s_len);
|
||||
|
||||
/* match v = 0, no match v = 1 */
|
||||
php_pcre_match_impl(pce, haystack, ms->search.s_len, &retval, &subpats, 1, 1, PREG_OFFSET_CAPTURE, 0);
|
||||
php_pcre_match_impl(pce, haystack, ms->search.s_len, &retval, &subpats, 0, 1, PREG_OFFSET_CAPTURE, 0);
|
||||
/* Free haystack */
|
||||
efree(haystack);
|
||||
|
||||
@ -2040,64 +2040,30 @@ magiccheck(struct magic_set *ms, struct magic *m)
|
||||
/* Need to fetch global match which equals pmatch[0] */
|
||||
zval *pzval;
|
||||
HashTable *ht = Z_ARRVAL(subpats);
|
||||
zval *pattern_match = NULL, *pattern_offset = NULL;
|
||||
int first = 1, inner_first;
|
||||
|
||||
ZEND_HASH_FOREACH_VAL(ht, pzval) {
|
||||
HashTable *inner_ht;
|
||||
zval *match, *offset;
|
||||
zval tmpcopy, matchcopy, offsetcopy;
|
||||
|
||||
if (first) {
|
||||
first = 0;
|
||||
continue;
|
||||
}
|
||||
ZVAL_DUP(&tmpcopy, pzval);
|
||||
|
||||
inner_ht = Z_ARRVAL(tmpcopy);
|
||||
|
||||
if ((pzval = zend_hash_index_find(ht, 0)) != NULL && Z_TYPE_P(pzval) == IS_ARRAY) {
|
||||
/* If everything goes according to the master plan
|
||||
tmpcopy now contains two elements:
|
||||
0 = the match
|
||||
1 = starting position of the match */
|
||||
inner_first = 1;
|
||||
ZEND_HASH_FOREACH_VAL(inner_ht, match) {
|
||||
if (inner_first) {
|
||||
inner_first = 0;
|
||||
continue;
|
||||
zval *match, *offset;
|
||||
if ((match = zend_hash_index_find(Z_ARRVAL_P(pzval), 0)) &&
|
||||
(offset = zend_hash_index_find(Z_ARRVAL_P(pzval), 1))) {
|
||||
if (Z_TYPE_P(match) != IS_STRING && Z_TYPE_P(offset) != IS_LONG) {
|
||||
goto error_out;
|
||||
}
|
||||
ZVAL_DUP(&matchcopy, match);
|
||||
convert_to_string(&matchcopy);
|
||||
pattern_match = &matchcopy;
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
inner_first = 1;
|
||||
ZEND_HASH_FOREACH_VAL(inner_ht, offset) {
|
||||
if (inner_first) {
|
||||
inner_first = 0;
|
||||
continue;
|
||||
}
|
||||
ZVAL_DUP(&offsetcopy, offset);
|
||||
convert_to_long(&offsetcopy);
|
||||
pattern_offset = &offsetcopy;
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
zval_dtor(&tmpcopy);
|
||||
|
||||
if ((pattern_match != NULL) && (pattern_offset != NULL)) {
|
||||
ms->search.s += Z_LVAL_P(pattern_offset); /* this is where the match starts */
|
||||
ms->search.offset += Z_LVAL_P(pattern_offset); /* this is where the match starts as size_t */
|
||||
ms->search.rm_len = Z_STRLEN_P(pattern_match) /* This is the length of the matched pattern */;
|
||||
ms->search.s += Z_LVAL_P(offset); /* this is where the match starts */
|
||||
ms->search.offset += Z_LVAL_P(offset); /* this is where the match starts as size_t */
|
||||
ms->search.rm_len = Z_STRLEN_P(match) /* This is the length of the matched pattern */;
|
||||
v = 0;
|
||||
|
||||
zval_ptr_dtor(pattern_match);
|
||||
zval_ptr_dtor(pattern_offset);
|
||||
} else {
|
||||
zval_ptr_dtor(&subpats);
|
||||
zval_ptr_dtor(&pattern);
|
||||
return -1;
|
||||
goto error_out;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} else {
|
||||
error_out:
|
||||
zval_ptr_dtor(&subpats);
|
||||
zval_ptr_dtor(&pattern);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
v = 1;
|
||||
}
|
||||
|
17
ext/fileinfo/tests/bug71434.phpt
Normal file
17
ext/fileinfo/tests/bug71434.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #68735 fileinfo out-of-bounds memory access
|
||||
--SKIPIF--
|
||||
<?php require_once(dirname(__FILE__) . '/skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$a='#!env python
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from serial import Serial
|
||||
from sys import exit
|
||||
';
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
echo $finfo->buffer($a) . "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
text/x-python
|
@ -14,11 +14,11 @@ PHP_ARG_ENABLE(huge-code-pages, whether to enable copying PHP CODE pages into HU
|
||||
|
||||
if test "$PHP_OPCACHE" != "no"; then
|
||||
|
||||
if test "$PHP_OPCACHE_FILE" == "yes"; then
|
||||
if test "$PHP_OPCACHE_FILE" = "yes"; then
|
||||
AC_DEFINE(HAVE_OPCACHE_FILE_CACHE, 1, [Define to enable file based caching (experimental)])
|
||||
fi
|
||||
|
||||
if test "$PHP_HUGE_CODE_PAGES" == "yes"; then
|
||||
if test "$PHP_HUGE_CODE_PAGES" = "yes"; then
|
||||
AC_DEFINE(HAVE_HUGE_CODE_PAGES, 1, [Define to enable copying PHP CODE pages into HUGE PAGES (experimental)])
|
||||
fi
|
||||
|
||||
|
@ -3,6 +3,7 @@ Bug #65915 (Inconsistent results with require return value)
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.file_cache_only=0
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
@ -13,7 +14,7 @@ file_put_contents($tmp, '<?php return function(){ return "a";};');
|
||||
$f = require $tmp;
|
||||
var_dump($f());
|
||||
|
||||
opcache_invalidate($tmp, true);
|
||||
var_dump(opcache_invalidate($tmp, true));
|
||||
|
||||
file_put_contents($tmp, '<?php return function(){ return "b";};');
|
||||
$f = require $tmp;
|
||||
@ -23,4 +24,5 @@ var_dump($f());
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "a"
|
||||
bool(true)
|
||||
string(1) "b"
|
||||
|
17
ext/opcache/tests/bug71443.phpt
Normal file
17
ext/opcache/tests/bug71443.phpt
Normal file
@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Bug #71443 (Segfault using built-in webserver with intl using symfony)
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.file_cache=/tmp/
|
||||
opcache.file_cache_only=1
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
<?php if (substr(PHP_OS, 0, 3) == 'WIN') die('skip.. not for Windows'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
ini_set("include_path", "/tmp");
|
||||
?>
|
||||
okey
|
||||
--EXPECT--
|
||||
okey
|
@ -1317,6 +1317,10 @@ PHP_MSHUTDOWN_FUNCTION(openssl)
|
||||
{
|
||||
EVP_cleanup();
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00090805f
|
||||
ERR_free_strings();
|
||||
#endif
|
||||
|
||||
php_unregister_url_stream_wrapper("https");
|
||||
php_unregister_url_stream_wrapper("ftps");
|
||||
|
||||
@ -4938,6 +4942,7 @@ PHP_FUNCTION(openssl_seal)
|
||||
memset(eks, 0, sizeof(*eks) * nkeys);
|
||||
key_resources = safe_emalloc(nkeys, sizeof(zend_resource*), 0);
|
||||
memset(key_resources, 0, sizeof(zend_resource*) * nkeys);
|
||||
memset(pkeys, 0, sizeof(*pkeys) * nkeys);
|
||||
|
||||
/* get the public keys we are using to seal this data */
|
||||
i = 0;
|
||||
@ -4999,7 +5004,7 @@ PHP_FUNCTION(openssl_seal)
|
||||
|
||||
clean_exit:
|
||||
for (i=0; i<nkeys; i++) {
|
||||
if (key_resources[i] == NULL) {
|
||||
if (key_resources[i] == NULL && pkeys[i] != NULL) {
|
||||
EVP_PKEY_free(pkeys[i]);
|
||||
}
|
||||
if (eks[i]) {
|
||||
|
@ -1,32 +0,0 @@
|
||||
--TEST--
|
||||
openssl_seal() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$a = 1;
|
||||
$b = array(1);
|
||||
$c = array(1);
|
||||
$d = array(1);
|
||||
|
||||
var_dump(openssl_seal($a, $b, $c, $d));
|
||||
var_dump(openssl_seal($a, $a, $a, array()));
|
||||
var_dump(openssl_seal($c, $c, $c, 1));
|
||||
var_dump(openssl_seal($b, $b, $b, ""));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: openssl_seal(): not a public key (1th member of pubkeys) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_seal(): Fourth argument to openssl_seal() must be a non-empty array in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_seal() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: openssl_seal() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
Done
|
@ -1,60 +0,0 @@
|
||||
--TEST--
|
||||
openssl_x509_read() and openssl_x509_free() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$fp = fopen(dirname(__FILE__) . "/cert.crt","r");
|
||||
$a = fread($fp,8192);
|
||||
fclose($fp);
|
||||
|
||||
$b = "file://" . dirname(__FILE__) . "/cert.crt";
|
||||
$c = "invalid cert";
|
||||
$d = openssl_x509_read($a);
|
||||
$e = array();
|
||||
$f = array($b);
|
||||
|
||||
var_dump($res = openssl_x509_read($a)); // read cert as a string
|
||||
openssl_x509_free($res);
|
||||
var_dump($res);
|
||||
var_dump($res = openssl_x509_read($b)); // read cert as a filename string
|
||||
openssl_x509_free($res);
|
||||
var_dump($res);
|
||||
var_dump($res = openssl_x509_read($c)); // read an invalid cert, fails
|
||||
openssl_x509_free($res);
|
||||
var_dump($res);
|
||||
var_dump($res = openssl_x509_read($d)); // read cert from a resource
|
||||
openssl_x509_free($res);
|
||||
var_dump($res);
|
||||
var_dump($res = openssl_x509_read($e)); // read an array
|
||||
openssl_x509_free($res);
|
||||
var_dump($res);
|
||||
var_dump($res = openssl_x509_read($f)); // read an array with the filename
|
||||
openssl_x509_free($res);
|
||||
var_dump($res);
|
||||
?>
|
||||
--EXPECTF--
|
||||
resource(%d) of type (OpenSSL X.509)
|
||||
resource(%d) of type (Unknown)
|
||||
resource(%d) of type (OpenSSL X.509)
|
||||
resource(%d) of type (Unknown)
|
||||
|
||||
Warning: openssl_x509_read(): supplied parameter cannot be coerced into an X509 certificate! in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_x509_free() expects parameter 1 to be resource, boolean given in %s on line %d
|
||||
bool(false)
|
||||
resource(%d) of type (OpenSSL X.509)
|
||||
resource(%d) of type (Unknown)
|
||||
|
||||
Warning: openssl_x509_read(): supplied parameter cannot be coerced into an X509 certificate! in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_x509_free() expects parameter 1 to be resource, boolean given in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_x509_read(): supplied parameter cannot be coerced into an X509 certificate! in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_x509_free() expects parameter 1 to be resource, boolean given in %s on line %d
|
||||
bool(false)
|
@ -1,79 +0,0 @@
|
||||
--TEST--
|
||||
openssl_x509_export() and openssl_x509_export_to_file() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$fp = fopen(dirname(__FILE__) . "/cert.crt","r");
|
||||
$a = fread($fp,8192);
|
||||
fclose($fp);
|
||||
|
||||
$b = "file://" . dirname(__FILE__) . "/cert.crt";
|
||||
$c = "invalid cert";
|
||||
$d = openssl_x509_read($a);
|
||||
$e = array();
|
||||
|
||||
var_dump(openssl_x509_export($a, $output)); // read cert as a binary string
|
||||
var_dump(openssl_x509_export($b, $output2)); // read cert from a filename string
|
||||
var_dump(openssl_x509_export($c, $output3)); // read an invalid cert, fails
|
||||
var_dump(openssl_x509_export($d, $output4)); // read cert from a resource
|
||||
var_dump(openssl_x509_export($e, $output5)); // read an array, fails
|
||||
|
||||
$outfilename = tempnam("/tmp", "ssl");
|
||||
if ($outfilename === false)
|
||||
die("failed to get a temporary filename!");
|
||||
|
||||
echo "---\n";
|
||||
|
||||
var_dump(openssl_x509_export_to_file($a, $outfilename)); // read cert as a binary string
|
||||
var_dump(openssl_x509_export_to_file($b, $outfilename)); // read cert from a filename string
|
||||
var_dump(openssl_x509_export_to_file($c, $outfilename)); // read an invalid cert, fails
|
||||
var_dump(openssl_x509_export_to_file($d, $outfilename)); // read cert from a resource
|
||||
var_dump(openssl_x509_export_to_file($e, $outfilename)); // read an array, fails
|
||||
echo "---\n";
|
||||
|
||||
var_dump($exists = file_exists($outfilename));
|
||||
if ($exists) {
|
||||
@unlink($outfilename);
|
||||
}
|
||||
echo "---\n";
|
||||
|
||||
if (PHP_EOL !== "\n") {
|
||||
$a = str_replace(PHP_EOL, "\n", $a);
|
||||
}
|
||||
|
||||
var_dump(strcmp($output, $a));
|
||||
var_dump(strcmp($output, $output2));
|
||||
var_dump(strcmp($output, $output3));
|
||||
var_dump(strcmp($output, $output4)); // different
|
||||
var_dump(strcmp($output, $output5)); // different
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
---
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export_to_file(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export_to_file(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
---
|
||||
bool(true)
|
||||
---
|
||||
int(0)
|
||||
int(0)
|
||||
int(%d)
|
||||
int(0)
|
||||
int(%d)
|
@ -1,27 +0,0 @@
|
||||
--TEST--
|
||||
openssl_seal() error tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$data = "openssl_open() test";
|
||||
$pub_key = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$wrong = "wrong";
|
||||
|
||||
openssl_seal($data, $sealed, $ekeys, array($pub_key)); // no output
|
||||
openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key)); // no output
|
||||
openssl_seal($data, $sealed, $ekeys, array($pub_key, $wrong));
|
||||
openssl_seal($data, $sealed, $ekeys, $pub_key);
|
||||
openssl_seal($data, $sealed, $ekeys, array());
|
||||
openssl_seal($data, $sealed, $ekeys, array($wrong));
|
||||
?>
|
||||
--EXPECTF--
|
||||
|
||||
Warning: openssl_seal(): not a public key (2th member of pubkeys) in %s on line %d
|
||||
|
||||
Warning: openssl_seal() expects parameter 4 to be array, string given in %s on line %d
|
||||
|
||||
Warning: openssl_seal(): Fourth argument to openssl_seal() must be a non-empty array in %s on line %d
|
||||
|
||||
Warning: openssl_seal(): not a public key (1th member of pubkeys) in %s on line %d
|
||||
|
@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Options type checks
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$x = openssl_pkey_new();
|
||||
$csr = openssl_csr_new(["countryName" => "DE"], $x, ["x509_extensions" => 0xDEADBEEF]);
|
||||
?>
|
||||
DONE
|
||||
--EXPECT--
|
||||
DONE
|
@ -14,7 +14,7 @@ if (!in_array('AES-128-CBC', openssl_get_cipher_methods(true))) {
|
||||
$data = "openssl_seal() test";
|
||||
$cipher = 'AES-128-CBC';
|
||||
$pub_key = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$priv_key = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$priv_key = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
|
||||
openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), $cipher);
|
||||
openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), 'sparkles', $iv);
|
||||
|
16
ext/openssl/tests/bug71475.phpt
Normal file
16
ext/openssl/tests/bug71475.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Bug #71475: openssl_seal() uninitialized memory usage
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip openssl not loaded");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$_ = str_repeat("A", 512);
|
||||
openssl_seal($_, $_, $_, array_fill(0,64,0));
|
||||
?>
|
||||
DONE
|
||||
--EXPECTF--
|
||||
|
||||
Warning: openssl_seal(): not a public key (1th member of pubkeys) in %s%ebug71475.php on line %d
|
||||
DONE
|
@ -14,7 +14,7 @@ $dn = array(
|
||||
"localityName" => "Porto Alegre",
|
||||
"commonName" => "Henrique do N. Angelo",
|
||||
"emailAddress" => "hnangelo@php.net"
|
||||
);
|
||||
);
|
||||
|
||||
$args = array(
|
||||
"digest_alg" => "sha1",
|
||||
@ -22,7 +22,7 @@ $args = array(
|
||||
"private_key_type" => OPENSSL_KEYTYPE_DSA,
|
||||
"encrypt_key" => true,
|
||||
"config" => $config,
|
||||
);
|
||||
);
|
||||
|
||||
$privkey = openssl_pkey_new($config_arg);
|
||||
$csr = openssl_csr_new($dn, $privkey, $args);
|
@ -8,7 +8,7 @@ if (!function_exists("utf8_decode")) die("skip");
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$csr = file_get_contents(dirname(__FILE__) . '/005_crt.txt');
|
||||
$csr = file_get_contents(dirname(__FILE__) . '/cert.csr');
|
||||
if ($out = openssl_csr_get_subject($csr, 1)) {
|
||||
var_dump($out);
|
||||
}
|
@ -11,11 +11,15 @@ var_dump(openssl_csr_new(1,$a,1,1));
|
||||
$a = array();
|
||||
var_dump(openssl_csr_new(array(), $a, array('config' => __DIR__ . DIRECTORY_SEPARATOR . 'openssl.cnf'), array()));
|
||||
|
||||
//this leaks
|
||||
// this leaks
|
||||
$a = array(1,2);
|
||||
$b = array(1,2);
|
||||
var_dump(openssl_csr_new($a, $b, array('config' => __DIR__ . DIRECTORY_SEPARATOR . 'openssl.cnf')));
|
||||
|
||||
// options type check
|
||||
$x = openssl_pkey_new();
|
||||
var_dump(openssl_csr_new(["countryName" => "DE"], $x, ["x509_extensions" => 0xDEADBEEF]));
|
||||
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
@ -31,4 +35,5 @@ Warning: openssl_csr_new(): key array must be of the form array(0 => key, 1 => p
|
||||
Warning: openssl_csr_new(): add1_attr_by_txt challengePassword_min -> 4 (failed; check error queue and value of string_mask OpenSSL option if illegal characters are reported) in %s on line %d
|
||||
bool(false)
|
||||
resource(%d) of type (OpenSSL X.509 CSR)
|
||||
resource(%d) of type (OpenSSL X.509 CSR)
|
||||
Done
|
@ -5,7 +5,7 @@ openssl_csr_sign() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$cert = "file://" . dirname(__FILE__) . "/cert.crt";
|
||||
$priv = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$priv = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$wrong = "wrong";
|
||||
$pub = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$config = __DIR__ . DIRECTORY_SEPARATOR . 'openssl.cnf';
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
openssl_encrypt() and openssl_decrypt() tests
|
||||
openssl_decrypt() tests dependent on openssl_encrypt
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
@ -6,7 +6,7 @@ openssl_open() tests
|
||||
<?php
|
||||
$data = "openssl_open() test";
|
||||
$pub_key = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$priv_key = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$priv_key = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$wrong = "wrong";
|
||||
|
||||
openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key, $pub_key));
|
@ -5,7 +5,7 @@ openssl_pkcs7_decrypt() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$infile = dirname(__FILE__) . "/cert.crt";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$encrypted = tempnam("/tmp", "ssl");
|
||||
if ($encrypted === false)
|
||||
die("failed to get a temporary filename!");
|
@ -6,7 +6,7 @@ openssl_pkcs7_decrypt() and invalid parameters
|
||||
<?php
|
||||
|
||||
function myErrorHandler($errno, $errstr, $errfile, $errline) {
|
||||
var_dump($errstr);
|
||||
var_dump($errstr);
|
||||
}
|
||||
set_error_handler("myErrorHandler");
|
||||
|
@ -13,7 +13,7 @@ if ($outfile2 === false)
|
||||
die("failed to get a temporary filename!");
|
||||
|
||||
$single_cert = "file://" . dirname(__FILE__) . "/cert.crt";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$multi_certs = array($single_cert, $single_cert);
|
||||
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_pkcs7_encrypt()");
|
||||
$headers = array("test@test", "testing openssl_pkcs7_encrypt()");
|
@ -6,10 +6,11 @@ openssl_pkcs7_sign() tests
|
||||
<?php
|
||||
$infile = dirname(__FILE__) . "/cert.crt";
|
||||
$outfile = tempnam("/tmp", "ssl");
|
||||
if ($outfile === false)
|
||||
if ($outfile === false) {
|
||||
die("failed to get a temporary filename!");
|
||||
}
|
||||
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$single_cert = "file://" . dirname(__FILE__) . "/cert.crt";
|
||||
$assoc_headers = array("To" => "test@test", "Subject" => "testing openssl_pkcs7_sign()");
|
||||
$headers = array("test@test", "testing openssl_pkcs7_sign()");
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
openssl_pkey_new() with an empty sub-array arg generates a malformed resource
|
||||
openssl_pkey_new() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
@ -5,7 +5,7 @@ openssl_private_decrypt() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$data = "Testing openssl_public_decrypt()";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$pubkey = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$wrong = "wrong";
|
||||
|
@ -5,13 +5,14 @@ openssl_private_encrypt() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$data = "Testing openssl_private_encrypt()";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$pubkey = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$wrong = "wrong";
|
||||
|
||||
class test {
|
||||
function __toString() {
|
||||
return "test";
|
||||
}
|
||||
function __toString() {
|
||||
return "test";
|
||||
}
|
||||
}
|
||||
$obj = new test;
|
||||
|
@ -5,7 +5,7 @@ openssl_public_decrypt() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$data = "Testing openssl_public_decrypt()";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$pubkey = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$wrong = "wrong";
|
||||
|
@ -5,13 +5,14 @@ openssl_public_encrypt() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$data = "Testing openssl_public_encrypt()";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$pubkey = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$wrong = "wrong";
|
||||
|
||||
class test {
|
||||
function __toString() {
|
||||
return "test";
|
||||
}
|
||||
function __toString() {
|
||||
return "test";
|
||||
}
|
||||
}
|
||||
$obj = new test;
|
||||
|
58
ext/openssl/tests/openssl_seal_basic.phpt
Normal file
58
ext/openssl/tests/openssl_seal_basic.phpt
Normal file
@ -0,0 +1,58 @@
|
||||
--TEST--
|
||||
openssl_seal() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
// simple tests
|
||||
$a = 1;
|
||||
$b = array(1);
|
||||
$c = array(1);
|
||||
$d = array(1);
|
||||
|
||||
var_dump(openssl_seal($a, $b, $c, $d));
|
||||
var_dump(openssl_seal($a, $a, $a, array()));
|
||||
var_dump(openssl_seal($c, $c, $c, 1));
|
||||
var_dump(openssl_seal($b, $b, $b, ""));
|
||||
|
||||
// tests with cert
|
||||
$data = "openssl_open() test";
|
||||
$pub_key = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$wrong = "wrong";
|
||||
|
||||
var_dump(openssl_seal($data, $sealed, $ekeys, array($pub_key))); // no output
|
||||
var_dump(openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key))); // no output
|
||||
var_dump(openssl_seal($data, $sealed, $ekeys, array($pub_key, $wrong)));
|
||||
var_dump(openssl_seal($data, $sealed, $ekeys, $pub_key));
|
||||
var_dump(openssl_seal($data, $sealed, $ekeys, array()));
|
||||
var_dump(openssl_seal($data, $sealed, $ekeys, array($wrong)));
|
||||
|
||||
echo "Done\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: openssl_seal(): not a public key (1th member of pubkeys) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_seal(): Fourth argument to openssl_seal() must be a non-empty array in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_seal() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: openssl_seal() expects parameter 1 to be string, array given in %s on line %d
|
||||
NULL
|
||||
int(19)
|
||||
int(19)
|
||||
|
||||
Warning: openssl_seal(): not a public key (2th member of pubkeys) in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_seal() expects parameter 4 to be array, string given in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: openssl_seal(): Fourth argument to openssl_seal() must be a non-empty array in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_seal(): not a public key (1th member of pubkeys) in %s on line %d
|
||||
bool(false)
|
||||
Done
|
@ -5,7 +5,7 @@ openssl_sign() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$data = "Testing openssl_sign()";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$wrong = "wrong";
|
||||
|
||||
var_dump(openssl_sign($data, $sign, $privkey)); // no output
|
@ -1,62 +0,0 @@
|
||||
--TEST--
|
||||
Testing openssl_spki_export()
|
||||
Creates SPKAC for all available key sizes & signature algorithms and exports public key
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip");
|
||||
if (!@openssl_pkey_new()) die("skip cannot create private key");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* array of private key sizes to test */
|
||||
$ksize = array('1024'=>1024,
|
||||
'2048'=>2048,
|
||||
'4096'=>4096);
|
||||
|
||||
/* array of available hashings to test */
|
||||
$algo = array('md4'=>OPENSSL_ALGO_MD4,
|
||||
'md5'=>OPENSSL_ALGO_MD5,
|
||||
'sha1'=>OPENSSL_ALGO_SHA1,
|
||||
'sha224'=>OPENSSL_ALGO_SHA224,
|
||||
'sha256'=>OPENSSL_ALGO_SHA256,
|
||||
'sha384'=>OPENSSL_ALGO_SHA384,
|
||||
'sha512'=>OPENSSL_ALGO_SHA512,
|
||||
'rmd160'=>OPENSSL_ALGO_RMD160);
|
||||
|
||||
/* loop over key sizes for test */
|
||||
foreach($ksize as $k => $v) {
|
||||
|
||||
/* generate new private key of specified size to use for tests */
|
||||
$pkey = openssl_pkey_new(array('digest_alg' => 'sha512',
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
'private_key_bits' => $v));
|
||||
openssl_pkey_export($pkey, $pass);
|
||||
|
||||
/* loop to create and verify results */
|
||||
foreach($algo as $key => $value) {
|
||||
$spkac = openssl_spki_new($pkey, _uuid(), $value);
|
||||
echo openssl_spki_export(preg_replace('/SPKAC=/', '', $spkac));
|
||||
}
|
||||
openssl_free_key($pkey);
|
||||
}
|
||||
|
||||
/* generate a random challenge */
|
||||
function _uuid()
|
||||
{
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
60
ext/openssl/tests/openssl_spki_export_basic.phpt
Normal file
60
ext/openssl/tests/openssl_spki_export_basic.phpt
Normal file
@ -0,0 +1,60 @@
|
||||
--TEST--
|
||||
openssl_spki_export() tests for exporting public key
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip");
|
||||
if (!@openssl_pkey_new()) die("skip cannot create private key");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* array of private key sizes to test */
|
||||
$key_sizes = array(1024, 2048, 4096);
|
||||
$pkeys = array();
|
||||
foreach ($key_sizes as $key_size) {
|
||||
$key_file = "file://" . dirname(__FILE__) . "/private_rsa_" . $key_size . ".key";
|
||||
$pkeys[] = openssl_pkey_get_private($key_file);
|
||||
}
|
||||
|
||||
|
||||
/* array of available hashings to test */
|
||||
$algo = array(
|
||||
OPENSSL_ALGO_MD4,
|
||||
OPENSSL_ALGO_MD5,
|
||||
OPENSSL_ALGO_SHA1,
|
||||
OPENSSL_ALGO_SHA224,
|
||||
OPENSSL_ALGO_SHA256,
|
||||
OPENSSL_ALGO_SHA384,
|
||||
OPENSSL_ALGO_SHA512,
|
||||
OPENSSL_ALGO_RMD160
|
||||
);
|
||||
|
||||
/* loop over key sizes for test */
|
||||
foreach ($pkeys as $pkey) {
|
||||
|
||||
/* loop to create and verify results */
|
||||
foreach ($algo as $value) {
|
||||
$spkac = openssl_spki_new($pkey, _uuid(), $value);
|
||||
echo openssl_spki_export(preg_replace('/SPKAC=/', '', $spkac));
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a random challenge */
|
||||
function _uuid() {
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
||||
\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-.*\-\-\-\-\-END PUBLIC KEY\-\-\-\-\-
|
@ -1,6 +1,5 @@
|
||||
--TEST--
|
||||
Testing openssl_spki_export_challenge()
|
||||
Creates SPKAC for all available key sizes & signature algorithms and exports challenge
|
||||
openssl_spki_export_challenge() tests for exporting challenge
|
||||
--INI--
|
||||
error_reporting=0
|
||||
--SKIPIF--
|
||||
@ -12,47 +11,46 @@ if (!@openssl_pkey_new()) die("skip cannot create private key");
|
||||
<?php
|
||||
|
||||
/* array of private key sizes to test */
|
||||
$ksize = array('1024'=>1024,
|
||||
'2048'=>2048,
|
||||
'4096'=>4096);
|
||||
$key_sizes = array(1024, 2048, 4096);
|
||||
$pkeys = array();
|
||||
foreach ($key_sizes as $key_size) {
|
||||
$key_file = "file://" . dirname(__FILE__) . "/private_rsa_" . $key_size . ".key";
|
||||
$pkeys[] = openssl_pkey_get_private($key_file);
|
||||
}
|
||||
|
||||
|
||||
/* array of available hashings to test */
|
||||
$algo = array('md4'=>OPENSSL_ALGO_MD4,
|
||||
'md5'=>OPENSSL_ALGO_MD5,
|
||||
'sha1'=>OPENSSL_ALGO_SHA1,
|
||||
'sha224'=>OPENSSL_ALGO_SHA224,
|
||||
'sha256'=>OPENSSL_ALGO_SHA256,
|
||||
'sha384'=>OPENSSL_ALGO_SHA384,
|
||||
'sha512'=>OPENSSL_ALGO_SHA512,
|
||||
'rmd160'=>OPENSSL_ALGO_RMD160);
|
||||
$algo = array(
|
||||
OPENSSL_ALGO_MD4,
|
||||
OPENSSL_ALGO_MD5,
|
||||
OPENSSL_ALGO_SHA1,
|
||||
OPENSSL_ALGO_SHA224,
|
||||
OPENSSL_ALGO_SHA256,
|
||||
OPENSSL_ALGO_SHA384,
|
||||
OPENSSL_ALGO_SHA512,
|
||||
OPENSSL_ALGO_RMD160
|
||||
);
|
||||
|
||||
/* loop over key sizes for test */
|
||||
foreach($ksize as $k => $v) {
|
||||
|
||||
/* generate new private key of specified size to use for tests */
|
||||
$pkey = openssl_pkey_new(array('digest_alg' => 'sha512',
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
'private_key_bits' => $v));
|
||||
openssl_pkey_export($pkey, $pass);
|
||||
foreach ($pkeys as $pkey) {
|
||||
|
||||
/* loop to create and verify results */
|
||||
foreach($algo as $key => $value) {
|
||||
foreach ($algo as $value) {
|
||||
$spkac = openssl_spki_new($pkey, _uuid(), $value);
|
||||
var_dump(openssl_spki_export_challenge(preg_replace('/SPKAC=/', '', $spkac)));
|
||||
var_dump(openssl_spki_export_challenge($spkac.'Make it fail'));
|
||||
var_dump(openssl_spki_export_challenge($spkac . 'Make it fail'));
|
||||
}
|
||||
openssl_free_key($pkey);
|
||||
}
|
||||
|
||||
/* generate a random challenge */
|
||||
function _uuid()
|
||||
{
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
function _uuid() {
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
string\(36\) \"[0-9a-f]{8}\-([0-9a-f]{4}\-){3}[0-9a-f]{12}\"
|
@ -1,77 +0,0 @@
|
||||
--TEST--
|
||||
Testing openssl_spki_new()
|
||||
Tests SPKAC for all available private key sizes & hashing algorithms
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip");
|
||||
if (!@openssl_pkey_new()) die("skip cannot create private key");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* array of private key sizes to test */
|
||||
$ksize = array('1024'=>1024,
|
||||
'2048'=>2048,
|
||||
'4096'=>4096);
|
||||
|
||||
/* array of available hashings to test */
|
||||
$algo = array('md4'=>OPENSSL_ALGO_MD4,
|
||||
'md5'=>OPENSSL_ALGO_MD5,
|
||||
'sha1'=>OPENSSL_ALGO_SHA1,
|
||||
'sha224'=>OPENSSL_ALGO_SHA224,
|
||||
'sha256'=>OPENSSL_ALGO_SHA256,
|
||||
'sha384'=>OPENSSL_ALGO_SHA384,
|
||||
'sha512'=>OPENSSL_ALGO_SHA512,
|
||||
'rmd160'=>OPENSSL_ALGO_RMD160);
|
||||
|
||||
/* loop over key sizes for test */
|
||||
foreach($ksize as $k => $v) {
|
||||
|
||||
/* generate new private key of specified size to use for tests */
|
||||
$pkey = openssl_pkey_new(array('digest_alg' => 'sha512',
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
'private_key_bits' => $v));
|
||||
openssl_pkey_export($pkey, $pass);
|
||||
|
||||
/* loop to create and verify results */
|
||||
foreach($algo as $key => $value) {
|
||||
var_dump(openssl_spki_new($pkey, _uuid(), $value));
|
||||
}
|
||||
openssl_free_key($pkey);
|
||||
}
|
||||
|
||||
/* generate a random challenge */
|
||||
function _uuid()
|
||||
{
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(474) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(826) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1506) "%s"
|
73
ext/openssl/tests/openssl_spki_new_basic.phpt
Normal file
73
ext/openssl/tests/openssl_spki_new_basic.phpt
Normal file
@ -0,0 +1,73 @@
|
||||
--TEST--
|
||||
openssl_spki_new() test for creating SPKI string
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* array of private key sizes to test */
|
||||
$key_sizes = array(1024, 2048, 4096);
|
||||
$pkeys = array();
|
||||
foreach ($key_sizes as $key_size) {
|
||||
$key_file = "file://" . dirname(__FILE__) . "/private_rsa_" . $key_size . ".key";
|
||||
$pkeys[] = openssl_pkey_get_private($key_file);
|
||||
}
|
||||
|
||||
|
||||
/* array of available hashings to test */
|
||||
$algo = array(
|
||||
OPENSSL_ALGO_MD4,
|
||||
OPENSSL_ALGO_MD5,
|
||||
OPENSSL_ALGO_SHA1,
|
||||
OPENSSL_ALGO_SHA224,
|
||||
OPENSSL_ALGO_SHA256,
|
||||
OPENSSL_ALGO_SHA384,
|
||||
OPENSSL_ALGO_SHA512,
|
||||
OPENSSL_ALGO_RMD160
|
||||
);
|
||||
|
||||
/* loop over key sizes for test */
|
||||
foreach ($pkeys as $pkey) {
|
||||
|
||||
/* loop to create and verify results */
|
||||
foreach ($algo as $value) {
|
||||
var_dump(openssl_spki_new($pkey, _uuid(), $value));
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a random challenge */
|
||||
function _uuid() {
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(478) "%s"
|
||||
string(474) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(830) "%s"
|
||||
string(826) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1510) "%s"
|
||||
string(1506) "%s"
|
@ -1,91 +0,0 @@
|
||||
--TEST--
|
||||
Testing openssl_spki_verify()
|
||||
Creates SPKAC for all available key sizes & signature algorithms and tests for valid signature
|
||||
--INI--
|
||||
error_reporting=0
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip");
|
||||
if (!@openssl_pkey_new()) die("skip cannot create private key");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* array of private key sizes to test */
|
||||
$ksize = array('1024'=>1024,
|
||||
'2048'=>2048,
|
||||
'4096'=>4096);
|
||||
|
||||
/* array of available hashings to test */
|
||||
$algo = array('sha1'=>OPENSSL_ALGO_SHA1,
|
||||
'sha224'=>OPENSSL_ALGO_SHA224,
|
||||
'sha256'=>OPENSSL_ALGO_SHA256,
|
||||
'sha384'=>OPENSSL_ALGO_SHA384,
|
||||
'sha512'=>OPENSSL_ALGO_SHA512,
|
||||
'rmd160'=>OPENSSL_ALGO_RMD160);
|
||||
|
||||
/* loop over key sizes for test */
|
||||
foreach($ksize as $k => $v) {
|
||||
|
||||
/* generate new private key of specified size to use for tests */
|
||||
$pkey = openssl_pkey_new(array('digest_alg' => 'sha512',
|
||||
'private_key_type' => OPENSSL_KEYTYPE_RSA,
|
||||
'private_key_bits' => $v));
|
||||
openssl_pkey_export($pkey, $pass);
|
||||
|
||||
/* loop to create and verify results */
|
||||
foreach($algo as $key => $value) {
|
||||
$spkac = openssl_spki_new($pkey, _uuid(), $value);
|
||||
var_dump(openssl_spki_verify(preg_replace('/SPKAC=/', '', $spkac)));
|
||||
var_dump(openssl_spki_verify($spkac.'Make it fail'));
|
||||
}
|
||||
openssl_free_key($pkey);
|
||||
}
|
||||
|
||||
/* generate a random challenge */
|
||||
function _uuid()
|
||||
{
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
88
ext/openssl/tests/openssl_spki_verify_basic.phpt
Normal file
88
ext/openssl/tests/openssl_spki_verify_basic.phpt
Normal file
@ -0,0 +1,88 @@
|
||||
--TEST--
|
||||
openssl_spki_verify() tests for valid signature
|
||||
--INI--
|
||||
error_reporting=0
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
/* array of private key sizes to test */
|
||||
$key_sizes = array(1024, 2048, 4096);
|
||||
$pkeys = array();
|
||||
foreach ($key_sizes as $key_size) {
|
||||
$key_file = "file://" . dirname(__FILE__) . "/private_rsa_" . $key_size . ".key";
|
||||
$pkeys[] = openssl_pkey_get_private($key_file);
|
||||
}
|
||||
|
||||
|
||||
/* array of available hashings to test */
|
||||
$algo = array(
|
||||
OPENSSL_ALGO_SHA1,
|
||||
OPENSSL_ALGO_SHA224,
|
||||
OPENSSL_ALGO_SHA256,
|
||||
OPENSSL_ALGO_SHA384,
|
||||
OPENSSL_ALGO_SHA512,
|
||||
OPENSSL_ALGO_RMD160
|
||||
);
|
||||
|
||||
/* loop over key sizes for test */
|
||||
foreach ($pkeys as $pkey) {
|
||||
|
||||
/* loop to create and verify results */
|
||||
foreach ($algo as $value) {
|
||||
$spkac = openssl_spki_new($pkey, _uuid(), $value);
|
||||
var_dump(openssl_spki_verify(preg_replace('/SPKAC=/', '', $spkac)));
|
||||
var_dump(openssl_spki_verify($spkac . 'Make it fail'));
|
||||
}
|
||||
}
|
||||
|
||||
/* generate a random challenge */
|
||||
function _uuid() {
|
||||
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0x0fff) | 0x4000,
|
||||
mt_rand(0, 0x3fff) | 0x8000, mt_rand(0, 0xffff),
|
||||
mt_rand(0, 0xffff), mt_rand(0, 0xffff));
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
@ -5,7 +5,7 @@ openssl_verify() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$data = "Testing openssl_verify()";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$privkey = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
$pubkey = "file://" . dirname(__FILE__) . "/public.key";
|
||||
$wrong = "wrong";
|
||||
|
@ -5,15 +5,15 @@ openssl_x509_check_private_key() tests
|
||||
--FILE--
|
||||
<?php
|
||||
$fp = fopen(dirname(__FILE__) . "/cert.crt","r");
|
||||
$a = fread($fp,8192);
|
||||
$a = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
|
||||
$fp = fopen(dirname(__FILE__) . "/private.key","r");
|
||||
$b = fread($fp,8192);
|
||||
$fp = fopen(dirname(__FILE__) . "/private_rsa_1024.key","r");
|
||||
$b = fread($fp, 8192);
|
||||
fclose($fp);
|
||||
|
||||
$cert = "file://" . dirname(__FILE__) . "/cert.crt";
|
||||
$key = "file://" . dirname(__FILE__) . "/private.key";
|
||||
$key = "file://" . dirname(__FILE__) . "/private_rsa_1024.key";
|
||||
|
||||
var_dump(openssl_x509_check_private_key($cert, $key));
|
||||
var_dump(openssl_x509_check_private_key("", $key));
|
45
ext/openssl/tests/openssl_x509_export_basic.phpt
Normal file
45
ext/openssl/tests/openssl_x509_export_basic.phpt
Normal file
@ -0,0 +1,45 @@
|
||||
--TEST--
|
||||
openssl_x509_export() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$cert_file = dirname(__FILE__) . "/cert.crt";
|
||||
|
||||
$a = file_get_contents($cert_file);
|
||||
$b = "file://" . $cert_file;
|
||||
$c = "invalid cert";
|
||||
$d = openssl_x509_read($a);
|
||||
$e = array();
|
||||
|
||||
var_dump(openssl_x509_export($a, $output)); // read cert as a binary string
|
||||
var_dump(openssl_x509_export($b, $output2)); // read cert from a filename string
|
||||
var_dump(openssl_x509_export($c, $output3)); // read an invalid cert, fails
|
||||
var_dump(openssl_x509_export($d, $output4)); // read cert from a resource
|
||||
var_dump(openssl_x509_export($e, $output5)); // read an array, fails
|
||||
|
||||
if (PHP_EOL !== "\n") {
|
||||
$a = str_replace(PHP_EOL, "\n", $a);
|
||||
}
|
||||
|
||||
var_dump(strcmp($output, $a));
|
||||
var_dump(strcmp($output, $output2));
|
||||
var_dump(strcmp($output, $output3));
|
||||
var_dump(strcmp($output, $output4)); // different
|
||||
var_dump(strcmp($output, $output5)); // different
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
int(0)
|
||||
int(0)
|
||||
int(%d)
|
||||
int(0)
|
||||
int(%d)
|
42
ext/openssl/tests/openssl_x509_export_to_file_basic.phpt
Normal file
42
ext/openssl/tests/openssl_x509_export_to_file_basic.phpt
Normal file
@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
openssl_x509_export_to_file() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$outfilename = dirname(__FILE__) . "/openssl_x509_export_to_file__outfilename.tmp";
|
||||
$cert_file = dirname(__FILE__) . "/cert.crt";
|
||||
|
||||
$a = file_get_contents($cert_file);
|
||||
$b = "file://" . $cert_file;
|
||||
$c = "invalid cert";
|
||||
$d = openssl_x509_read($a);
|
||||
$e = array();
|
||||
|
||||
var_dump(openssl_x509_export_to_file($a, $outfilename)); // read cert as a binary string
|
||||
var_dump(openssl_x509_export_to_file($b, $outfilename)); // read cert from a filename string
|
||||
var_dump(openssl_x509_export_to_file($c, $outfilename)); // read an invalid cert, fails
|
||||
var_dump(openssl_x509_export_to_file($d, $outfilename)); // read cert from a resource
|
||||
var_dump(openssl_x509_export_to_file($e, $outfilename)); // read an array, fails
|
||||
echo "---\n";
|
||||
var_dump($exists = file_exists($outfilename));
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
$outfilename = dirname(__FILE__) . "/openssl_x509_export_to_file__outfilename.tmp";
|
||||
if (file_exists($outfilename)) {
|
||||
unlink($outfilename);
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(true)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export_to_file(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
bool(true)
|
||||
|
||||
Warning: openssl_x509_export_to_file(): cannot get cert from parameter 1 in %s on line %d
|
||||
bool(false)
|
||||
---
|
||||
bool(true)
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Testing openssl_x509_fingerprint()
|
||||
openssl_x509_fingerprint() tests
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!extension_loaded("openssl")) die("skip");
|
16
ext/openssl/tests/openssl_x509_free_basic.phpt
Normal file
16
ext/openssl/tests/openssl_x509_free_basic.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
openssl_x509_free() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump($res = openssl_x509_read("file://" . dirname(__FILE__) . "/cert.crt"));
|
||||
openssl_x509_free($res);
|
||||
var_dump($res);
|
||||
openssl_x509_free(false);
|
||||
?>
|
||||
--EXPECTF--
|
||||
resource(%d) of type (OpenSSL X.509)
|
||||
resource(%d) of type (Unknown)
|
||||
|
||||
Warning: openssl_x509_free() expects parameter 1 to be resource, boolean given in %s on line %d
|
@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
openssl_x509_parse() basic test
|
||||
openssl_x509_parse() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip";
|
||||
if (OPENSSL_VERSION_NUMBER < 0x10000000) die("skip Output requires OpenSSL 1.0");
|
||||
|
37
ext/openssl/tests/openssl_x509_read_basic.phpt
Normal file
37
ext/openssl/tests/openssl_x509_read_basic.phpt
Normal file
@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
openssl_x509_read() tests
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded("openssl")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
$fp = fopen(dirname(__FILE__) . "/cert.crt","r");
|
||||
$a = fread($fp,8192);
|
||||
fclose($fp);
|
||||
|
||||
$b = "file://" . dirname(__FILE__) . "/cert.crt";
|
||||
$c = "invalid cert";
|
||||
$d = openssl_x509_read($a);
|
||||
$e = array();
|
||||
$f = array($b);
|
||||
|
||||
var_dump(openssl_x509_read($a)); // read cert as a string
|
||||
var_dump(openssl_x509_read($b)); // read cert as a filename string
|
||||
var_dump(openssl_x509_read($c)); // read an invalid cert, fails
|
||||
var_dump(openssl_x509_read($d)); // read cert from a resource
|
||||
var_dump(openssl_x509_read($e)); // read an array
|
||||
var_dump(openssl_x509_read($f)); // read an array with the filename
|
||||
?>
|
||||
--EXPECTF--
|
||||
resource(%d) of type (OpenSSL X.509)
|
||||
resource(%d) of type (OpenSSL X.509)
|
||||
|
||||
Warning: openssl_x509_read(): supplied parameter cannot be coerced into an X509 certificate! in %s on line %d
|
||||
bool(false)
|
||||
resource(%d) of type (OpenSSL X.509)
|
||||
|
||||
Warning: openssl_x509_read(): supplied parameter cannot be coerced into an X509 certificate! in %s on line %d
|
||||
bool(false)
|
||||
|
||||
Warning: openssl_x509_read(): supplied parameter cannot be coerced into an X509 certificate! in %s on line %d
|
||||
bool(false)
|
||||
|
27
ext/openssl/tests/private_rsa_2048.key
Normal file
27
ext/openssl/tests/private_rsa_2048.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEArbUmVW1Y+rJzZRC3DYB0kdIgvk7MAday78ybGPPDhVlbAb4C
|
||||
jWbaPs4nyUCTEt9KVG0H7pXHxDbWSsC2974zdvqlP0L2op1/M2SteTcGCBOdwGH2
|
||||
jORVAZL8/WbTOf9IpKAM77oN14scsyOlQBJqhh+xrLg8ksB2dOos54yDqo0Tq7R5
|
||||
tldV+alKZXWlJnqRCfFuxvqtfWI5nGTAedVZhvjQfLQQgujfXHoFWoGbXn2buzfw
|
||||
KGJEeqWPbQOZF/FeOJPlgOBhhDb3BAFNVCtM3k71Rblj54pNd3yvq152xsgFd0o3
|
||||
s15fuSwZgerUjeEuw/wTK9k7vyp+MrIQHQmPdQIDAQABAoIBABPDKDlP12+uHbLB
|
||||
1BGVK63rWg5MqKkM5A6kGIEeOoBRSilIlMHBkdLTYXNkBVeAT9SLEvvxzmhkVLzs
|
||||
b+R/nxtKKMKpu6WEhZQzQAkqWWVR1gCtJH+i+ojTUDUEHcPbZ0hTbSVY5XpAOWOo
|
||||
CoTfk37u3CfqTfnkK5XhjnpJYjFk60fLeTKKG90xb4WmPGCOxBZGeI9yk+gEgMVx
|
||||
4qYBQEgcaJEBXebvM0q8BCDh/rlYxwQ/q0RJ6W1D84SOeyYv/9LesFZSbnUN16tA
|
||||
/YezkhYVkVIrQFzh1al7NKvWEUZ3Yx3AEuggKtijlZyO9zOAOigSiFQjtqOl7S6e
|
||||
jbVfLYECgYEA51E5TNvN6IW6p58wOXTmINnsW3sDYS1CyPh3TkSvWU2OqMXJxQSA
|
||||
bASpXtqicAY32wkBOiazyY/+L7x1ReG/8z3tTm53AsYwkLKrgUfjdrOFhXWk8QI3
|
||||
0WS/1hS7qZ4Ycxi5B2X+rPPLnc2+mUvaEX6/B2Fjbqp4nIt+ZAE8SvcCgYEAwD47
|
||||
anMk8z68wdgzxY4J10sgCKfgHCe7J8ikpzloznX1HnbZTWf74FLlA/8ctfFJCVAy
|
||||
4dG1s0D+JSpxxMSkk4hvi10Ha6t5U+BreD9VPAQRspGSKhn8JfwvLfKPH65uazBP
|
||||
yvBtVIdagBf/msLfF33vkrQSjAEJM1njl6XMEfMCgYB1BddqNa0G3Figol0gRC6E
|
||||
Iht78FC2YdJun5yj4QWgtSbd5Sn9XRinDPiufwc8izjIu9Z+F8ROzWT3u2zMzLdy
|
||||
FDswuZvFsIQzP+CaB8dgbtO2v9yQ/OFGMqUGZfjGh6+w0qoQvx3HW5MAI20wWnpY
|
||||
7Xkw/6jw/JcGA2AOsb1R4wKBgQCFfnF54Q1GkEk4/m4tAA4bX4KWICUCyCAxZyXX
|
||||
LYl23PhiuDr7gnqockevt8ZzHWMPQY6juyFGoZoZqtinv7lc7YAvsWEGxmMQ+KUI
|
||||
Mkp4y4aSjn2GGNc8dVs5t9blNBZe/oRaMwxohzkz+/Y1vJ54TK5BHCRI7is6anAd
|
||||
jTchOwKBgQDP9yOdQTfUwJRUMERWmzXWU2oDXeEMdpbGPLGJ4/e/hu1CW7bdQRoc
|
||||
jBSEpn3hOodmdwdmoXtbJReMCE8qS6yVHNn4orpJf+uOBr5fVnHwttFfN8HID9js
|
||||
Lml8jAAQItMFw1CEPR75NVdFb7ksNKlxE9376tG63JhrTttRGwO3CA==
|
||||
-----END RSA PRIVATE KEY-----
|
51
ext/openssl/tests/private_rsa_4096.key
Normal file
51
ext/openssl/tests/private_rsa_4096.key
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIJKAIBAAKCAgEAtlmPieG4yL/HQ1j98U+VqlAzO55+aSHKXOV9q5+uTevtzXVV
|
||||
s+rOPUAlPkUi7kcp3Yrum+Y0rNCnTNpSmpFB2f/Y1rHb6Rxn8SXzWSq8BM0BhbCm
|
||||
yE+PY3DyIBizX6isb13vJyvU7f8Ayv4xAQ/ve8ytFAnBXUdIhtQNygraxvr8aoZw
|
||||
81cBRQ8NhBkk/qDZWVkOiePC9voZ05sENhL4aUZw3Xew2JtZyw+lRxheczkYYc71
|
||||
OQuOKoU06j3ZpLhdhtdjpOVC6csIk9qyq8ki8t9m66a2BdiPaz1cWGZGqQg4SDrJ
|
||||
0XKG6/wdSWgdUKMp0wB2Kwph2SWwLm7BQEpdtMtXnNGB2dT+lffjtqRvyT4HKO03
|
||||
R9b7ZxUVA34Tzi+kX04g3e4qI4eD0bsHYwioUlkKf/q7E1+WjwaQ2LLbOUnWeKqb
|
||||
wGBsZYMWeWGTc/FO4oyDJBG9gnsqmSHasAsxsW6ojsGnz9IXywpwInlz+R4pB+ua
|
||||
dXHiUZEuT8lCdBUWKAtCIb/F9cNEJg/Vq0iVoWFaOYd5D4PHXV5aXjEx18ez7GvN
|
||||
98XPYNXQmVBmsIlOHQpytz0RdrlstksxBqWhaBUT3ZJU6czchNgYeFsEuYKkUNK+
|
||||
fwQLhA9aeT6RBdet2efhyaf4y3vQFb5kxx4JcljXjIYVR3yB9iZnD0WGQxkCAwEA
|
||||
AQKCAgBHrhkQmFxs/YY04SyhySkKFBCvpPQIG7JSphuqdVCtbMrD8xXHbcu4pBh/
|
||||
y+mZRPweDFkTi4C1VigNu9ywydza9wmkC7JohjQNxV9Nc9EJChVJGlHVeADjlCh5
|
||||
mXwZZFK0THaQLVi8XXtQUG+u/TaksaZvtA4Avt6xsXXiMDYj9dF3hnWsEk17ehlU
|
||||
DhZOyafmyW0/ovqm31V7qvoSz446w+fmBwDLhPXdLr9HnTqzjIQbHqGi1PoDmO1e
|
||||
DwYZDCgns0+GKGEPSjKK/HMzuBM26b6pb5Up4yEthKdiUIICPCrzqbhfzudeqHJS
|
||||
wsyTQDBWs13AOYqRM5F4Dy2EOjdvCgt2zElO0c3r/pOTplk3/v7VrsqiNN33xGfc
|
||||
4zGw3d0xLjQRhA9vhG5Kdtqqs1GqZDf3mNmPxv8gHJDdB6Twkk9iNlUnV5neew6R
|
||||
0KKklZvMApE+KMVrRKmez0+ab/ktpoAe9Xox9ChBfLaZQgJlDwNDktjRu8RT1da8
|
||||
L6SMy5+mP+aSKxWxgNGoM0BQiv3DBriyTuyhcu+2SIr4c0LrWqedZRI1eRREZjhG
|
||||
VLBpftvQH7AMTZuIHXYjtF8XcZneaa2/fI7SNH6RpPc7WJmLCF3ufjv6HVp3qA8B
|
||||
ahRCgsr4sBZDJqwMkbNJQfuF/zNOAGmO5VRBodb/P9UQeEVeAQKCAQEA6TkahKZq
|
||||
374hUnElMH3mmYPVxOKfqx4EMrS+MP8cjXXmiw7bWjQlufcmbMhxHaXkGiU9+/TB
|
||||
VdFPtLZvo7Aa+m2sHCySJ1pG2T4kkmV9cNVExKPllraH3/QvDK3o34aA2DxgOXAT
|
||||
33wxlxvmmaMmrjjP6BZduvS/W/vwL6+aA1erZbsBuA1CoeyiyE95zdcD43+TlZWi
|
||||
fwCqCZ27wrKHCPFcEN/ecpjKQTQQdogDNWdJJzaTH7y3iWNOsLdTNeLRYrvu94dS
|
||||
J9n7cCoLCEFzdylaXx/jGCNrnaNtqDj46JHW6XSQ6e3D0UpV2hx5V2+0q1gbEhWe
|
||||
wtBrhGsHj/jj+QKCAQEAyCiOlcE6a1tjIdMihAO1hqdUiFcIKzoiDQKNBEaY9ELz
|
||||
oWkuZj2fUnhjeAKhkQ4ZheH6+fk2Tt0+kU1Jl+Iym/ciE/m/N8RUyqq2FOnmwktz
|
||||
yGqD9fQeLix2b2txp+0dyi1niQ+S8ZKAJBbxKTb3CBefowrkz5JK7+jWqaUDNQ5h
|
||||
8KoGCcAB8kSkXGgqVOapXyGb31YdyM3X1mJGv95jO4A+OmFI2faPAOtZrg9EicSI
|
||||
7U84bfFMhfhrpxZuU7Bbyz6Kg9hleAv0q/3tBFSJvMTOiuM7OFtlUAByL+pWwZ9Y
|
||||
haQ4ojojsPaQ6pMmf0JNXwnp8Rhz2+QNDyFzRm/gIQKCAQEA3dmA/S/kuAL/ZZHV
|
||||
g4QvyFYdEdVVdwvtiGJgDPGPsoy1ig/O3sZ+IKEWPyKIX2B/U9ObW8Hd6wlZXZix
|
||||
J68Maq3Kq15GhQKeJGa1mUDLi3qDmN4jNjNZmtKHsvL3czFZ/Nep3NldPhjAf3J9
|
||||
8CW/VLkcJDSqYn4QTaqhNms/APDzTKkQIIkUmj0kN5FKV2CyBUVFGWSml1MFbHJL
|
||||
ug/i3cHiBvc9fhsTQeUJyAbnrnQapR+H4ge9OwZpQzaQA9FHxjjpPzLNFrWHNZH4
|
||||
vpisAm0m1xfZCQwggWqFlCDlvS2FlrtYYf3XaI3ijsDJOEA9R0RfM9u3Eq/5ppO9
|
||||
NNnX2QKCAQAJ63ilk14B1BWlp4EeadClS8W0vBt7iPYHDwlOHPGXqXnJlhzmlEdB
|
||||
HxZO7FJ1je1V5U069k7quaxQJzRugpdfg2/87XO8n85T/QHpJ254UqT6Wc0Qc3jL
|
||||
cQitnPWVDPtc+cMX193AezI+l6R8Fm1HyWPwAKo2X1m3aiK5ZaQzDPNtqf+CnDF8
|
||||
gEplCgSPEJ90R4YiG3J+cTUxOs2m1K62VDTBT/D8XGvZ79ASAE+1RDhFCpgRWtQg
|
||||
D5/GOCZfn23tNLxIrIDa4jzOCVelz0rEQDy8RWa59E2hGWSPW13RWsRYWzszTw5V
|
||||
xuKHvaM6y15qR2OAv2V+kF7VUSMVapYBAoIBAEyZDn9H+IMQBkRyZgxPLsE5cgd3
|
||||
DeR2Txn2RxQBpop9+lgniuq/NVHiUIRscynsJ01/bFifmFNkgD2cRORy7SU+wsNr
|
||||
zsWlLPO1e/axdfMsT0OIBOQ84jZ6FDGi5JnqnC8zVVPU7g2iNoDEtA7ltlXknUUX
|
||||
uigFoR1CXoNz8KdW+18MtYDjBLR1crfGa+zqPOpxfjoXBhehtCKG9ZxtrBSWq6mz
|
||||
lR9N5Tv9USiJW1r6+85aLsC5E9ARjAxMLhTKvD+NXbQDwZJgfM/vs1eZ6eIYMYE9
|
||||
lB7kMFfHKqsagNXdyhRFzfEfx+FkKTHaqC6V5rOp6q0t8AO41ZvZO/tKdi8=
|
||||
-----END RSA PRIVATE KEY-----
|
@ -1,6 +1,182 @@
|
||||
ChangeLog for PCRE
|
||||
------------------
|
||||
|
||||
Note that the PCRE 8.xx series (PCRE1) is now in a bugfix-only state. All
|
||||
development is happening in the PCRE2 10.xx series.
|
||||
|
||||
Version 8.38 23-November-2015
|
||||
-----------------------------
|
||||
|
||||
1. If a group that contained a recursive back reference also contained a
|
||||
forward reference subroutine call followed by a non-forward-reference
|
||||
subroutine call, for example /.((?2)(?R)\1)()/, pcre2_compile() failed to
|
||||
compile correct code, leading to undefined behaviour or an internally
|
||||
detected error. This bug was discovered by the LLVM fuzzer.
|
||||
|
||||
2. Quantification of certain items (e.g. atomic back references) could cause
|
||||
incorrect code to be compiled when recursive forward references were
|
||||
involved. For example, in this pattern: /(?1)()((((((\1++))\x85)+)|))/.
|
||||
This bug was discovered by the LLVM fuzzer.
|
||||
|
||||
3. A repeated conditional group whose condition was a reference by name caused
|
||||
a buffer overflow if there was more than one group with the given name.
|
||||
This bug was discovered by the LLVM fuzzer.
|
||||
|
||||
4. A recursive back reference by name within a group that had the same name as
|
||||
another group caused a buffer overflow. For example:
|
||||
/(?J)(?'d'(?'d'\g{d}))/. This bug was discovered by the LLVM fuzzer.
|
||||
|
||||
5. A forward reference by name to a group whose number is the same as the
|
||||
current group, for example in this pattern: /(?|(\k'Pm')|(?'Pm'))/, caused
|
||||
a buffer overflow at compile time. This bug was discovered by the LLVM
|
||||
fuzzer.
|
||||
|
||||
6. A lookbehind assertion within a set of mutually recursive subpatterns could
|
||||
provoke a buffer overflow. This bug was discovered by the LLVM fuzzer.
|
||||
|
||||
7. Another buffer overflow bug involved duplicate named groups with a
|
||||
reference between their definition, with a group that reset capture
|
||||
numbers, for example: /(?J:(?|(?'R')(\k'R')|((?'R'))))/. This has been
|
||||
fixed by always allowing for more memory, even if not needed. (A proper fix
|
||||
is implemented in PCRE2, but it involves more refactoring.)
|
||||
|
||||
8. There was no check for integer overflow in subroutine calls such as (?123).
|
||||
|
||||
9. The table entry for \l in EBCDIC environments was incorrect, leading to its
|
||||
being treated as a literal 'l' instead of causing an error.
|
||||
|
||||
10. There was a buffer overflow if pcre_exec() was called with an ovector of
|
||||
size 1. This bug was found by american fuzzy lop.
|
||||
|
||||
11. If a non-capturing group containing a conditional group that could match
|
||||
an empty string was repeated, it was not identified as matching an empty
|
||||
string itself. For example: /^(?:(?(1)x|)+)+$()/.
|
||||
|
||||
12. In an EBCDIC environment, pcretest was mishandling the escape sequences
|
||||
\a and \e in test subject lines.
|
||||
|
||||
13. In an EBCDIC environment, \a in a pattern was converted to the ASCII
|
||||
instead of the EBCDIC value.
|
||||
|
||||
14. The handling of \c in an EBCDIC environment has been revised so that it is
|
||||
now compatible with the specification in Perl's perlebcdic page.
|
||||
|
||||
15. The EBCDIC character 0x41 is a non-breaking space, equivalent to 0xa0 in
|
||||
ASCII/Unicode. This has now been added to the list of characters that are
|
||||
recognized as white space in EBCDIC.
|
||||
|
||||
16. When PCRE was compiled without UCP support, the use of \p and \P gave an
|
||||
error (correctly) when used outside a class, but did not give an error
|
||||
within a class.
|
||||
|
||||
17. \h within a class was incorrectly compiled in EBCDIC environments.
|
||||
|
||||
18. A pattern with an unmatched closing parenthesis that contained a backward
|
||||
assertion which itself contained a forward reference caused buffer
|
||||
overflow. And example pattern is: /(?=di(?<=(?1))|(?=(.))))/.
|
||||
|
||||
19. JIT should return with error when the compiled pattern requires more stack
|
||||
space than the maximum.
|
||||
|
||||
20. A possessively repeated conditional group that could match an empty string,
|
||||
for example, /(?(R))*+/, was incorrectly compiled.
|
||||
|
||||
21. Fix infinite recursion in the JIT compiler when certain patterns such as
|
||||
/(?:|a|){100}x/ are analysed.
|
||||
|
||||
22. Some patterns with character classes involving [: and \\ were incorrectly
|
||||
compiled and could cause reading from uninitialized memory or an incorrect
|
||||
error diagnosis.
|
||||
|
||||
23. Pathological patterns containing many nested occurrences of [: caused
|
||||
pcre_compile() to run for a very long time.
|
||||
|
||||
24. A conditional group with only one branch has an implicit empty alternative
|
||||
branch and must therefore be treated as potentially matching an empty
|
||||
string.
|
||||
|
||||
25. If (?R was followed by - or + incorrect behaviour happened instead of a
|
||||
diagnostic.
|
||||
|
||||
26. Arrange to give up on finding the minimum matching length for overly
|
||||
complex patterns.
|
||||
|
||||
27. Similar to (4) above: in a pattern with duplicated named groups and an
|
||||
occurrence of (?| it is possible for an apparently non-recursive back
|
||||
reference to become recursive if a later named group with the relevant
|
||||
number is encountered. This could lead to a buffer overflow. Wen Guanxing
|
||||
from Venustech ADLAB discovered this bug.
|
||||
|
||||
28. If pcregrep was given the -q option with -c or -l, or when handling a
|
||||
binary file, it incorrectly wrote output to stdout.
|
||||
|
||||
29. The JIT compiler did not restore the control verb head in case of *THEN
|
||||
control verbs. This issue was found by Karl Skomski with a custom LLVM
|
||||
fuzzer.
|
||||
|
||||
30. Error messages for syntax errors following \g and \k were giving inaccurate
|
||||
offsets in the pattern.
|
||||
|
||||
31. Added a check for integer overflow in conditions (?(<digits>) and
|
||||
(?(R<digits>). This omission was discovered by Karl Skomski with the LLVM
|
||||
fuzzer.
|
||||
|
||||
32. Handling recursive references such as (?2) when the reference is to a group
|
||||
later in the pattern uses code that is very hacked about and error-prone.
|
||||
It has been re-written for PCRE2. Here in PCRE1, a check has been added to
|
||||
give an internal error if it is obvious that compiling has gone wrong.
|
||||
|
||||
33. The JIT compiler should not check repeats after a {0,1} repeat byte code.
|
||||
This issue was found by Karl Skomski with a custom LLVM fuzzer.
|
||||
|
||||
34. The JIT compiler should restore the control chain for empty possessive
|
||||
repeats. This issue was found by Karl Skomski with a custom LLVM fuzzer.
|
||||
|
||||
35. Match limit check added to JIT recursion. This issue was found by Karl
|
||||
Skomski with a custom LLVM fuzzer.
|
||||
|
||||
36. Yet another case similar to 27 above has been circumvented by an
|
||||
unconditional allocation of extra memory. This issue is fixed "properly" in
|
||||
PCRE2 by refactoring the way references are handled. Wen Guanxing
|
||||
from Venustech ADLAB discovered this bug.
|
||||
|
||||
37. Fix two assertion fails in JIT. These issues were found by Karl Skomski
|
||||
with a custom LLVM fuzzer.
|
||||
|
||||
38. Fixed a corner case of range optimization in JIT.
|
||||
|
||||
39. An incorrect error "overran compiling workspace" was given if there were
|
||||
exactly enough group forward references such that the last one extended
|
||||
into the workspace safety margin. The next one would have expanded the
|
||||
workspace. The test for overflow was not including the safety margin.
|
||||
|
||||
40. A match limit issue is fixed in JIT which was found by Karl Skomski
|
||||
with a custom LLVM fuzzer.
|
||||
|
||||
41. Remove the use of /dev/null in testdata/testinput2, because it doesn't
|
||||
work under Windows. (Why has it taken so long for anyone to notice?)
|
||||
|
||||
42. In a character class such as [\W\p{Any}] where both a negative-type escape
|
||||
("not a word character") and a property escape were present, the property
|
||||
escape was being ignored.
|
||||
|
||||
43. Fix crash caused by very long (*MARK) or (*THEN) names.
|
||||
|
||||
44. A sequence such as [[:punct:]b] that is, a POSIX character class followed
|
||||
by a single ASCII character in a class item, was incorrectly compiled in
|
||||
UCP mode. The POSIX class got lost, but only if the single character
|
||||
followed it.
|
||||
|
||||
45. [:punct:] in UCP mode was matching some characters in the range 128-255
|
||||
that should not have been matched.
|
||||
|
||||
46. If [:^ascii:] or [:^xdigit:] or [:^cntrl:] are present in a non-negated
|
||||
class, all characters with code points greater than 255 are in the class.
|
||||
When a Unicode property was also in the class (if PCRE_UCP is set, escapes
|
||||
such as \w are turned into Unicode properties), wide characters were not
|
||||
correctly handled, and could fail to match.
|
||||
|
||||
|
||||
Version 8.37 28-April-2015
|
||||
--------------------------
|
||||
|
||||
|
@ -1,6 +1,14 @@
|
||||
News about PCRE releases
|
||||
------------------------
|
||||
|
||||
Release 8.38 23-November-2015
|
||||
-----------------------------
|
||||
|
||||
This is bug-fix release. Note that this library (now called PCRE1) is now being
|
||||
maintained for bug fixes only. New projects are advised to use the new PCRE2
|
||||
libraries.
|
||||
|
||||
|
||||
Release 8.37 28-April-2015
|
||||
--------------------------
|
||||
|
||||
|
@ -24,41 +24,37 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Exclude these below definitions when building within PHP */
|
||||
#ifndef ZEND_API
|
||||
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
|
||||
/* PCRE is written in Standard C, but there are a few non-standard things it
|
||||
can cope with, allowing it to run on SunOS4 and other "close to standard"
|
||||
systems.
|
||||
|
||||
In environments that support the GNU autotools, config.h.in is converted into
|
||||
config.h by the "configure" script. In environments that use CMake,
|
||||
config-cmake.in is converted into config.h. If you are going to build PCRE "by
|
||||
hand" without using "configure" or CMake, you should copy the distributed
|
||||
config.h.generic to config.h, and edit the macro definitions to be the way you
|
||||
need them. You must then add -DHAVE_CONFIG_H to all of your compile commands,
|
||||
so that config.h is included at the start of every source.
|
||||
In environments that support the facilities, config.h.in is converted by
|
||||
"configure", or config-cmake.h.in is converted by CMake, into config.h. If you
|
||||
are going to build PCRE "by hand" without using "configure" or CMake, you
|
||||
should copy the distributed config.h.generic to config.h, and then edit the
|
||||
macro definitions to be the way you need them. You must then add
|
||||
-DHAVE_CONFIG_H to all of your compile commands, so that config.h is included
|
||||
at the start of every source.
|
||||
|
||||
Alternatively, you can avoid editing by using -D on the compiler command line
|
||||
to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,
|
||||
but if you do, default values will be taken from config.h for non-boolean
|
||||
macros that are not defined on the command line.
|
||||
to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H.
|
||||
|
||||
Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE8 should either be defined
|
||||
(conventionally to 1) for TRUE, and not defined at all for FALSE. All such
|
||||
macros are listed as a commented #undef in config.h.generic. Macros such as
|
||||
MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are
|
||||
surrounded by #ifndef/#endif lines so that the value can be overridden by -D.
|
||||
|
||||
PCRE uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if
|
||||
HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make
|
||||
sure both macros are undefined; an emulation function will then be used. */
|
||||
PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if
|
||||
HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set
|
||||
them both to 0; an emulation function will be used. */
|
||||
|
||||
/* By default, the \R escape sequence matches any Unicode line ending
|
||||
character or sequence of characters. If BSR_ANYCRLF is defined (to any
|
||||
value), this is changed so that backslash-R matches only CR, LF, or CRLF.
|
||||
The build-time default can be overridden by the user of PCRE at runtime. */
|
||||
/* #undef BSR_ANYCRLF */
|
||||
#undef BSR_ANYCRLF
|
||||
|
||||
/* If you are compiling for a system that uses EBCDIC instead of ASCII
|
||||
character codes, define this macro to any value. You must also edit the
|
||||
@ -68,80 +64,113 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
strings are in EBCDIC. If you do not define this macro, PCRE will assume
|
||||
input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build
|
||||
a version of PCRE that supports both EBCDIC and UTF-8/16/32. */
|
||||
/* #undef EBCDIC */
|
||||
#undef EBCDIC
|
||||
|
||||
/* In an EBCDIC environment, define this macro to any value to arrange for the
|
||||
NL character to be 0x25 instead of the default 0x15. NL plays the role that
|
||||
LF does in an ASCII/Unicode environment. The value must also be set in the
|
||||
NEWLINE macro below. On systems that can use "configure" or CMake to set
|
||||
EBCDIC_NL25, the adjustment of NEWLINE is automatic. */
|
||||
/* #undef EBCDIC_NL25 */
|
||||
#undef EBCDIC_NL25
|
||||
|
||||
/* Define to 1 if you have the `bcopy' function. */
|
||||
/* #undef HAVE_BCOPY */
|
||||
#ifndef HAVE_BCOPY
|
||||
#define HAVE_BCOPY 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <bits/type_traits.h> header file. */
|
||||
/* #undef HAVE_BITS_TYPE_TRAITS_H */
|
||||
|
||||
/* Define to 1 if you have the <bzlib.h> header file. */
|
||||
/* #undef HAVE_BZLIB_H */
|
||||
#ifndef HAVE_BZLIB_H
|
||||
#define HAVE_BZLIB_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file. */
|
||||
/* #undef HAVE_DIRENT_H */
|
||||
#ifndef HAVE_DIRENT_H
|
||||
#define HAVE_DIRENT_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
#ifndef HAVE_DLFCN_H
|
||||
#define HAVE_DLFCN_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <editline/readline.h> header file. */
|
||||
/* #undef HAVE_EDITLINE_READLINE_H */
|
||||
/*#undef HAVE_EDITLINE_READLINE_H*/
|
||||
|
||||
/* Define to 1 if you have the <edit/readline/readline.h> header file. */
|
||||
/* #undef HAVE_EDIT_READLINE_READLINE_H */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
/* #undef HAVE_INTTYPES_H */
|
||||
#ifndef HAVE_INTTYPES_H
|
||||
#define HAVE_INTTYPES_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
/* #undef HAVE_LIMITS_H */
|
||||
#ifndef HAVE_LIMITS_H
|
||||
#define HAVE_LIMITS_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
/* #undef HAVE_LONG_LONG */
|
||||
#ifndef HAVE_LONG_LONG
|
||||
#define HAVE_LONG_LONG 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
/* #undef HAVE_MEMMOVE */
|
||||
#ifndef HAVE_MEMMOVE
|
||||
#define HAVE_MEMMOVE 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
/* #undef HAVE_MEMORY_H */
|
||||
#ifndef HAVE_MEMORY_H
|
||||
#define HAVE_MEMORY_H 1
|
||||
#endif
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
/* #undef HAVE_PTHREAD */
|
||||
#undef HAVE_PTHREAD
|
||||
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
/* #undef HAVE_PTHREAD_PRIO_INHERIT */
|
||||
|
||||
#undef HAVE_PTHREAD_PRIO_INHERIT
|
||||
/* Define to 1 if you have the <readline/history.h> header file. */
|
||||
/* #undef HAVE_READLINE_HISTORY_H */
|
||||
#ifndef HAVE_READLINE_HISTORY_H
|
||||
#define HAVE_READLINE_HISTORY_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <readline/readline.h> header file. */
|
||||
/* #undef HAVE_READLINE_READLINE_H */
|
||||
#ifndef HAVE_READLINE_READLINE_H
|
||||
#define HAVE_READLINE_READLINE_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
/* #undef HAVE_STDINT_H */
|
||||
#ifndef HAVE_STDINT_H
|
||||
#define HAVE_STDINT_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
/* #undef HAVE_STDLIB_H */
|
||||
#ifndef HAVE_STDLIB_H
|
||||
#define HAVE_STDLIB_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
/* #undef HAVE_STRERROR */
|
||||
#ifndef HAVE_STRERROR
|
||||
#define HAVE_STRERROR 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <string> header file. */
|
||||
/* #undef HAVE_STRING */
|
||||
#ifndef HAVE_STRING
|
||||
#define HAVE_STRING 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
#ifndef HAVE_STRINGS_H
|
||||
#define HAVE_STRINGS_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
/* #undef HAVE_STRING_H */
|
||||
#ifndef HAVE_STRING_H
|
||||
#define HAVE_STRING_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have `strtoimax'. */
|
||||
/* #undef HAVE_STRTOIMAX */
|
||||
@ -150,46 +179,62 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
/* #undef HAVE_STRTOLL */
|
||||
|
||||
/* Define to 1 if you have `strtoq'. */
|
||||
/* #undef HAVE_STRTOQ */
|
||||
#ifndef HAVE_STRTOQ
|
||||
#define HAVE_STRTOQ 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
/* #undef HAVE_SYS_STAT_H */
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
/* #undef HAVE_SYS_TYPES_H */
|
||||
#ifndef HAVE_SYS_TYPES_H
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the <type_traits.h> header file. */
|
||||
/* #undef HAVE_TYPE_TRAITS_H */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if the system has the type `unsigned long long'. */
|
||||
/* #undef HAVE_UNSIGNED_LONG_LONG */
|
||||
#ifndef HAVE_UNSIGNED_LONG_LONG
|
||||
#define HAVE_UNSIGNED_LONG_LONG 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if the compiler supports simple visibility declarations. */
|
||||
/* Define to 1 or 0, depending whether the compiler supports simple visibility
|
||||
declarations. */
|
||||
/* #undef HAVE_VISIBILITY */
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
/* #undef HAVE_WINDOWS_H */
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
/* #undef HAVE_ZLIB_H */
|
||||
#ifndef HAVE_ZLIB_H
|
||||
#define HAVE_ZLIB_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have `_strtoi64'. */
|
||||
/* #undef HAVE__STRTOI64 */
|
||||
|
||||
/* Exclude these above definitions when building within PHP */
|
||||
#endif
|
||||
|
||||
/* The value of LINK_SIZE determines the number of bytes used to store links
|
||||
as offsets within the compiled regex. The default is 2, which allows for
|
||||
compiled patterns up to 64K long. This covers the vast majority of cases.
|
||||
However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows
|
||||
for longer patterns in extreme cases. */
|
||||
for longer patterns in extreme cases. On systems that support it,
|
||||
"configure" can be used to override this default. */
|
||||
#ifndef LINK_SIZE
|
||||
#define LINK_SIZE 2
|
||||
#endif
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
/* This is ignored unless you are using libtool. */
|
||||
#ifndef LT_OBJDIR
|
||||
#define LT_OBJDIR ".libs/"
|
||||
@ -200,7 +245,8 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
pcre_exec(). There is a runtime interface for setting a different limit.
|
||||
The limit exists in order to catch runaway regular expressions that take
|
||||
for ever to determine that they do not match. The default is set very large
|
||||
so that it does not accidentally catch legitimate cases. */
|
||||
so that it does not accidentally catch legitimate cases. On systems that
|
||||
support it, "configure" can be used to override this default default. */
|
||||
#ifndef MATCH_LIMIT
|
||||
#define MATCH_LIMIT 10000000
|
||||
#endif
|
||||
@ -212,7 +258,8 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of
|
||||
match(). To have any useful effect, it must be less than the value of
|
||||
MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is
|
||||
a runtime method for setting a different limit. */
|
||||
a runtime method for setting a different limit. On systems that support it,
|
||||
"configure" can be used to override the default. */
|
||||
#ifndef MATCH_LIMIT_RECURSION
|
||||
#define MATCH_LIMIT_RECURSION MATCH_LIMIT
|
||||
#endif
|
||||
@ -243,6 +290,9 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
#define NEWLINE 10
|
||||
#endif
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* PCRE uses recursive function calls to handle backtracking while matching.
|
||||
This can sometimes be a problem on systems that have stacks of limited
|
||||
size. Define NO_RECURSE to any value to get a version that doesn't use
|
||||
@ -252,6 +302,8 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
*/
|
||||
/* #undef NO_RECURSE */
|
||||
|
||||
#define PARENS_NEST_LIMIT 250
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "pcre"
|
||||
|
||||
@ -262,7 +314,7 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
#define PACKAGE_NAME "PCRE"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "PCRE 8.37"
|
||||
#define PACKAGE_STRING "PCRE 8.38"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "pcre"
|
||||
@ -271,7 +323,13 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "8.37"
|
||||
#define PACKAGE_VERSION "8.38"
|
||||
|
||||
/* to make a symbol visible */
|
||||
/* #undef PCRECPP_EXP_DECL */
|
||||
|
||||
/* to make a symbol visible */
|
||||
/* #undef PCRECPP_EXP_DEFN */
|
||||
|
||||
/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
|
||||
parentheses (of any kind) in a pattern. This limits the amount of system
|
||||
@ -285,9 +343,20 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
minimum value. The actual amount of memory used by pcregrep is three times
|
||||
this number, because it allows for the buffering of "before" and "after"
|
||||
lines. */
|
||||
#ifndef PCREGREP_BUFSIZE
|
||||
#define PCREGREP_BUFSIZE 20480
|
||||
#endif
|
||||
/* #undef PCREGREP_BUFSIZE */
|
||||
|
||||
/* to make a symbol visible */
|
||||
/* #undef PCREPOSIX_EXP_DECL */
|
||||
|
||||
/* to make a symbol visible */
|
||||
/* #undef PCREPOSIX_EXP_DEFN */
|
||||
|
||||
/* to make a symbol visible */
|
||||
/* #undef PCRE_EXP_DATA_DEFN */
|
||||
|
||||
/* to make a symbol visible */
|
||||
/* #undef PCRE_EXP_DECL */
|
||||
|
||||
|
||||
/* If you are compiling for a system other than a Unix-like system or
|
||||
Win32, and it needs some magic to be inserted before the definition
|
||||
@ -319,7 +388,13 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
/* #undef PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
/* #undef STDC_HEADERS */
|
||||
#ifndef STDC_HEADERS
|
||||
#define STDC_HEADERS 1
|
||||
#endif
|
||||
|
||||
/* Define to allow pcretest and pcregrep to be linked with gcov, so that they
|
||||
are able to generate code coverage reports. */
|
||||
#undef SUPPORT_GCOV
|
||||
|
||||
/* Define to any value to enable support for Just-In-Time compiling. */
|
||||
#define SUPPORT_JIT
|
||||
@ -329,7 +404,7 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
/* #undef SUPPORT_LIBBZ2 */
|
||||
|
||||
/* Define to any value to allow pcretest to be linked with libedit. */
|
||||
/* #undef SUPPORT_LIBEDIT */
|
||||
#undef SUPPORT_LIBEDIT
|
||||
|
||||
/* Define to any value to allow pcretest to be linked with libreadline. */
|
||||
/* #undef SUPPORT_LIBREADLINE */
|
||||
@ -348,23 +423,23 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
/* #undef SUPPORT_PCRE8 */
|
||||
|
||||
/* Define to any value to enable JIT support in pcregrep. */
|
||||
#define SUPPORT_PCREGREP_JIT
|
||||
/* #undef SUPPORT_PCREGREP_JIT */
|
||||
|
||||
/* Define to any value to enable support for Unicode properties. */
|
||||
/* Define to enable support for Unicode properties */
|
||||
/* #undef SUPPORT_UCP */
|
||||
|
||||
/* Define to any value to enable support for the UTF-8/16/32 Unicode encoding.
|
||||
This will work even in an EBCDIC environment, but it is incompatible with
|
||||
the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or*
|
||||
ASCII/UTF-8/16/32, but not both at once. */
|
||||
/* #undef SUPPORT_UTF */
|
||||
/* #undef SUPPORT_UTF8 */
|
||||
|
||||
/* Define to any value for valgrind support to find invalid memory reads. */
|
||||
/* Valgrind support to find invalid memory reads. */
|
||||
/* #undef SUPPORT_VALGRIND */
|
||||
|
||||
/* Version number of package */
|
||||
#ifndef VERSION
|
||||
#define VERSION "8.37"
|
||||
#define VERSION "8.38"
|
||||
#endif
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
@ -376,4 +451,3 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
/* The current PCRE version information. */
|
||||
|
||||
#define PCRE_MAJOR 8
|
||||
#define PCRE_MINOR 37
|
||||
#define PCRE_MINOR 38
|
||||
#define PCRE_PRERELEASE
|
||||
#define PCRE_DATE 2015-04-28
|
||||
#define PCRE_DATE 2015-11-23
|
||||
|
||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||
imported have to be identified as such. When building PCRE, the appropriate
|
||||
|
@ -172,7 +172,7 @@ static const short int escapes[] = {
|
||||
-ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
|
||||
CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
|
||||
CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
|
||||
CHAR_GRAVE_ACCENT, 7,
|
||||
CHAR_GRAVE_ACCENT, ESC_a,
|
||||
-ESC_b, 0,
|
||||
-ESC_d, ESC_e,
|
||||
ESC_f, 0,
|
||||
@ -200,9 +200,9 @@ static const short int escapes[] = {
|
||||
/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
|
||||
/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
|
||||
/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
|
||||
/* 80 */ 0, ESC_a, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
|
||||
/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
|
||||
/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p,
|
||||
/* 90 */ 0, 0, -ESC_k, 0, 0, ESC_n, 0, -ESC_p,
|
||||
/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
|
||||
/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
|
||||
/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
|
||||
@ -217,6 +217,12 @@ static const short int escapes[] = {
|
||||
/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* We also need a table of characters that may follow \c in an EBCDIC
|
||||
environment for characters 0-31. */
|
||||
|
||||
static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -456,7 +462,7 @@ static const char error_texts[] =
|
||||
"range out of order in character class\0"
|
||||
"nothing to repeat\0"
|
||||
/* 10 */
|
||||
"operand of unlimited repeat could match the empty string\0" /** DEAD **/
|
||||
"internal error: invalid forward reference offset\0"
|
||||
"internal error: unexpected repeat\0"
|
||||
"unrecognized character after (? or (?-\0"
|
||||
"POSIX named classes are supported only within a class\0"
|
||||
@ -525,7 +531,11 @@ static const char error_texts[] =
|
||||
"different names for subpatterns of the same number are not allowed\0"
|
||||
"(*MARK) must have an argument\0"
|
||||
"this version of PCRE is not compiled with Unicode property support\0"
|
||||
#ifndef EBCDIC
|
||||
"\\c must be followed by an ASCII character\0"
|
||||
#else
|
||||
"\\c must be followed by a letter or one of [\\]^_?\0"
|
||||
#endif
|
||||
"\\k is not followed by a braced, angle-bracketed, or quoted name\0"
|
||||
/* 70 */
|
||||
"internal error: unknown opcode in find_fixedlength()\0"
|
||||
@ -1423,7 +1433,16 @@ else
|
||||
c ^= 0x40;
|
||||
#else /* EBCDIC coding */
|
||||
if (c >= CHAR_a && c <= CHAR_z) c += 64;
|
||||
c ^= 0xC0;
|
||||
if (c == CHAR_QUESTION_MARK)
|
||||
c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (c == ebcdic_escape_c[i]) break;
|
||||
}
|
||||
if (i < 32) c = i; else *errorcodeptr = ERR68;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -1797,7 +1816,7 @@ for (;;)
|
||||
case OP_ASSERTBACK:
|
||||
case OP_ASSERTBACK_NOT:
|
||||
do cc += GET(cc, 1); while (*cc == OP_ALT);
|
||||
cc += PRIV(OP_lengths)[*cc];
|
||||
cc += 1 + LINK_SIZE;
|
||||
break;
|
||||
|
||||
/* Skip over things that don't match chars */
|
||||
@ -2485,7 +2504,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
|
||||
if (c == OP_BRA || c == OP_BRAPOS ||
|
||||
c == OP_CBRA || c == OP_CBRAPOS ||
|
||||
c == OP_ONCE || c == OP_ONCE_NC ||
|
||||
c == OP_COND)
|
||||
c == OP_COND || c == OP_SCOND)
|
||||
{
|
||||
BOOL empty_branch;
|
||||
if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
|
||||
@ -3884,11 +3903,11 @@ didn't consider this to be a POSIX class. Likewise for [:1234:].
|
||||
The problem in trying to be exactly like Perl is in the handling of escapes. We
|
||||
have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
|
||||
class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
|
||||
below handles the special case of \], but does not try to do any other escape
|
||||
processing. This makes it different from Perl for cases such as [:l\ower:]
|
||||
where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
|
||||
"l\ower". This is a lesser evil than not diagnosing bad classes when Perl does,
|
||||
I think.
|
||||
below handles the special cases \\ and \], but does not try to do any other
|
||||
escape processing. This makes it different from Perl for cases such as
|
||||
[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does
|
||||
not recognize "l\ower". This is a lesser evil than not diagnosing bad classes
|
||||
when Perl does, I think.
|
||||
|
||||
A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
|
||||
It seems that the appearance of a nested POSIX class supersedes an apparent
|
||||
@ -3915,21 +3934,16 @@ pcre_uchar terminator; /* Don't combine these lines; the Solaris cc */
|
||||
terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
|
||||
for (++ptr; *ptr != CHAR_NULL; ptr++)
|
||||
{
|
||||
if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
if (*ptr == CHAR_BACKSLASH &&
|
||||
(ptr[1] == CHAR_RIGHT_SQUARE_BRACKET ||
|
||||
ptr[1] == CHAR_BACKSLASH))
|
||||
ptr++;
|
||||
else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
|
||||
else
|
||||
else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||
|
||||
*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
|
||||
else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
{
|
||||
if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
{
|
||||
*endptr = ptr;
|
||||
return TRUE;
|
||||
}
|
||||
if (*ptr == CHAR_LEFT_SQUARE_BRACKET &&
|
||||
(ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
|
||||
ptr[1] == CHAR_EQUALS_SIGN) &&
|
||||
check_posix_syntax(ptr, endptr))
|
||||
return FALSE;
|
||||
*endptr = ptr;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
@ -3983,11 +3997,12 @@ have their offsets adjusted. That one of the jobs of this function. Before it
|
||||
is called, the partially compiled regex must be temporarily terminated with
|
||||
OP_END.
|
||||
|
||||
This function has been extended with the possibility of forward references for
|
||||
recursions and subroutine calls. It must also check the list of such references
|
||||
for the group we are dealing with. If it finds that one of the recursions in
|
||||
the current group is on this list, it adjusts the offset in the list, not the
|
||||
value in the reference (which is a group number).
|
||||
This function has been extended to cope with forward references for recursions
|
||||
and subroutine calls. It must check the list of such references for the
|
||||
group we are dealing with. If it finds that one of the recursions in the
|
||||
current group is on this list, it does not adjust the value in the reference
|
||||
(which is a group number). After the group has been scanned, all the offsets in
|
||||
the forward reference list for the group are adjusted.
|
||||
|
||||
Arguments:
|
||||
group points to the start of the group
|
||||
@ -4003,29 +4018,21 @@ static void
|
||||
adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
|
||||
size_t save_hwm_offset)
|
||||
{
|
||||
int offset;
|
||||
pcre_uchar *hc;
|
||||
pcre_uchar *ptr = group;
|
||||
|
||||
while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
|
||||
{
|
||||
int offset;
|
||||
pcre_uchar *hc;
|
||||
|
||||
/* See if this recursion is on the forward reference list. If so, adjust the
|
||||
reference. */
|
||||
|
||||
for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
|
||||
hc += LINK_SIZE)
|
||||
{
|
||||
offset = (int)GET(hc, 0);
|
||||
if (cd->start_code + offset == ptr + 1)
|
||||
{
|
||||
PUT(hc, 0, offset + adjust);
|
||||
break;
|
||||
}
|
||||
if (cd->start_code + offset == ptr + 1) break;
|
||||
}
|
||||
|
||||
/* Otherwise, adjust the recursion offset if it's after the start of this
|
||||
group. */
|
||||
/* If we have not found this recursion on the forward reference list, adjust
|
||||
the recursion's offset if it's after the start of this group. */
|
||||
|
||||
if (hc >= cd->hwm)
|
||||
{
|
||||
@ -4035,6 +4042,15 @@ while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
|
||||
|
||||
ptr += 1 + LINK_SIZE;
|
||||
}
|
||||
|
||||
/* Now adjust all forward reference offsets for the group. */
|
||||
|
||||
for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
|
||||
hc += LINK_SIZE)
|
||||
{
|
||||
offset = (int)GET(hc, 0);
|
||||
PUT(hc, 0, offset + adjust);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4463,7 +4479,7 @@ const pcre_uchar *tempptr;
|
||||
const pcre_uchar *nestptr = NULL;
|
||||
pcre_uchar *previous = NULL;
|
||||
pcre_uchar *previous_callout = NULL;
|
||||
size_t save_hwm_offset = 0;
|
||||
size_t item_hwm_offset = 0;
|
||||
pcre_uint8 classbits[32];
|
||||
|
||||
/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
|
||||
@ -4621,8 +4637,7 @@ for (;; ptr++)
|
||||
/* In the real compile phase, just check the workspace used by the forward
|
||||
reference list. */
|
||||
|
||||
else if (cd->hwm > cd->start_workspace + cd->workspace_size -
|
||||
WORK_SIZE_SAFETY_MARGIN)
|
||||
else if (cd->hwm > cd->start_workspace + cd->workspace_size)
|
||||
{
|
||||
*errorcodeptr = ERR52;
|
||||
goto FAILED;
|
||||
@ -4765,6 +4780,7 @@ for (;; ptr++)
|
||||
zeroreqchar = reqchar;
|
||||
zeroreqcharflags = reqcharflags;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
|
||||
break;
|
||||
|
||||
@ -4816,6 +4832,7 @@ for (;; ptr++)
|
||||
/* Handle a real character class. */
|
||||
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
|
||||
/* PCRE supports POSIX class stuff inside a class. Perl gives an error if
|
||||
they are encountered at the top level, so we'll do that too. */
|
||||
@ -4921,9 +4938,10 @@ for (;; ptr++)
|
||||
(which is on the stack). We have to remember that there was XCLASS data,
|
||||
however. */
|
||||
|
||||
if (class_uchardata > class_uchardata_base) xclass = TRUE;
|
||||
|
||||
if (lengthptr != NULL && class_uchardata > class_uchardata_base)
|
||||
{
|
||||
xclass = TRUE;
|
||||
*lengthptr += (int)(class_uchardata - class_uchardata_base);
|
||||
class_uchardata = class_uchardata_base;
|
||||
}
|
||||
@ -5026,10 +5044,26 @@ for (;; ptr++)
|
||||
ptr = tempptr + 1;
|
||||
continue;
|
||||
|
||||
/* For all other POSIX classes, no special action is taken in UCP
|
||||
mode. Fall through to the non_UCP case. */
|
||||
/* For the other POSIX classes (ascii, xdigit) we are going to fall
|
||||
through to the non-UCP case and build a bit map for characters with
|
||||
code points less than 256. If we are in a negated POSIX class
|
||||
within a non-negated overall class, characters with code points
|
||||
greater than 255 must all match. In the special case where we have
|
||||
not yet generated any xclass data, and this is the final item in
|
||||
the overall class, we need do nothing: later on, the opcode
|
||||
OP_NCLASS will be used to indicate that characters greater than 255
|
||||
are acceptable. If we have already seen an xclass item or one may
|
||||
follow (we have to assume that it might if this is not the end of
|
||||
the class), explicitly match all wide codepoints. */
|
||||
|
||||
default:
|
||||
if (!negate_class && local_negate &&
|
||||
(xclass || tempptr[2] != CHAR_RIGHT_SQUARE_BRACKET))
|
||||
{
|
||||
*class_uchardata++ = XCL_RANGE;
|
||||
class_uchardata += PRIV(ord2utf)(0x100, class_uchardata);
|
||||
class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -5193,9 +5227,9 @@ for (;; ptr++)
|
||||
cd, PRIV(vspace_list));
|
||||
continue;
|
||||
|
||||
#ifdef SUPPORT_UCP
|
||||
case ESC_p:
|
||||
case ESC_P:
|
||||
#ifdef SUPPORT_UCP
|
||||
{
|
||||
BOOL negated;
|
||||
unsigned int ptype = 0, pdata = 0;
|
||||
@ -5209,6 +5243,9 @@ for (;; ptr++)
|
||||
class_has_8bitchar--; /* Undo! */
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
*errorcodeptr = ERR45;
|
||||
goto FAILED;
|
||||
#endif
|
||||
/* Unrecognized escapes are faulted if PCRE is running in its
|
||||
strict mode. By default, for compatibility with Perl, they are
|
||||
@ -5365,16 +5402,20 @@ for (;; ptr++)
|
||||
CLASS_SINGLE_CHARACTER:
|
||||
if (class_one_char < 2) class_one_char++;
|
||||
|
||||
/* If class_one_char is 1, we have the first single character in the
|
||||
class, and there have been no prior ranges, or XCLASS items generated by
|
||||
escapes. If this is the final character in the class, we can optimize by
|
||||
turning the item into a 1-character OP_CHAR[I] if it's positive, or
|
||||
OP_NOT[I] if it's negative. In the positive case, it can cause firstchar
|
||||
to be set. Otherwise, there can be no first char if this item is first,
|
||||
whatever repeat count may follow. In the case of reqchar, save the
|
||||
previous value for reinstating. */
|
||||
/* If xclass_has_prop is false and class_one_char is 1, we have the first
|
||||
single character in the class, and there have been no prior ranges, or
|
||||
XCLASS items generated by escapes. If this is the final character in the
|
||||
class, we can optimize by turning the item into a 1-character OP_CHAR[I]
|
||||
if it's positive, or OP_NOT[I] if it's negative. In the positive case, it
|
||||
can cause firstchar to be set. Otherwise, there can be no first char if
|
||||
this item is first, whatever repeat count may follow. In the case of
|
||||
reqchar, save the previous value for reinstating. */
|
||||
|
||||
if (!inescq && class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
if (!inescq &&
|
||||
#ifdef SUPPORT_UCP
|
||||
!xclass_has_prop &&
|
||||
#endif
|
||||
class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
||||
{
|
||||
ptr++;
|
||||
zeroreqchar = reqchar;
|
||||
@ -5490,9 +5531,10 @@ for (;; ptr++)
|
||||
actual compiled code. */
|
||||
|
||||
#ifdef SUPPORT_UTF
|
||||
if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0))
|
||||
if (xclass && (xclass_has_prop || !should_flip_negation ||
|
||||
(options & PCRE_UCP) != 0))
|
||||
#elif !defined COMPILE_PCRE8
|
||||
if (xclass && !should_flip_negation)
|
||||
if (xclass && (xclass_has_prop || !should_flip_negation))
|
||||
#endif
|
||||
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
|
||||
{
|
||||
@ -5928,7 +5970,7 @@ for (;; ptr++)
|
||||
{
|
||||
register int i;
|
||||
int len = (int)(code - previous);
|
||||
size_t base_hwm_offset = save_hwm_offset;
|
||||
size_t base_hwm_offset = item_hwm_offset;
|
||||
pcre_uchar *bralink = NULL;
|
||||
pcre_uchar *brazeroptr = NULL;
|
||||
|
||||
@ -5983,7 +6025,7 @@ for (;; ptr++)
|
||||
if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
|
||||
{
|
||||
*code = OP_END;
|
||||
adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(previous, 1, utf, cd, item_hwm_offset);
|
||||
memmove(previous + 1, previous, IN_UCHARS(len));
|
||||
code++;
|
||||
if (repeat_max == 0)
|
||||
@ -6007,7 +6049,7 @@ for (;; ptr++)
|
||||
{
|
||||
int offset;
|
||||
*code = OP_END;
|
||||
adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
|
||||
code += 2 + LINK_SIZE;
|
||||
*previous++ = OP_BRAZERO + repeat_type;
|
||||
@ -6252,6 +6294,12 @@ for (;; ptr++)
|
||||
while (*scode == OP_ALT);
|
||||
}
|
||||
|
||||
/* A conditional group with only one branch has an implicit empty
|
||||
alternative branch. */
|
||||
|
||||
if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)
|
||||
*bracode = OP_SCOND;
|
||||
|
||||
/* Handle possessive quantifiers. */
|
||||
|
||||
if (possessive_quantifier)
|
||||
@ -6265,11 +6313,11 @@ for (;; ptr++)
|
||||
{
|
||||
int nlen = (int)(code - bracode);
|
||||
*code = OP_END;
|
||||
adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
|
||||
code += 1 + LINK_SIZE;
|
||||
nlen += 1 + LINK_SIZE;
|
||||
*bracode = OP_BRAPOS;
|
||||
*bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
|
||||
*code++ = OP_KETRPOS;
|
||||
PUTINC(code, 0, nlen);
|
||||
PUT(bracode, 1, nlen);
|
||||
@ -6399,7 +6447,7 @@ for (;; ptr++)
|
||||
else
|
||||
{
|
||||
*code = OP_END;
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
||||
code += 1 + LINK_SIZE;
|
||||
len += 1 + LINK_SIZE;
|
||||
@ -6448,7 +6496,7 @@ for (;; ptr++)
|
||||
|
||||
default:
|
||||
*code = OP_END;
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
||||
adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
||||
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
||||
code += 1 + LINK_SIZE;
|
||||
len += 1 + LINK_SIZE;
|
||||
@ -6584,9 +6632,17 @@ for (;; ptr++)
|
||||
goto FAILED;
|
||||
}
|
||||
setverb = *code++ = verbs[i].op_arg;
|
||||
*code++ = arglen;
|
||||
memcpy(code, arg, IN_UCHARS(arglen));
|
||||
code += arglen;
|
||||
if (lengthptr != NULL) /* In pass 1 just add in the length */
|
||||
{ /* to avoid potential workspace */
|
||||
*lengthptr += arglen; /* overflow. */
|
||||
*code++ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*code++ = arglen;
|
||||
memcpy(code, arg, IN_UCHARS(arglen));
|
||||
code += arglen;
|
||||
}
|
||||
*code++ = 0;
|
||||
}
|
||||
|
||||
@ -6621,7 +6677,7 @@ for (;; ptr++)
|
||||
newoptions = options;
|
||||
skipbytes = 0;
|
||||
bravalue = OP_CBRA;
|
||||
save_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
reset_bracount = FALSE;
|
||||
|
||||
/* Deal with the extended parentheses; all are introduced by '?', and the
|
||||
@ -6639,6 +6695,7 @@ for (;; ptr++)
|
||||
/* ------------------------------------------------------------ */
|
||||
case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
|
||||
reset_bracount = TRUE;
|
||||
cd->dupgroups = TRUE; /* Record (?| encountered */
|
||||
/* Fall through */
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ -6739,6 +6796,12 @@ for (;; ptr++)
|
||||
{
|
||||
while (IS_DIGIT(*ptr))
|
||||
{
|
||||
if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
||||
{
|
||||
while (IS_DIGIT(*ptr)) ptr++;
|
||||
*errorcodeptr = ERR61;
|
||||
goto FAILED;
|
||||
}
|
||||
recno = recno * 10 + (int)(*ptr - CHAR_0);
|
||||
ptr++;
|
||||
}
|
||||
@ -6767,7 +6830,7 @@ for (;; ptr++)
|
||||
ptr++;
|
||||
}
|
||||
namelen = (int)(ptr - name);
|
||||
if (lengthptr != NULL) *lengthptr += IMM2_SIZE;
|
||||
if (lengthptr != NULL) skipbytes += IMM2_SIZE;
|
||||
}
|
||||
|
||||
/* Check the terminator */
|
||||
@ -6873,6 +6936,11 @@ for (;; ptr++)
|
||||
*errorcodeptr = ERR15;
|
||||
goto FAILED;
|
||||
}
|
||||
if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
||||
{
|
||||
*errorcodeptr = ERR61;
|
||||
goto FAILED;
|
||||
}
|
||||
recno = recno * 10 + name[i] - CHAR_0;
|
||||
}
|
||||
if (recno == 0) recno = RREF_ANY;
|
||||
@ -7149,6 +7217,7 @@ for (;; ptr++)
|
||||
if (lengthptr != NULL)
|
||||
{
|
||||
named_group *ng;
|
||||
recno = 0;
|
||||
|
||||
if (namelen == 0)
|
||||
{
|
||||
@ -7166,20 +7235,6 @@ for (;; ptr++)
|
||||
goto FAILED;
|
||||
}
|
||||
|
||||
/* The name table does not exist in the first pass; instead we must
|
||||
scan the list of names encountered so far in order to get the
|
||||
number. If the name is not found, set the value to 0 for a forward
|
||||
reference. */
|
||||
|
||||
ng = cd->named_groups;
|
||||
for (i = 0; i < cd->names_found; i++, ng++)
|
||||
{
|
||||
if (namelen == ng->length &&
|
||||
STRNCMP_UC_UC(name, ng->name, namelen) == 0)
|
||||
break;
|
||||
}
|
||||
recno = (i < cd->names_found)? ng->number : 0;
|
||||
|
||||
/* Count named back references. */
|
||||
|
||||
if (!is_recurse) cd->namedrefcount++;
|
||||
@ -7189,6 +7244,56 @@ for (;; ptr++)
|
||||
16-bit data item. */
|
||||
|
||||
*lengthptr += IMM2_SIZE;
|
||||
|
||||
/* If this is a forward reference and we are within a (?|...) group,
|
||||
the reference may end up as the number of a group which we are
|
||||
currently inside, that is, it could be a recursive reference. In the
|
||||
real compile this will be picked up and the reference wrapped with
|
||||
OP_ONCE to make it atomic, so we must space in case this occurs. */
|
||||
|
||||
/* In fact, this can happen for a non-forward reference because
|
||||
another group with the same number might be created later. This
|
||||
issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance
|
||||
only mode, we finesse the bug by allowing more memory always. */
|
||||
|
||||
*lengthptr += 2 + 2*LINK_SIZE;
|
||||
|
||||
/* It is even worse than that. The current reference may be to an
|
||||
existing named group with a different number (so apparently not
|
||||
recursive) but which later on is also attached to a group with the
|
||||
current number. This can only happen if $(| has been previous
|
||||
encountered. In that case, we allow yet more memory, just in case.
|
||||
(Again, this is fixed "properly" in PCRE2. */
|
||||
|
||||
if (cd->dupgroups) *lengthptr += 4 + 4*LINK_SIZE;
|
||||
|
||||
/* Otherwise, check for recursion here. The name table does not exist
|
||||
in the first pass; instead we must scan the list of names encountered
|
||||
so far in order to get the number. If the name is not found, leave
|
||||
the value of recno as 0 for a forward reference. */
|
||||
|
||||
else
|
||||
{
|
||||
ng = cd->named_groups;
|
||||
for (i = 0; i < cd->names_found; i++, ng++)
|
||||
{
|
||||
if (namelen == ng->length &&
|
||||
STRNCMP_UC_UC(name, ng->name, namelen) == 0)
|
||||
{
|
||||
open_capitem *oc;
|
||||
recno = ng->number;
|
||||
if (is_recurse) break;
|
||||
for (oc = cd->open_caps; oc != NULL; oc = oc->next)
|
||||
{
|
||||
if (oc->number == recno)
|
||||
{
|
||||
oc->flag = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In the real compile, search the name table. We check the name
|
||||
@ -7235,8 +7340,6 @@ for (;; ptr++)
|
||||
for (i++; i < cd->names_found; i++)
|
||||
{
|
||||
if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
|
||||
|
||||
|
||||
count++;
|
||||
cslot += cd->name_entry_size;
|
||||
}
|
||||
@ -7245,6 +7348,7 @@ for (;; ptr++)
|
||||
{
|
||||
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
|
||||
PUT2INC(code, 0, index);
|
||||
PUT2INC(code, 0, count);
|
||||
@ -7282,9 +7386,14 @@ for (;; ptr++)
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
case CHAR_R: /* Recursion */
|
||||
ptr++; /* Same as (?0) */
|
||||
/* Fall through */
|
||||
case CHAR_R: /* Recursion, same as (?0) */
|
||||
recno = 0;
|
||||
if (*(++ptr) != CHAR_RIGHT_PARENTHESIS)
|
||||
{
|
||||
*errorcodeptr = ERR29;
|
||||
goto FAILED;
|
||||
}
|
||||
goto HANDLE_RECURSION;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@ -7321,7 +7430,15 @@ for (;; ptr++)
|
||||
|
||||
recno = 0;
|
||||
while(IS_DIGIT(*ptr))
|
||||
{
|
||||
if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
||||
{
|
||||
while (IS_DIGIT(*ptr)) ptr++;
|
||||
*errorcodeptr = ERR61;
|
||||
goto FAILED;
|
||||
}
|
||||
recno = recno * 10 + *ptr++ - CHAR_0;
|
||||
}
|
||||
|
||||
if (*ptr != (pcre_uchar)terminator)
|
||||
{
|
||||
@ -7358,6 +7475,7 @@ for (;; ptr++)
|
||||
HANDLE_RECURSION:
|
||||
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
called = cd->start_code;
|
||||
|
||||
/* When we are actually compiling, find the bracket that is being
|
||||
@ -7559,7 +7677,11 @@ for (;; ptr++)
|
||||
previous = NULL;
|
||||
cd->iscondassert = FALSE;
|
||||
}
|
||||
else previous = code;
|
||||
else
|
||||
{
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
}
|
||||
|
||||
*code = bravalue;
|
||||
tempcode = code;
|
||||
@ -7807,7 +7929,7 @@ for (;; ptr++)
|
||||
const pcre_uchar *p;
|
||||
pcre_uint32 cf;
|
||||
|
||||
save_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
|
||||
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
|
||||
CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
|
||||
|
||||
@ -7836,7 +7958,7 @@ for (;; ptr++)
|
||||
if (*p != (pcre_uchar)terminator)
|
||||
{
|
||||
*errorcodeptr = ERR57;
|
||||
break;
|
||||
goto FAILED;
|
||||
}
|
||||
ptr++;
|
||||
goto HANDLE_NUMERICAL_RECURSION;
|
||||
@ -7851,7 +7973,7 @@ for (;; ptr++)
|
||||
ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
|
||||
{
|
||||
*errorcodeptr = ERR69;
|
||||
break;
|
||||
goto FAILED;
|
||||
}
|
||||
is_recurse = FALSE;
|
||||
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
|
||||
@ -7875,6 +7997,7 @@ for (;; ptr++)
|
||||
HANDLE_REFERENCE:
|
||||
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
|
||||
PUT2INC(code, 0, recno);
|
||||
cd->backref_map |= (recno < 32)? (1 << recno) : 1;
|
||||
@ -7904,6 +8027,7 @@ for (;; ptr++)
|
||||
if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr))
|
||||
goto FAILED;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
|
||||
*code++ = ptype;
|
||||
*code++ = pdata;
|
||||
@ -7944,6 +8068,7 @@ for (;; ptr++)
|
||||
|
||||
{
|
||||
previous = (escape > ESC_b && escape < ESC_Z)? code : NULL;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape;
|
||||
}
|
||||
}
|
||||
@ -7987,6 +8112,7 @@ for (;; ptr++)
|
||||
|
||||
ONE_CHAR:
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
|
||||
/* For caseless UTF-8 mode when UCP support is available, check whether
|
||||
this character has more than one other case. If so, generate a special
|
||||
@ -9162,6 +9288,7 @@ cd->names_found = 0;
|
||||
cd->name_entry_size = 0;
|
||||
cd->name_table = NULL;
|
||||
cd->dupnames = FALSE;
|
||||
cd->dupgroups = FALSE;
|
||||
cd->namedrefcount = 0;
|
||||
cd->start_code = cworkspace;
|
||||
cd->hwm = cworkspace;
|
||||
@ -9334,6 +9461,16 @@ if (cd->hwm > cd->start_workspace)
|
||||
int offset, recno;
|
||||
cd->hwm -= LINK_SIZE;
|
||||
offset = GET(cd->hwm, 0);
|
||||
|
||||
/* Check that the hwm handling hasn't gone wrong. This whole area is
|
||||
rewritten in PCRE2 because there are some obscure cases. */
|
||||
|
||||
if (offset == 0 || codestart[offset-1] != OP_RECURSE)
|
||||
{
|
||||
errorcode = ERR10;
|
||||
break;
|
||||
}
|
||||
|
||||
recno = GET(codestart, offset);
|
||||
if (recno != prev_recno)
|
||||
{
|
||||
@ -9364,7 +9501,7 @@ used in this code because at least one compiler gives a warning about loss of
|
||||
"const" attribute if the cast (pcre_uchar *)codestart is used directly in the
|
||||
function call. */
|
||||
|
||||
if ((options & PCRE_NO_AUTO_POSSESS) == 0)
|
||||
if (errorcode == 0 && (options & PCRE_NO_AUTO_POSSESS) == 0)
|
||||
{
|
||||
pcre_uchar *temp = (pcre_uchar *)codestart;
|
||||
auto_possessify(temp, utf, cd);
|
||||
@ -9378,7 +9515,7 @@ OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The
|
||||
exceptional ones forgo this. We scan the pattern to check that they are fixed
|
||||
length, and set their lengths. */
|
||||
|
||||
if (cd->check_lookbehind)
|
||||
if (errorcode == 0 && cd->check_lookbehind)
|
||||
{
|
||||
pcre_uchar *cc = (pcre_uchar *)codestart;
|
||||
|
||||
@ -9591,4 +9728,3 @@ return (pcre32 *)re;
|
||||
}
|
||||
|
||||
/* End of pcre_compile.c */
|
||||
|
||||
|
@ -686,7 +686,7 @@ the alternative names that are used. */
|
||||
#define foc number
|
||||
#define save_mark data
|
||||
|
||||
/* These statements are here to stop the compiler complaining about uninitialized
|
||||
/* These statements are here to stop the compiler complaining about unitialized
|
||||
variables. */
|
||||
|
||||
#ifdef SUPPORT_UCP
|
||||
@ -6683,7 +6683,8 @@ if (md->offset_vector != NULL)
|
||||
register int *iend = iptr - re->top_bracket;
|
||||
if (iend < md->offset_vector + 2) iend = md->offset_vector + 2;
|
||||
while (--iptr >= iend) *iptr = -1;
|
||||
md->offset_vector[0] = md->offset_vector[1] = -1;
|
||||
if (offsetcount > 0) md->offset_vector[0] = -1;
|
||||
if (offsetcount > 1) md->offset_vector[1] = -1;
|
||||
}
|
||||
|
||||
/* Set up the first character to match, if available. The first_char value is
|
||||
|
@ -984,7 +984,7 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
|
||||
#ifndef EBCDIC
|
||||
|
||||
#define HSPACE_LIST \
|
||||
CHAR_HT, CHAR_SPACE, 0xa0, \
|
||||
CHAR_HT, CHAR_SPACE, CHAR_NBSP, \
|
||||
0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
|
||||
0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
|
||||
NOTACHAR
|
||||
@ -1010,7 +1010,7 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
|
||||
#define HSPACE_BYTE_CASES \
|
||||
case CHAR_HT: \
|
||||
case CHAR_SPACE: \
|
||||
case 0xa0 /* NBSP */
|
||||
case CHAR_NBSP
|
||||
|
||||
#define HSPACE_CASES \
|
||||
HSPACE_BYTE_CASES: \
|
||||
@ -1037,11 +1037,12 @@ other. NOTE: The values also appear in pcre_jit_compile.c. */
|
||||
/* ------ EBCDIC environments ------ */
|
||||
|
||||
#else
|
||||
#define HSPACE_LIST CHAR_HT, CHAR_SPACE
|
||||
#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR
|
||||
|
||||
#define HSPACE_BYTE_CASES \
|
||||
case CHAR_HT: \
|
||||
case CHAR_SPACE
|
||||
case CHAR_SPACE: \
|
||||
case CHAR_NBSP
|
||||
|
||||
#define HSPACE_CASES HSPACE_BYTE_CASES
|
||||
|
||||
@ -1215,6 +1216,7 @@ same code point. */
|
||||
|
||||
#define CHAR_ESC '\047'
|
||||
#define CHAR_DEL '\007'
|
||||
#define CHAR_NBSP '\x41'
|
||||
#define STR_ESC "\047"
|
||||
#define STR_DEL "\007"
|
||||
|
||||
@ -1229,6 +1231,7 @@ a positive value. */
|
||||
#define CHAR_NEL ((unsigned char)'\x85')
|
||||
#define CHAR_ESC '\033'
|
||||
#define CHAR_DEL '\177'
|
||||
#define CHAR_NBSP ((unsigned char)'\xa0')
|
||||
|
||||
#define STR_LF "\n"
|
||||
#define STR_NL STR_LF
|
||||
@ -1606,6 +1609,7 @@ only. */
|
||||
#define CHAR_VERTICAL_LINE '\174'
|
||||
#define CHAR_RIGHT_CURLY_BRACKET '\175'
|
||||
#define CHAR_TILDE '\176'
|
||||
#define CHAR_NBSP ((unsigned char)'\xa0')
|
||||
|
||||
#define STR_HT "\011"
|
||||
#define STR_VT "\013"
|
||||
@ -1762,6 +1766,10 @@ only. */
|
||||
|
||||
/* Escape items that are just an encoding of a particular data value. */
|
||||
|
||||
#ifndef ESC_a
|
||||
#define ESC_a CHAR_BEL
|
||||
#endif
|
||||
|
||||
#ifndef ESC_e
|
||||
#define ESC_e CHAR_ESC
|
||||
#endif
|
||||
@ -2446,6 +2454,7 @@ typedef struct compile_data {
|
||||
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
|
||||
BOOL check_lookbehind; /* Lookbehinds need later checking */
|
||||
BOOL dupnames; /* Duplicate names exist */
|
||||
BOOL dupgroups; /* Duplicate groups exist: (?| found */
|
||||
BOOL iscondassert; /* Next assert is a condition */
|
||||
int nltype; /* Newline type */
|
||||
int nllen; /* Newline string length */
|
||||
|
@ -1064,6 +1064,7 @@ pcre_uchar *alternative;
|
||||
pcre_uchar *end = NULL;
|
||||
int private_data_ptr = *private_data_start;
|
||||
int space, size, bracketlen;
|
||||
BOOL repeat_check = TRUE;
|
||||
|
||||
while (cc < ccend)
|
||||
{
|
||||
@ -1071,9 +1072,10 @@ while (cc < ccend)
|
||||
size = 0;
|
||||
bracketlen = 0;
|
||||
if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
|
||||
return;
|
||||
break;
|
||||
|
||||
if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
|
||||
if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
|
||||
{
|
||||
if (detect_repeat(common, cc))
|
||||
{
|
||||
/* These brackets are converted to repeats, so no global
|
||||
@ -1081,6 +1083,8 @@ while (cc < ccend)
|
||||
if (cc >= end)
|
||||
end = bracketend(cc);
|
||||
}
|
||||
}
|
||||
repeat_check = TRUE;
|
||||
|
||||
switch(*cc)
|
||||
{
|
||||
@ -1136,6 +1140,13 @@ while (cc < ccend)
|
||||
bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_BRAZERO:
|
||||
case OP_BRAMINZERO:
|
||||
case OP_BRAPOSZERO:
|
||||
repeat_check = FALSE;
|
||||
size = 1;
|
||||
break;
|
||||
|
||||
CASE_ITERATOR_PRIVATE_DATA_1
|
||||
space = 1;
|
||||
size = -2;
|
||||
@ -1162,12 +1173,17 @@ while (cc < ccend)
|
||||
size = 1;
|
||||
break;
|
||||
|
||||
CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
|
||||
case OP_TYPEUPTO:
|
||||
if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
|
||||
space = 2;
|
||||
size = 1 + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_TYPEMINUPTO:
|
||||
space = 2;
|
||||
size = 1 + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_CLASS:
|
||||
case OP_NCLASS:
|
||||
size += 1 + 32 / sizeof(pcre_uchar);
|
||||
@ -1316,6 +1332,13 @@ while (cc < ccend)
|
||||
cc += 1 + LINK_SIZE + IMM2_SIZE;
|
||||
break;
|
||||
|
||||
case OP_THEN:
|
||||
stack_restore = TRUE;
|
||||
if (common->control_head_ptr != 0)
|
||||
*needs_control_head = TRUE;
|
||||
cc ++;
|
||||
break;
|
||||
|
||||
default:
|
||||
stack_restore = TRUE;
|
||||
/* Fall through. */
|
||||
@ -2220,6 +2243,7 @@ while (current != NULL)
|
||||
SLJIT_ASSERT_STOP();
|
||||
break;
|
||||
}
|
||||
SLJIT_ASSERT(current > (sljit_sw*)current[-1]);
|
||||
current = (sljit_sw*)current[-1];
|
||||
}
|
||||
return -1;
|
||||
@ -3209,7 +3233,7 @@ bytes[len] = byte;
|
||||
bytes[0] = len;
|
||||
}
|
||||
|
||||
static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars)
|
||||
static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars, pcre_uint32 *rec_count)
|
||||
{
|
||||
/* Recursive function, which scans prefix literals. */
|
||||
BOOL last, any, caseless;
|
||||
@ -3227,9 +3251,14 @@ pcre_uchar othercase[1];
|
||||
repeat = 1;
|
||||
while (TRUE)
|
||||
{
|
||||
if (*rec_count == 0)
|
||||
return 0;
|
||||
(*rec_count)--;
|
||||
|
||||
last = TRUE;
|
||||
any = FALSE;
|
||||
caseless = FALSE;
|
||||
|
||||
switch (*cc)
|
||||
{
|
||||
case OP_CHARI:
|
||||
@ -3291,7 +3320,7 @@ while (TRUE)
|
||||
#ifdef SUPPORT_UTF
|
||||
if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
|
||||
#endif
|
||||
max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars);
|
||||
max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count);
|
||||
if (max_chars == 0)
|
||||
return consumed;
|
||||
last = FALSE;
|
||||
@ -3314,7 +3343,7 @@ while (TRUE)
|
||||
alternative = cc + GET(cc, 1);
|
||||
while (*alternative == OP_ALT)
|
||||
{
|
||||
max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars);
|
||||
max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count);
|
||||
if (max_chars == 0)
|
||||
return consumed;
|
||||
alternative += GET(alternative, 1);
|
||||
@ -3556,6 +3585,7 @@ int i, max, from;
|
||||
int range_right = -1, range_len = 3 - 1;
|
||||
sljit_ub *update_table = NULL;
|
||||
BOOL in_range;
|
||||
pcre_uint32 rec_count;
|
||||
|
||||
for (i = 0; i < MAX_N_CHARS; i++)
|
||||
{
|
||||
@ -3564,7 +3594,8 @@ for (i = 0; i < MAX_N_CHARS; i++)
|
||||
bytes[i * MAX_N_BYTES] = 0;
|
||||
}
|
||||
|
||||
max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS);
|
||||
rec_count = 10000;
|
||||
max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count);
|
||||
|
||||
if (max <= 1)
|
||||
return FALSE;
|
||||
@ -4311,8 +4342,10 @@ switch(length)
|
||||
case 4:
|
||||
if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
|
||||
&& (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
|
||||
&& (ranges[1] & (ranges[2] - ranges[0])) == 0
|
||||
&& is_powerof2(ranges[2] - ranges[0]))
|
||||
{
|
||||
SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
|
||||
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
|
||||
if (ranges[2] + 1 != ranges[3])
|
||||
{
|
||||
@ -4900,9 +4933,10 @@ else if ((cc[-1] & XCL_MAP) != 0)
|
||||
if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
|
||||
{
|
||||
#ifdef COMPILE_PCRE8
|
||||
SLJIT_ASSERT(common->utf);
|
||||
jump = NULL;
|
||||
if (common->utf)
|
||||
#endif
|
||||
jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
|
||||
jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
|
||||
|
||||
OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
|
||||
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
|
||||
@ -4911,7 +4945,10 @@ else if ((cc[-1] & XCL_MAP) != 0)
|
||||
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
|
||||
add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
|
||||
|
||||
JUMPHERE(jump);
|
||||
#ifdef COMPILE_PCRE8
|
||||
if (common->utf)
|
||||
#endif
|
||||
JUMPHERE(jump);
|
||||
}
|
||||
|
||||
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
|
||||
@ -5219,7 +5256,7 @@ while (*cc != XCL_END)
|
||||
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
|
||||
|
||||
SET_CHAR_OFFSET(0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
|
||||
OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
|
||||
|
||||
SET_TYPE_OFFSET(ucp_Pc);
|
||||
@ -7665,6 +7702,10 @@ while (*cc != OP_KETRPOS)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
|
||||
}
|
||||
|
||||
/* Even if the match is empty, we need to reset the control head. */
|
||||
if (needs_control_head)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
||||
|
||||
if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
|
||||
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
|
||||
|
||||
@ -7692,6 +7733,10 @@ while (*cc != OP_KETRPOS)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
|
||||
}
|
||||
|
||||
/* Even if the match is empty, we need to reset the control head. */
|
||||
if (needs_control_head)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
||||
|
||||
if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
|
||||
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
|
||||
|
||||
@ -7704,9 +7749,6 @@ while (*cc != OP_KETRPOS)
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_control_head)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
||||
|
||||
JUMPTO(SLJIT_JUMP, loop);
|
||||
flush_stubs(common);
|
||||
|
||||
@ -8441,8 +8483,7 @@ while (cc < ccend)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
|
||||
}
|
||||
BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
|
||||
if (cc[1] > OP_ASSERTBACK_NOT)
|
||||
count_match(common);
|
||||
count_match(common);
|
||||
break;
|
||||
|
||||
case OP_ONCE:
|
||||
@ -9624,7 +9665,7 @@ static SLJIT_INLINE void compile_recurse(compiler_common *common)
|
||||
DEFINE_COMPILER;
|
||||
pcre_uchar *cc = common->start + common->currententry->start;
|
||||
pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
|
||||
pcre_uchar *ccend = bracketend(cc);
|
||||
pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
|
||||
BOOL needs_control_head;
|
||||
int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
|
||||
int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
|
||||
@ -9648,6 +9689,7 @@ set_jumps(common->currententry->calls, common->currententry->entry);
|
||||
|
||||
sljit_emit_fast_enter(compiler, TMP2, 0);
|
||||
allocate_stack(common, private_data_size + framesize + alternativesize);
|
||||
count_match(common);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
|
||||
copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
|
||||
if (needs_control_head)
|
||||
@ -9992,6 +10034,7 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
||||
|
||||
if (mode == JIT_PARTIAL_SOFT_COMPILE)
|
||||
|
@ -69,6 +69,7 @@ Arguments:
|
||||
startcode pointer to start of the whole pattern's code
|
||||
options the compiling options
|
||||
recurses chain of recurse_check to catch mutual recursion
|
||||
countptr pointer to call count (to catch over complexity)
|
||||
|
||||
Returns: the minimum length
|
||||
-1 if \C in UTF-8 mode or (*ACCEPT) was encountered
|
||||
@ -78,7 +79,8 @@ Returns: the minimum length
|
||||
|
||||
static int
|
||||
find_minlength(const REAL_PCRE *re, const pcre_uchar *code,
|
||||
const pcre_uchar *startcode, int options, recurse_check *recurses)
|
||||
const pcre_uchar *startcode, int options, recurse_check *recurses,
|
||||
int *countptr)
|
||||
{
|
||||
int length = -1;
|
||||
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
|
||||
@ -88,6 +90,8 @@ recurse_check this_recurse;
|
||||
register int branchlength = 0;
|
||||
register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
|
||||
|
||||
if ((*countptr)++ > 1000) return -1; /* too complex */
|
||||
|
||||
if (*code == OP_CBRA || *code == OP_SCBRA ||
|
||||
*code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
|
||||
|
||||
@ -129,7 +133,7 @@ for (;;)
|
||||
case OP_SBRAPOS:
|
||||
case OP_ONCE:
|
||||
case OP_ONCE_NC:
|
||||
d = find_minlength(re, cc, startcode, options, recurses);
|
||||
d = find_minlength(re, cc, startcode, options, recurses, countptr);
|
||||
if (d < 0) return d;
|
||||
branchlength += d;
|
||||
do cc += GET(cc, 1); while (*cc == OP_ALT);
|
||||
@ -413,7 +417,8 @@ for (;;)
|
||||
int dd;
|
||||
this_recurse.prev = recurses;
|
||||
this_recurse.group = cs;
|
||||
dd = find_minlength(re, cs, startcode, options, &this_recurse);
|
||||
dd = find_minlength(re, cs, startcode, options, &this_recurse,
|
||||
countptr);
|
||||
if (dd < d) d = dd;
|
||||
}
|
||||
}
|
||||
@ -449,7 +454,8 @@ for (;;)
|
||||
{
|
||||
this_recurse.prev = recurses;
|
||||
this_recurse.group = cs;
|
||||
d = find_minlength(re, cs, startcode, options, &this_recurse);
|
||||
d = find_minlength(re, cs, startcode, options, &this_recurse,
|
||||
countptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -512,7 +518,7 @@ for (;;)
|
||||
this_recurse.prev = recurses;
|
||||
this_recurse.group = cs;
|
||||
branchlength += find_minlength(re, cs, startcode, options,
|
||||
&this_recurse);
|
||||
&this_recurse, countptr);
|
||||
}
|
||||
}
|
||||
cc += 1 + LINK_SIZE;
|
||||
@ -1451,6 +1457,7 @@ pcre32_study(const pcre32 *external_re, int options, const char **errorptr)
|
||||
#endif
|
||||
{
|
||||
int min;
|
||||
int count = 0;
|
||||
BOOL bits_set = FALSE;
|
||||
pcre_uint8 start_bits[32];
|
||||
PUBL(extra) *extra = NULL;
|
||||
@ -1537,7 +1544,7 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
|
||||
|
||||
/* Find the minimum length of subject string. */
|
||||
|
||||
switch(min = find_minlength(re, code, code, re->options, NULL))
|
||||
switch(min = find_minlength(re, code, code, re->options, NULL, &count))
|
||||
{
|
||||
case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
|
||||
case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
|
||||
|
@ -244,7 +244,7 @@ while ((t = *data++) != XCL_END)
|
||||
|
||||
case PT_PXPUNCT:
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||
|
||||
(c < 256 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
|
||||
(c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
|
@ -96,6 +96,15 @@
|
||||
#define SLJIT_EXECUTABLE_ALLOCATOR 1
|
||||
#endif
|
||||
|
||||
/* Force cdecl calling convention even if a better calling
|
||||
convention (e.g. fastcall) is supported by the C compiler.
|
||||
If this option is enabled, C functions without
|
||||
SLJIT_CALL can also be called from JIT code. */
|
||||
#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION
|
||||
/* Disabled by default */
|
||||
#define SLJIT_USE_CDECL_CALLING_CONVENTION 0
|
||||
#endif
|
||||
|
||||
/* Return with error when an invalid argument is passed. */
|
||||
#ifndef SLJIT_ARGUMENT_CHECKS
|
||||
/* Disabled by default */
|
||||
|
@ -468,7 +468,12 @@ typedef double sljit_d;
|
||||
|
||||
#ifndef SLJIT_CALL
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
|
||||
|
||||
/* Force cdecl. */
|
||||
#define SLJIT_CALL
|
||||
|
||||
#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
@ -608,6 +613,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 10
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 0
|
||||
|
@ -845,8 +845,8 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp
|
||||
}
|
||||
|
||||
static SLJIT_CONST char* op0_names[] = {
|
||||
(char*)"breakpoint", (char*)"nop",
|
||||
(char*)"lumul", (char*)"lsmul", (char*)"ludiv", (char*)"lsdiv",
|
||||
(char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul",
|
||||
(char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi"
|
||||
};
|
||||
|
||||
static SLJIT_CONST char* op1_names[] = {
|
||||
@ -1036,7 +1036,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL)
|
||||
|| ((op & ~SLJIT_INT_OP) >= SLJIT_LUDIV && (op & ~SLJIT_INT_OP) <= SLJIT_LSDIV));
|
||||
|| ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI));
|
||||
CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2);
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
@ -1447,6 +1447,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(offset);
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
FUNCTION_CHECK_DST(dst, dstw);
|
||||
#endif
|
||||
@ -1462,6 +1464,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(init_value);
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
FUNCTION_CHECK_DST(dst, dstw);
|
||||
#endif
|
||||
|
@ -687,7 +687,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
#define SLJIT_OP0_BASE 0
|
||||
|
||||
/* Flags: - (never set any flags)
|
||||
Note: breakpoint instruction is not supported by all architectures (namely ppc)
|
||||
Note: breakpoint instruction is not supported by all architectures (e.g. ppc)
|
||||
It falls back to SLJIT_NOP in those cases. */
|
||||
#define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0)
|
||||
/* Flags: - (never set any flags)
|
||||
@ -696,24 +696,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
|
||||
#define SLJIT_NOP (SLJIT_OP0_BASE + 1)
|
||||
/* Flags: - (may destroy flags)
|
||||
Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LUMUL (SLJIT_OP0_BASE + 2)
|
||||
/* Flags: - (may destroy flags)
|
||||
Signed multiplication of SLJIT_R0 and SLJIT_R1.
|
||||
Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
||||
#define SLJIT_LSMUL (SLJIT_OP0_BASE + 3)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
||||
Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_LUDIV (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_ILUDIV (SLJIT_LUDIV | SLJIT_INT_OP)
|
||||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined. */
|
||||
#define SLJIT_UDIVMOD (SLJIT_OP0_BASE + 4)
|
||||
#define SLJIT_IUDIVMOD (SLJIT_UDIVMOD | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
||||
Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_LSDIV (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_ILSDIV (SLJIT_LSDIV | SLJIT_INT_OP)
|
||||
The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined. */
|
||||
#define SLJIT_SDIVMOD (SLJIT_OP0_BASE + 5)
|
||||
#define SLJIT_ISDIVMOD (SLJIT_SDIVMOD | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: SLJIT_SDIV is single precision divide. */
|
||||
#define SLJIT_UDIVI (SLJIT_OP0_BASE + 6)
|
||||
#define SLJIT_IUDIVI (SLJIT_UDIVI | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
||||
The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
||||
Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
||||
Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
||||
the behaviour is undefined.
|
||||
Note: SLJIT_SDIV is single precision divide. */
|
||||
#define SLJIT_SDIVI (SLJIT_OP0_BASE + 7)
|
||||
#define SLJIT_ISDIVI (SLJIT_SDIVI | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
|
||||
|
||||
@ -851,34 +869,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index ( >=0 ) of any SLJIT_R,
|
||||
SLJIT_S and SLJIT_SP registers.
|
||||
|
||||
Note: it returns with -1 for virtual registers (only on x86-32). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index of any SLJIT_FLOAT register.
|
||||
|
||||
Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
|
||||
|
||||
/* Any instruction can be inserted into the instruction stream by
|
||||
sljit_emit_op_custom. It has a similar purpose as inline assembly.
|
||||
The size parameter must match to the instruction size of the target
|
||||
architecture:
|
||||
|
||||
x86: 0 < size <= 15. The instruction argument can be byte aligned.
|
||||
Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
|
||||
if size == 4, the instruction argument must be 4 byte aligned.
|
||||
Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size);
|
||||
|
||||
/* Returns with non-zero if fpu is available. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
|
||||
@ -1196,4 +1186,64 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct
|
||||
|
||||
#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* CPU specific functions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index ( >=0 ) of any SLJIT_R,
|
||||
SLJIT_S and SLJIT_SP registers.
|
||||
|
||||
Note: it returns with -1 for virtual registers (only on x86-32). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index of any SLJIT_FLOAT register.
|
||||
|
||||
Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
|
||||
|
||||
/* Any instruction can be inserted into the instruction stream by
|
||||
sljit_emit_op_custom. It has a similar purpose as inline assembly.
|
||||
The size parameter must match to the instruction size of the target
|
||||
architecture:
|
||||
|
||||
x86: 0 < size <= 15. The instruction argument can be byte aligned.
|
||||
Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
|
||||
if size == 4, the instruction argument must be 4 byte aligned.
|
||||
Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
|
||||
/* Returns with non-zero if sse2 is available. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void);
|
||||
|
||||
/* Returns with non-zero if cmov instruction is available. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void);
|
||||
|
||||
/* Emit a conditional mov instruction on x86 CPUs. This instruction
|
||||
moves src to destination, if the condition is satisfied. Unlike
|
||||
other arithmetic instructions, destination must be a register.
|
||||
Before such instructions are emitted, cmov support should be
|
||||
checked by sljit_x86_is_cmov_available function.
|
||||
type must be between SLJIT_EQUAL and SLJIT_S_ORDERED
|
||||
dst_reg must be a valid register and it can be combined
|
||||
with SLJIT_INT_OP to perform 32 bit arithmetic
|
||||
Flags: I - (never set any flags)
|
||||
*/
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler,
|
||||
sljit_si type,
|
||||
sljit_si dst_reg,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _SLJIT_LIR_H_ */
|
||||
|
@ -1833,18 +1833,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
| (reg_map[SLJIT_R0] << 8)
|
||||
| reg_map[TMP_REG1]);
|
||||
#endif
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
if (compiler->scratches >= 3)
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping);
|
||||
|
||||
if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) {
|
||||
FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */));
|
||||
FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */));
|
||||
}
|
||||
else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3))
|
||||
FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */));
|
||||
|
||||
#if defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
(op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
#error "Software divmod functions are needed"
|
||||
#endif
|
||||
if (compiler->scratches >= 3)
|
||||
return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */);
|
||||
|
||||
if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) {
|
||||
FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */));
|
||||
FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */));
|
||||
}
|
||||
else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3))
|
||||
return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1087,14 +1087,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
saved_regs_size += sizeof(sljit_sw);
|
||||
}
|
||||
local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
|
||||
FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
||||
if (saved_regs_size > 0)
|
||||
FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
||||
}
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
prev = -1;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1104,7 +1110,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
|
||||
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1112,8 +1123,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
if (prev != -1)
|
||||
FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
||||
SLJIT_ASSERT(prev == -1);
|
||||
|
||||
if (compiler->local_size > (63 * sizeof(sljit_sw))) {
|
||||
/* The local_size is already adjusted by the saved registers. */
|
||||
@ -1188,7 +1198,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
prev = -1;
|
||||
for (i = SLJIT_S0; i >= tmp; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1198,7 +1213,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
|
||||
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
||||
if (prev == -1) {
|
||||
prev = i;
|
||||
if (!(offs & (1 << 15))) {
|
||||
prev = i;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
||||
offs += 1 << 15;
|
||||
continue;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
||||
@ -1206,13 +1226,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
|
||||
prev = -1;
|
||||
}
|
||||
|
||||
if (prev != -1)
|
||||
FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
||||
SLJIT_ASSERT(prev == -1);
|
||||
|
||||
if (compiler->local_size <= (63 * sizeof(sljit_sw))) {
|
||||
FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
|
||||
| RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
|
||||
} else {
|
||||
} else if (saved_regs_size > 0) {
|
||||
FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
||||
}
|
||||
|
||||
@ -1242,12 +1261,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_LUDIV ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
||||
FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
||||
return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
@ -1239,6 +1239,9 @@ extern int __aeabi_idivmod(int numerator, int denominator);
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
||||
{
|
||||
sljit_sw saved_reg_list[3];
|
||||
sljit_sw saved_reg_count;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
|
||||
@ -1255,24 +1258,53 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
| (reg_map[SLJIT_R0] << 12)
|
||||
| (reg_map[SLJIT_R0] << 16)
|
||||
| reg_map[SLJIT_R1]);
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
if (compiler->scratches >= 4) {
|
||||
FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */));
|
||||
FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */));
|
||||
} else if (compiler->scratches >= 3)
|
||||
FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */));
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping);
|
||||
|
||||
saved_reg_count = 0;
|
||||
if (compiler->scratches >= 4)
|
||||
saved_reg_list[saved_reg_count++] = 12;
|
||||
if (compiler->scratches >= 3)
|
||||
saved_reg_list[saved_reg_count++] = 2;
|
||||
if (op >= SLJIT_UDIVI)
|
||||
saved_reg_list[saved_reg_count++] = 1;
|
||||
|
||||
if (saved_reg_count > 0) {
|
||||
FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8)
|
||||
| (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));
|
||||
if (saved_reg_count >= 2) {
|
||||
SLJIT_ASSERT(saved_reg_list[1] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */));
|
||||
}
|
||||
if (saved_reg_count >= 3) {
|
||||
SLJIT_ASSERT(saved_reg_list[2] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
(op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
#error "Software divmod functions are needed"
|
||||
#endif
|
||||
if (compiler->scratches >= 4) {
|
||||
FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */));
|
||||
return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */);
|
||||
} else if (compiler->scratches >= 3)
|
||||
return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */);
|
||||
|
||||
if (saved_reg_count > 0) {
|
||||
if (saved_reg_count >= 3) {
|
||||
SLJIT_ASSERT(saved_reg_list[2] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */));
|
||||
}
|
||||
if (saved_reg_count >= 2) {
|
||||
SLJIT_ASSERT(saved_reg_list[1] < 8);
|
||||
FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */));
|
||||
}
|
||||
return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)
|
||||
| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1053,8 +1053,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
#endif
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
case SLJIT_LUDIV:
|
||||
case SLJIT_LSDIV:
|
||||
case SLJIT_UDIVMOD:
|
||||
case SLJIT_SDIVMOD:
|
||||
case SLJIT_UDIVI:
|
||||
case SLJIT_SDIVI:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
||||
#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
@ -1062,15 +1065,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (int_op)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#else
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#endif
|
||||
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user