From ba82e18755098a7d303e8bc3a92cf57adcfc75dc Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Sat, 25 Jan 2020 12:22:01 +0100 Subject: [PATCH 01/80] Allow empty needle in mb_strrchr() --- ext/mbstring/mbstring.c | 7 ------- ext/mbstring/tests/mb_strrchr_empty_needle.phpt | 16 ++++++++-------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 1970febc5492e..de4ccfc4278de 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2266,13 +2266,6 @@ PHP_FUNCTION(mb_strrchr) RETURN_FALSE; } - if (haystack.len == 0) { - RETURN_FALSE; - } - if (needle.len == 0) { - RETURN_FALSE; - } - n = mbfl_strpos(&haystack, &needle, 0, 1); if (!mbfl_is_error(n)) { if (part) { diff --git a/ext/mbstring/tests/mb_strrchr_empty_needle.phpt b/ext/mbstring/tests/mb_strrchr_empty_needle.phpt index 1efacc90d23eb..642c9ca15f284 100644 --- a/ext/mbstring/tests/mb_strrchr_empty_needle.phpt +++ b/ext/mbstring/tests/mb_strrchr_empty_needle.phpt @@ -15,23 +15,23 @@ $string_ascii = 'abc def'; $string_mb = "日本語テキストです。0123456789。"; echo "\n-- ASCII string --\n"; -var_dump(bin2hex(mb_strrchr($string_ascii, '', false, 'ISO-8859-1'))); -var_dump(bin2hex(mb_strrchr($string_ascii, ''))); -var_dump(bin2hex(mb_strrchr($string_ascii, '', true))); +var_dump(mb_strrchr($string_ascii, '', false, 'ISO-8859-1')); +var_dump(mb_strrchr($string_ascii, '')); +var_dump(mb_strrchr($string_ascii, '', true)); echo "\n-- Multibyte string --\n"; -var_dump(bin2hex(mb_strrchr($string_mb, ''))); -var_dump(bin2hex(mb_strrchr($string_mb, '', false, 'utf-8'))); -var_dump(bin2hex(mb_strrchr($string_mb, '', true))); +var_dump(mb_strrchr($string_mb, '')); +var_dump(mb_strrchr($string_mb, '', false, 'utf-8')); +var_dump(mb_strrchr($string_mb, '', true)); ?> --EXPECT-- -- ASCII string -- string(0) "" string(0) "" -string(0) "" +string(7) "abc def" -- Multibyte string -- string(0) "" string(0) "" -string(0) "" +string(53) "日本語テキストです。0123456789。" From 300d4df65426522d5337bbfa0fe6b5d28a4387bc Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Sat, 25 Jan 2020 12:32:55 +0100 Subject: [PATCH 02/80] Add mention about empty needles for strrch() functions in UPGRADING [ci skip] --- UPGRADING | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/UPGRADING b/UPGRADING index 88241d9cc76d7..70b5585fcb8d8 100644 --- a/UPGRADING +++ b/UPGRADING @@ -217,8 +217,8 @@ PHP 8.0 UPGRADE NOTES . A non-string pattern argument to mb_ereg_replace() will now be interpreted as a string instead of an ASCII codepoint. The previous behavior may be restored with an explicit call to chr(). - . The needle argument for mb_strpos(), mb_strrpos(), mb_stripos(), mb_strripos(), mb_strstr() and mb_stristr() - can now be empty. + . The needle argument for mb_strpos(), mb_strrpos(), mb_stripos(), mb_strripos(), + mb_strstr(), mb_stristr(), mb_strrchr() and mb_strrichr() can now be empty. . The $is_hex parameter, which was not used internally, has been removed from mb_decode_numericentity(). . The legacy behaviour of passing the encoding as the third argument instead of an offset for the mb_strrpos @@ -286,7 +286,8 @@ PHP 8.0 UPGRADE NOTES string. Previously non-string needles were interpreted as an ASCII code point. An explicit call to chr() can be used to restore the previous behavior. - . The needle argument for strpos(), strrpos(), stripos(), strripos(), strstr() and stristr() can now be empty. + . The needle argument for strpos(), strrpos(), stripos(), strripos(), strstr(), + stristr() and strrchr() can now be empty. . The length argument for substr(), substr_count(), substr_compare(), and iconv_substr() can now be null. Null values will behave as if no length argument was provided and will therefore return the remainder of the string From a1f2f8f06e1a40a77c22861c266377c790c3f26b Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Sat, 25 Jan 2020 13:23:51 +0100 Subject: [PATCH 03/80] Fixed bug #79080 [ci skip] Rewrote session.gc_probability and session.gc_divisor INI setting description to be more succint. --- php.ini-development | 19 ++++++------------- php.ini-production | 19 ++++++------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/php.ini-development b/php.ini-development index 97e1657a7c57e..a2167e8395c6d 100644 --- a/php.ini-development +++ b/php.ini-development @@ -1421,12 +1421,9 @@ session.cookie_samesite = ; http://php.net/session.serialize-handler session.serialize_handler = php -; Defines the probability that the 'garbage collection' process is started -; on every session initialization. The probability is calculated by using -; gc_probability/gc_divisor. Where session.gc_probability is the numerator -; and gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any given request. +; Defines the probability that the 'garbage collection' process is started on every +; session initialization. The probability is calculated by using gc_probability/gc_divisor, +; e.g. 1/100 means there is a 1% chance that the GC process starts on each request. ; Default Value: 1 ; Development Value: 1 ; Production Value: 1 @@ -1434,13 +1431,9 @@ session.serialize_handler = php session.gc_probability = 1 ; Defines the probability that the 'garbage collection' process is started on every -; session initialization. The probability is calculated by using the following equation: -; gc_probability/gc_divisor. Where session.gc_probability is the numerator and -; session.gc_divisor is the denominator in the equation. Setting this value to 100 -; when the session.gc_probability value is 1 will give you approximately a 1% chance -; the gc will run on any given request. Increasing this value to 1000 will give you -; a 0.1% chance the gc will run on any given request. For high volume production servers, -; this is a more efficient approach. +; session initialization. The probability is calculated by using gc_probability/gc_divisor, +; e.g. 1/100 means there is a 1% chance that the GC process starts on each request. +; For high volume production servers, using a value of 1000 is a more efficient approach. ; Default Value: 100 ; Development Value: 1000 ; Production Value: 1000 diff --git a/php.ini-production b/php.ini-production index c4f9a7121fe35..3459193941b73 100644 --- a/php.ini-production +++ b/php.ini-production @@ -1423,12 +1423,9 @@ session.cookie_samesite = ; http://php.net/session.serialize-handler session.serialize_handler = php -; Defines the probability that the 'garbage collection' process is started -; on every session initialization. The probability is calculated by using -; gc_probability/gc_divisor. Where session.gc_probability is the numerator -; and gc_divisor is the denominator in the equation. Setting this value to 1 -; when the session.gc_divisor value is 100 will give you approximately a 1% chance -; the gc will run on any given request. +; Defines the probability that the 'garbage collection' process is started on every +; session initialization. The probability is calculated by using gc_probability/gc_divisor, +; e.g. 1/100 means there is a 1% chance that the GC process starts on each request. ; Default Value: 1 ; Development Value: 1 ; Production Value: 1 @@ -1436,13 +1433,9 @@ session.serialize_handler = php session.gc_probability = 1 ; Defines the probability that the 'garbage collection' process is started on every -; session initialization. The probability is calculated by using the following equation: -; gc_probability/gc_divisor. Where session.gc_probability is the numerator and -; session.gc_divisor is the denominator in the equation. Setting this value to 100 -; when the session.gc_probability value is 1 will give you approximately a 1% chance -; the gc will run on any given request. Increasing this value to 1000 will give you -; a 0.1% chance the gc will run on any given request. For high volume production servers, -; this is a more efficient approach. +; session initialization. The probability is calculated by using gc_probability/gc_divisor, +; e.g. 1/100 means there is a 1% chance that the GC process starts on each request. +; For high volume production servers, using a value of 1000 is a more efficient approach. ; Default Value: 100 ; Development Value: 1000 ; Production Value: 1000 From 52d07834df3ebd3720fd4f7d0a6eb11c52d33fb1 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 21 Jan 2020 20:22:40 +0100 Subject: [PATCH 04/80] Upgrade bundled PCRE2 to 10.34 --- ext/pcre/pcre2lib/pcre2.h | 19 +- ext/pcre/pcre2lib/pcre2_auto_possess.c | 7 + ext/pcre/pcre2lib/pcre2_compile.c | 535 +- ext/pcre/pcre2lib/pcre2_context.c | 2 +- ext/pcre/pcre2lib/pcre2_dfa_match.c | 129 +- ext/pcre/pcre2lib/pcre2_error.c | 3 + ext/pcre/pcre2lib/pcre2_internal.h | 105 +- ext/pcre/pcre2lib/pcre2_intmodedep.h | 10 +- ext/pcre/pcre2lib/pcre2_jit_compile.c | 2003 +++--- ext/pcre/pcre2lib/pcre2_jit_match.c | 1 - ext/pcre/pcre2lib/pcre2_jit_neon_inc.h | 321 + ext/pcre/pcre2lib/pcre2_jit_simd_inc.h | 993 +++ ext/pcre/pcre2lib/pcre2_maketables.c | 11 + ext/pcre/pcre2lib/pcre2_match.c | 603 +- ext/pcre/pcre2lib/pcre2_match_data.c | 15 +- ext/pcre/pcre2lib/pcre2_printint.c | 2 + ext/pcre/pcre2lib/pcre2_study.c | 306 +- ext/pcre/pcre2lib/pcre2_tables.c | 316 +- ext/pcre/pcre2lib/pcre2_ucd.c | 5623 +++++++++-------- ext/pcre/pcre2lib/pcre2_ucp.h | 7 +- ext/pcre/pcre2lib/sljit/sljitConfigInternal.h | 4 + ext/pcre/pcre2lib/sljit/sljitExecAllocator.c | 31 +- ext/pcre/pcre2lib/sljit/sljitLir.c | 71 +- ext/pcre/pcre2lib/sljit/sljitLir.h | 22 +- ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c | 126 +- ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c | 111 +- .../pcre2lib/sljit/sljitNativeARM_T2_32.c | 76 +- ext/pcre/pcre2lib/sljit/sljitNativeMIPS_32.c | 2 + .../pcre2lib/sljit/sljitNativeMIPS_common.c | 155 +- ext/pcre/pcre2lib/sljit/sljitNativePPC_32.c | 2 + ext/pcre/pcre2lib/sljit/sljitNativePPC_64.c | 3 - .../pcre2lib/sljit/sljitNativePPC_common.c | 214 +- ext/pcre/pcre2lib/sljit/sljitNativeSPARC_32.c | 2 + .../pcre2lib/sljit/sljitNativeSPARC_common.c | 102 +- .../pcre2lib/sljit/sljitNativeTILEGX_64.c | 8 +- ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c | 4 +- ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c | 54 +- .../pcre2lib/sljit/sljitNativeX86_common.c | 125 +- ext/pcre/pcre2lib/sljit/sljitUtils.c | 10 +- 39 files changed, 7417 insertions(+), 4716 deletions(-) create mode 100644 ext/pcre/pcre2lib/pcre2_jit_neon_inc.h create mode 100644 ext/pcre/pcre2lib/pcre2_jit_simd_inc.h diff --git a/ext/pcre/pcre2lib/pcre2.h b/ext/pcre/pcre2lib/pcre2.h index 102b5d91f1adf..cb9d61a35b14e 100644 --- a/ext/pcre/pcre2lib/pcre2.h +++ b/ext/pcre/pcre2lib/pcre2.h @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, second API, to be #included by applications that call PCRE2 functions. - Copyright (c) 2016-2018 University of Cambridge + Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 33 +#define PCRE2_MINOR 34 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2019-04-16 +#define PCRE2_DATE 2019-11-21 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -142,6 +142,7 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */ #define PCRE2_EXTENDED_MORE 0x01000000u /* C */ #define PCRE2_LITERAL 0x02000000u /* C */ +#define PCRE2_MATCH_INVALID_UTF 0x04000000u /* J M D */ /* An additional compile options word is available in the compile context. */ @@ -305,6 +306,8 @@ pcre2_pattern_convert(). */ #define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS 194 #define PCRE2_ERROR_ALPHA_ASSERTION_UNKNOWN 195 #define PCRE2_ERROR_SCRIPT_RUN_NOT_AVAILABLE 196 +#define PCRE2_ERROR_TOO_MANY_CAPTURES 197 +#define PCRE2_ERROR_CONDITION_ATOMIC_ASSERTION_EXPECTED 198 /* "Expected" matching error codes: no match and partial match. */ @@ -390,6 +393,7 @@ released, the numbers must not be changed. */ #define PCRE2_ERROR_HEAPLIMIT (-63) #define PCRE2_ERROR_CONVERT_SYNTAX (-64) #define PCRE2_ERROR_INTERNAL_DUPMATCH (-65) +#define PCRE2_ERROR_DFA_UINVALID_UTF (-66) /* Request types for pcre2_pattern_info() */ @@ -580,7 +584,7 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_bsr(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ - pcre2_set_character_tables(pcre2_compile_context *, const unsigned char *); \ + pcre2_set_character_tables(pcre2_compile_context *, const uint8_t *); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ @@ -675,6 +679,8 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ pcre2_match_data_free(pcre2_match_data *); \ PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \ pcre2_get_mark(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \ + pcre2_get_match_data_size(pcre2_match_data *); \ PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \ pcre2_get_ovector_count(pcre2_match_data *); \ PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \ @@ -773,7 +779,8 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \ PCRE2_EXP_DECL const uint8_t PCRE2_CALL_CONVENTION \ *pcre2_maketables(pcre2_general_context *); \ - +PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ + pcre2_maketables_free(pcre2_general_context *, const uint8_t *); /* Define macros that generate width-specific names from generic versions. The three-level macro scheme is necessary to get the macros expanded when we want @@ -838,6 +845,7 @@ pcre2_compile are called by application code. */ #define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_) #define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_) #define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_) +#define pcre2_get_match_data_size PCRE2_SUFFIX(pcre2_get_match_data_size_) #define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_) #define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_) #define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_) @@ -848,6 +856,7 @@ pcre2_compile are called by application code. */ #define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_) #define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_) #define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_) +#define pcre2_maketables_free PCRE2_SUFFIX(pcre2_maketables_free_) #define pcre2_match PCRE2_SUFFIX(pcre2_match_) #define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_) #define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_) diff --git a/ext/pcre/pcre2lib/pcre2_auto_possess.c b/ext/pcre/pcre2lib/pcre2_auto_possess.c index 6d7b7c4a4d979..5b95b9b8a8b05 100644 --- a/ext/pcre/pcre2lib/pcre2_auto_possess.c +++ b/ext/pcre/pcre2lib/pcre2_auto_possess.c @@ -624,6 +624,13 @@ for(;;) case OP_ASSERTBACK_NOT: case OP_ONCE: return !entered_a_group; + + /* Non-atomic assertions - don't possessify last iterator. This needs + more thought. */ + + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: + return FALSE; } /* Skip over the bracket and inspect what comes next. */ diff --git a/ext/pcre/pcre2lib/pcre2_compile.c b/ext/pcre/pcre2lib/pcre2_compile.c index 068735ae8eed6..f2e6b6b5bde42 100644 --- a/ext/pcre/pcre2lib/pcre2_compile.c +++ b/ext/pcre/pcre2lib/pcre2_compile.c @@ -135,6 +135,9 @@ static BOOL set_lookbehind_lengths(uint32_t **, int *, int *, parsed_recurse_check *, compile_block *); +static int + check_lookbehinds(uint32_t *, uint32_t **, parsed_recurse_check *, + compile_block *); /************************************************* @@ -250,36 +253,41 @@ is present where expected in a conditional group. */ #define META_LOOKBEHIND 0x80250000u /* (?<= */ #define META_LOOKBEHINDNOT 0x80260000u /* (? META_END. A macros encapsulates -the storing of literal values in the parsed pattern. */ +/* Only in 32-bit mode can there be literals > META_END. A macro encapsulates +the storing of literal values in the main parsed pattern, where they can always +be quantified. */ #if PCRE2_CODE_UNIT_WIDTH == 32 #define PARSED_LITERAL(c, p) \ @@ -2474,6 +2497,7 @@ uint32_t delimiter; uint32_t namelen; uint32_t class_range_state; uint32_t *verblengthptr = NULL; /* Value avoids compiler warning */ +uint32_t *verbstartptr = NULL; uint32_t *previous_callout = NULL; uint32_t *parsed_pattern = cb->parsed_pattern; uint32_t *parsed_pattern_end = cb->parsed_pattern_end; @@ -2600,10 +2624,20 @@ while (ptr < ptrend) errorcode = ERR28; goto FAILED; } - if (!inverbname && after_manual_callout-- <= 0) - parsed_pattern = manage_callouts(thisptr, &previous_callout, - auto_callout, parsed_pattern, cb); - PARSED_LITERAL(c, parsed_pattern); + if (inverbname) + { /* Don't use PARSED_LITERAL() because it */ +#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */ + if (c >= META_END) *parsed_pattern++ = META_BIGVALUE; +#endif + *parsed_pattern++ = c; + } + else + { + if (after_manual_callout-- <= 0) + parsed_pattern = manage_callouts(thisptr, &previous_callout, + auto_callout, parsed_pattern, cb); + PARSED_LITERAL(c, parsed_pattern); + } meta_quantifier = 0; } continue; /* Next character */ @@ -2640,13 +2674,15 @@ while (ptr < ptrend) switch(c) { - default: - PARSED_LITERAL(c, parsed_pattern); + default: /* Don't use PARSED_LITERAL() because it */ +#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */ + if (c >= META_END) *parsed_pattern++ = META_BIGVALUE; +#endif + *parsed_pattern++ = c; break; case CHAR_RIGHT_PARENTHESIS: inverbname = FALSE; - okquantifier = FALSE; /* Was probably set by literals */ /* This is the length in characters */ verbnamelength = (PCRE2_SIZE)(parsed_pattern - verblengthptr - 1); /* But the limit on the length is in code units */ @@ -2680,8 +2716,11 @@ while (ptr < ptrend) switch(escape) { - case 0: - PARSED_LITERAL(c, parsed_pattern); + case 0: /* Don't use PARSED_LITERAL() because it */ +#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */ + if (c >= META_END) *parsed_pattern++ = META_BIGVALUE; +#endif + *parsed_pattern++ = c; break; case ESC_Q: @@ -3135,6 +3174,21 @@ while (ptr < ptrend) goto FAILED_BACK; } + /* Most (*VERB)s are not allowed to be quantified, but an ungreedy + quantifier can be useful for (*ACCEPT) - meaning "succeed on backtrack", a + sort of negated (*COMMIT). We therefore allow (*ACCEPT) to be quantified by + wrapping it in non-capturing brackets, but we have to allow for a preceding + (*MARK) for when (*ACCEPT) has an argument. */ + + if (parsed_pattern[-1] == META_ACCEPT) + { + uint32_t *p; + for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0]; + *verbstartptr = META_NOCAPTURE; + parsed_pattern[1] = META_KET; + parsed_pattern += 2; + } + /* Now we can put the quantifier into the parsed pattern vector. At this stage, we have only the basic quantifier. The check for a following + or ? modifier happens at the top of the loop, after any intervening comments @@ -3581,6 +3635,8 @@ while (ptr < ptrend) if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break; } /* End of class-processing loop */ + /* -] at the end of a class is a literal '-' */ + if (class_range_state == RANGE_STARTED) { parsed_pattern[-1] = CHAR_MINUS; @@ -3611,6 +3667,11 @@ while (ptr < ptrend) nest_depth++; if ((options & PCRE2_NO_AUTO_CAPTURE) == 0) { + if (cb->bracount >= MAX_GROUP_NUMBER) + { + errorcode = ERR97; + goto FAILED; + } cb->bracount++; *parsed_pattern++ = META_CAPTURE | cb->bracount; } @@ -3658,19 +3719,20 @@ while (ptr < ptrend) goto FAILED; } - /* Check for expecting an assertion condition. If so, only lookaround - assertions are valid. */ + /* Check for expecting an assertion condition. If so, only atomic + lookaround assertions are valid. */ meta = alasmeta[i].meta; if (prev_expect_cond_assert > 0 && (meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT)) { - errorcode = ERR28; /* Assertion expected */ + errorcode = (meta == META_LOOKAHEAD_NA || meta == META_LOOKBEHIND_NA)? + ERR98 : ERR28; /* (Atomic) assertion expected */ goto FAILED; } - /* The lookaround alphabetic synonyms can be almost entirely handled by - jumping to the code that handles the traditional symbolic forms. */ + /* The lookaround alphabetic synonyms can mostly be handled by jumping + to the code that handles the traditional symbolic forms. */ switch(meta) { @@ -3684,11 +3746,17 @@ while (ptr < ptrend) case META_LOOKAHEAD: goto POSITIVE_LOOK_AHEAD; + case META_LOOKAHEAD_NA: + *parsed_pattern++ = meta; + ptr++; + goto POST_ASSERTION; + case META_LOOKAHEADNOT: goto NEGATIVE_LOOK_AHEAD; case META_LOOKBEHIND: case META_LOOKBEHINDNOT: + case META_LOOKBEHIND_NA: *parsed_pattern++ = meta; ptr--; goto POST_LOOKBEHIND; @@ -3770,6 +3838,12 @@ while (ptr < ptrend) goto FAILED; } + /* Remember where this verb, possibly with a preceding (*MARK), starts, + for handling quantified (*ACCEPT). */ + + verbstartptr = parsed_pattern; + okquantifier = (verbs[i].meta == META_ACCEPT); + /* It appears that Perl allows any characters whatsoever, other than a closing parenthesis, to appear in arguments ("names"), so we no longer insist on letters, digits, and underscores. Perl does not, however, do @@ -4386,7 +4460,7 @@ while (ptr < ptrend) *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)? META_LOOKBEHIND : META_LOOKBEHINDNOT; - POST_LOOKBEHIND: /* Come from (*plb: and (*nlb: */ + POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */ *has_lookbehind = TRUE; offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2); PUTOFFSET(offset, parsed_pattern); @@ -4435,6 +4509,11 @@ while (ptr < ptrend) /* We have a name for this capturing group. It is also assigned a number, which is its primary means of identification. */ + if (cb->bracount >= MAX_GROUP_NUMBER) + { + errorcode = ERR97; + goto FAILED; + } cb->bracount++; *parsed_pattern++ = META_CAPTURE | cb->bracount; nest_depth++; @@ -4661,6 +4740,7 @@ for (;;) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERTBACK_NA: if (!skipassert) return code; do code += GET(code, 1); while (*code == OP_ALT); code += PRIV(OP_lengths)[*code]; @@ -5221,8 +5301,10 @@ PCRE2_UCHAR *tempcode; PCRE2_UCHAR *previous = NULL; PCRE2_UCHAR op_previous; BOOL groupsetfirstcu = FALSE; +BOOL had_accept = FALSE; BOOL matched_char = FALSE; BOOL previous_matched_char = FALSE; +BOOL reset_caseful = FALSE; const uint8_t *cbits = cb->cbits; uint8_t classbits[32]; @@ -5355,7 +5437,7 @@ for (;; pptr++) if (meta < META_ASTERISK || meta > META_MINMAX_QUERY) { previous = code; - if (matched_char) okreturn = 1; + if (matched_char && !had_accept) okreturn = 1; } previous_matched_char = matched_char; @@ -5499,7 +5581,45 @@ for (;; pptr++) } /* End of 1-char optimization */ /* Handle character classes that contain more than just one literal - character. */ + character. If there are exactly two characters in a positive class, see if + they are case partners. This can be optimized to generate a caseless single + character match (which also sets first/required code units if relevant). */ + + if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END && + pptr[3] == META_CLASS_END) + { + uint32_t c = pptr[1]; + +#ifdef SUPPORT_UNICODE + if (UCD_CASESET(c) == 0) +#endif + { + uint32_t d; + +#ifdef SUPPORT_UNICODE + if (utf && c > 127) d = UCD_OTHERCASE(c); else +#endif + { +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (c > 255) d = c; else +#endif + d = TABLE_GET(c, cb->fcc, c); + } + + if (c != d && pptr[2] == d) + { + pptr += 3; /* Move on to class end */ + meta = c; + if ((options & PCRE2_CASELESS) == 0) + { + reset_caseful = TRUE; + options |= PCRE2_CASELESS; + req_caseopt = REQ_CASELESS; + } + goto CLASS_CASELESS_CHAR; + } + } + } /* If a non-extended class contains a negative special such as \S, we need to flip the negation flag at the end, so that support for characters > 255 @@ -5994,7 +6114,7 @@ for (;; pptr++) workspace overflow. Do not set firstcu after *ACCEPT. */ case META_ACCEPT: - cb->had_accept = TRUE; + cb->had_accept = had_accept = TRUE; for (oc = cb->open_caps; oc != NULL && oc->assert_depth >= cb->assert_depth; oc = oc->next) @@ -6252,6 +6372,11 @@ for (;; pptr++) cb->assert_depth += 1; goto GROUP_PROCESS; + case META_LOOKAHEAD_NA: + bravalue = OP_ASSERT_NA; + cb->assert_depth += 1; + goto GROUP_PROCESS; + /* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird thing to do, but Perl allows all assertions to be quantified, and when they contain capturing parentheses there may be a potential use for @@ -6283,6 +6408,11 @@ for (;; pptr++) cb->assert_depth += 1; goto GROUP_PROCESS; + case META_LOOKBEHIND_NA: + bravalue = OP_ASSERTBACK_NA; + cb->assert_depth += 1; + goto GROUP_PROCESS; + case META_ATOMIC: bravalue = OP_ONCE; goto GROUP_PROCESS_NOTE_EMPTY; @@ -6341,7 +6471,7 @@ for (;; pptr++) /* If we've just compiled an assertion, pop the assert depth. */ - if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT) + if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NA) cb->assert_depth -= 1; /* At the end of compiling, code is still pointing to the start of the @@ -6491,8 +6621,8 @@ for (;; pptr++) we must only take the reqcu when the group also set a firstcu. Otherwise, in that example, 'X' ends up set for both. */ - else if (bravalue == OP_ASSERT && subreqcuflags >= 0 && - subfirstcuflags >= 0) + else if ((bravalue == OP_ASSERT || bravalue == OP_ASSERT_NA) && + subreqcuflags >= 0 && subfirstcuflags >= 0) { reqcu = subreqcu; reqcuflags = subreqcuflags; @@ -6713,10 +6843,6 @@ for (;; pptr++) reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; op_type = 0; - /* If the repeat is {1} we can ignore it. */ - - if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT; - /* Adjust first and required code units for a zero repeat. */ if (repeat_min == 0) @@ -6759,7 +6885,10 @@ for (;; pptr++) tempcode = previous; op_previous = *previous; - /* Now handle repetition for the different types of item. */ + /* Now handle repetition for the different types of item. If the repeat + minimum and the repeat maximum are both 1, we can ignore the quantifier for + non-parenthesized items, as they have only one alternative. For anything in + parentheses, we must not ignore if {1} is possessive. */ switch (op_previous) { @@ -6773,6 +6902,7 @@ for (;; pptr++) case OP_CHARI: case OP_NOT: case OP_NOTI: + if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT; op_type = chartypeoffset[op_previous - OP_CHAR]; /* Deal with UTF characters that take up more than one code unit. */ @@ -6819,6 +6949,7 @@ for (;; pptr++) code = previous; goto END_REPEAT; } + if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT; if (repeat_min == 0 && repeat_max == REPEAT_UNLIMITED) *code++ = OP_CRSTAR + repeat_type; @@ -6853,6 +6984,8 @@ for (;; pptr++) repetition. */ case OP_RECURSE: + if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier) + goto END_REPEAT; /* Generate unwrapped repeats for a non-zero minimum, except when the minimum is 1 and the maximum unlimited, because that can be handled with @@ -6923,8 +7056,10 @@ for (;; pptr++) case OP_ASSERT: case OP_ASSERT_NOT: + case OP_ASSERT_NA: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRA: @@ -6935,6 +7070,9 @@ for (;; pptr++) PCRE2_UCHAR *bralink = NULL; PCRE2_UCHAR *brazeroptr = NULL; + if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier) + goto END_REPEAT; + /* Repeating a DEFINE group (or any group where the condition is always FALSE and there is only one branch) is pointless, but Perl allows the syntax, so we just ignore the repeat. */ @@ -7151,11 +7289,12 @@ for (;; pptr++) and SCRIPT_RUN groups at runtime, but in a different way.] Then, if the quantifier was possessive and the bracket is not a - conditional, we convert the BRA code to the POS form, and the KET code to - KETRPOS. (It turns out to be convenient at runtime to detect this kind of - subpattern at both the start and at the end.) The use of special opcodes - makes it possible to reduce greatly the stack usage in pcre2_match(). If - the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO. + conditional, we convert the BRA code to the POS form, and the KET code + to KETRPOS. (It turns out to be convenient at runtime to detect this + kind of subpattern at both the start and at the end.) The use of + special opcodes makes it possible to reduce greatly the stack usage in + pcre2_match(). If the group is preceded by OP_BRAZERO, convert this to + OP_BRAPOSZERO. Then, if the minimum number of matches is 1 or 0, cancel the possessive flag so that the default action below, of wrapping everything inside @@ -7256,6 +7395,8 @@ for (;; pptr++) int prop_type, prop_value; PCRE2_UCHAR *oldcode; + if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT; + op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ mclength = 0; /* Not a character */ @@ -7718,9 +7859,15 @@ for (;; pptr++) } #endif - /* Caseful matches, or not one of the multicase characters. Get the - character's code units into mcbuffer, with the length in mclength. When not - in UTF mode, the length is always 1. */ + /* Caseful matches, or caseless and not one of the multicase characters. We + come here by goto in the case of a positive class that contains only + case-partners of a character with just two cases; matched_char has already + been set TRUE and options fudged if necessary. */ + + CLASS_CASELESS_CHAR: + + /* Get the character's code units into mcbuffer, with the length in + mclength. When not in UTF mode, the length is always 1. */ #ifdef SUPPORT_UNICODE if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else @@ -7752,8 +7899,9 @@ for (;; pptr++) zeroreqcu = reqcu; zeroreqcuflags = reqcuflags; - /* If the character is more than one code unit long, we can set firstcu - only if it is not to be matched caselessly. */ + /* If the character is more than one code unit long, we can set a single + firstcu only if it is not to be matched caselessly. Multiple possible + starting code units may be picked up later in the studying code. */ if (mclength == 1 || req_caseopt == 0) { @@ -7783,7 +7931,17 @@ for (;; pptr++) reqcuflags = req_caseopt | cb->req_varyopt; } } - break; /* End default meta handling */ + + /* If caselessness was temporarily instated, reset it. */ + + if (reset_caseful) + { + options &= ~PCRE2_CASELESS; + req_caseopt = 0; + reset_caseful = FALSE; + } + + break; /* End literal character handling */ } /* End of big switch */ } /* End of big loop */ @@ -7874,7 +8032,10 @@ length = 2 + 2*LINK_SIZE + skipunits; /* Remember if this is a lookbehind assertion, and if it is, save its length and skip over the pattern offset. */ -lookbehind = *code == OP_ASSERTBACK || *code == OP_ASSERTBACK_NOT; +lookbehind = *code == OP_ASSERTBACK || + *code == OP_ASSERTBACK_NOT || + *code == OP_ASSERTBACK_NA; + if (lookbehind) { lookbehindlength = META_DATA(pptr[-1]); @@ -7948,7 +8109,7 @@ for (;;) /* If this is not the first branch, the first char and reqcu have to match the values from all the previous branches, except that if the previous value for reqcu didn't have REQ_VARY set, it can still match, - and we set REQ_VARY for the regex. */ + and we set REQ_VARY for the group from this branch's value. */ else { @@ -7987,7 +8148,7 @@ for (;;) else { reqcu = branchreqcu; - reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY */ + reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY if present */ } } } @@ -8167,7 +8328,7 @@ do { /* Positive forward assertion */ - else if (op == OP_ASSERT) + else if (op == OP_ASSERT || op == OP_ASSERT_NA) { if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; } @@ -8305,7 +8466,7 @@ do { /* Positive forward assertions */ - else if (op == OP_ASSERT) + else if (op == OP_ASSERT || op == OP_ASSERT_NA) { if (!is_startline(scode, bracket_map, cb, atomcount, TRUE)) return FALSE; @@ -8547,9 +8708,11 @@ do { case OP_CBRAPOS: case OP_SCBRAPOS: case OP_ASSERT: + case OP_ASSERT_NA: case OP_ONCE: case OP_SCRIPT_RUN: - d = find_firstassertedcu(scode, &dflags, inassert + ((op==OP_ASSERT)?1:0)); + d = find_firstassertedcu(scode, &dflags, inassert + + ((op == OP_ASSERT || op == OP_ASSERT_NA)?1:0)); if (dflags < 0) return 0; if (cflags < 0) { c = d; cflags = dflags; } @@ -8578,6 +8741,19 @@ do { case OP_MINPLUSI: case OP_POSPLUSI: if (inassert == 0) return 0; + + /* If the character is more than one code unit long, we cannot set its + first code unit when matching caselessly. Later scanning may pick up + multiple code units. */ + +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (scode[1] >= 0x80) return 0; +#elif PCRE2_CODE_UNIT_WIDTH == 16 + if (scode[1] >= 0xd800 && scode[1] <= 0xdfff) return 0; +#endif +#endif + if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; } else if (c != scode[1]) return 0; break; @@ -8745,8 +8921,10 @@ for (;; pptr++) case META_COND_VERSION: case META_LOOKAHEAD: case META_LOOKAHEADNOT: + case META_LOOKAHEAD_NA: case META_LOOKBEHIND: case META_LOOKBEHINDNOT: + case META_LOOKBEHIND_NA: case META_NOCAPTURE: case META_SCRIPT_RUN: nestlevel++; @@ -8798,7 +8976,7 @@ Returns: the group length or a negative number static int get_grouplength(uint32_t **pptrptr, BOOL isinline, int *errcodeptr, int *lcptr, - int group, parsed_recurse_check *recurses, compile_block *cb) + int group, parsed_recurse_check *recurses, compile_block *cb) { int branchlength; int grouplength = -1; @@ -8847,8 +9025,7 @@ return -1; *************************************************/ /* Return a fixed length for a branch in a lookbehind, giving an error if the -length is not fixed. If any lookbehinds are encountered on the way, they get -their length set. On entry, *pptrptr points to the first element inside the +length is not fixed. On entry, *pptrptr points to the first element inside the branch. On exit it is set to point to the ALT or KET. Arguments: @@ -8978,15 +9155,16 @@ for (;; pptr++) } break; - /* Lookaheads can be ignored, but we must start the skip inside the group - so that it isn't treated as a group within the branch. */ + /* Lookaheads do not contribute to the length of this branch, but they may + contain lookbehinds within them whose lengths need to be set. */ case META_LOOKAHEAD: case META_LOOKAHEADNOT: - pptr = parsed_skip(pptr + 1, PSKIP_KET); - if (pptr == NULL) goto PARSED_SKIP_FAILED; + case META_LOOKAHEAD_NA: + *errcodeptr = check_lookbehinds(pptr + 1, &pptr, recurses, cb); + if (*errcodeptr != 0) return -1; - /* Also ignore any qualifiers that follow a lookahead assertion. */ + /* Ignore any qualifiers that follow a lookahead assertion. */ switch (pptr[1]) { @@ -9013,10 +9191,12 @@ for (;; pptr++) } break; - /* Lookbehinds can be ignored, but must themselves be checked. */ + /* A nested lookbehind does not contribute any length to this lookbehind, + but must itself be checked and have its lengths set. */ case META_LOOKBEHIND: case META_LOOKBEHINDNOT: + case META_LOOKBEHIND_NA: if (!set_lookbehind_lengths(&pptr, errcodeptr, lcptr, recurses, cb)) return -1; break; @@ -9178,8 +9358,26 @@ for (;; pptr++) case META_MINMAX_QUERY: if (pptr[1] == pptr[2]) { - if (pptr[1] == 0) branchlength -= lastitemlength; - else itemlength = (pptr[1] - 1) * lastitemlength; + switch(pptr[1]) + { + case 0: + branchlength -= lastitemlength; + break; + + case 1: + itemlength = 0; + break; + + default: /* Check for integer overflow */ + if (lastitemlength != 0 && /* Should not occur, but just in case */ + INT_MAX/lastitemlength < pptr[1] - 1) + { + *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */ + return -1; + } + itemlength = (pptr[1] - 1) * lastitemlength; + break; + } pptr += 2; break; } @@ -9193,24 +9391,23 @@ for (;; pptr++) return -1; } - /* Add the item length to the branchlength, and save it for use if the next - thing is a quantifier. */ - - branchlength += itemlength; - lastitemlength = itemlength; - - /* Ensure that the length does not overflow the limit. */ + /* Add the item length to the branchlength, checking for integer overflow and + for the branch length exceeding the limit. */ - if (branchlength > LOOKBEHIND_MAX) + if (INT_MAX - branchlength < (int)itemlength || + (branchlength += itemlength) > LOOKBEHIND_MAX) { *errcodeptr = ERR87; return -1; } + + /* Save this item length for use if the next item is a quantifier. */ + + lastitemlength = itemlength; } EXIT: *pptrptr = pptr; -if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength; return branchlength; PARSED_SKIP_FAILED: @@ -9229,6 +9426,11 @@ branches. An error occurs if any branch does not have a fixed length that is less than the maximum (65535). On exit, the pointer must be left on the final ket. +The function also maintains the max_lookbehind value. Any lookbehind branch +that contains a nested lookbehind may actually look further back than the +length of the branch. The additional amount is passed back from +get_branchlength() as an "extra" value. + Arguments: pptrptr pointer to pointer in the parsed pattern errcodeptr pointer to error code @@ -9262,6 +9464,7 @@ do if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset; return FALSE; } + if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength; *bptr |= branchlength; /* branchlength never more than 65535 */ bptr = *pptrptr; } @@ -9282,20 +9485,30 @@ set_lookbehind_lengths() for each one. At the start, the errorcode is zero and the error offset is marked unset. The enables the functions above not to override settings from deeper nestings. -Arguments cb points to the compile block -Returns: 0 on success, or an errorcode (cb->erroroffset will be set) +This function is called recursively from get_branchlength() for lookaheads in +order to process any lookbehinds that they may contain. It stops when it hits a +non-nested closing parenthesis in this case, returning a pointer to it. + +Arguments + pptr points to where to start (start of pattern or start of lookahead) + retptr if not NULL, return the ket pointer here + recurses chain of recurse_check to catch mutual recursion + cb points to the compile block + +Returns: 0 on success, or an errorcode (cb->erroroffset will be set) */ static int -check_lookbehinds(compile_block *cb) +check_lookbehinds(uint32_t *pptr, uint32_t **retptr, + parsed_recurse_check *recurses, compile_block *cb) { -uint32_t *pptr; int errorcode = 0; int loopcount = 0; +int nestlevel = 0; cb->erroroffset = PCRE2_UNSET; -for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) +for (; *pptr != META_END; pptr++) { if (*pptr < META_END) continue; /* Literal */ @@ -9309,14 +9522,31 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) pptr += 1; break; + case META_KET: + if (--nestlevel < 0) + { + if (retptr != NULL) *retptr = pptr; + return 0; + } + break; + + case META_ATOMIC: + case META_CAPTURE: + case META_COND_ASSERT: + case META_LOOKAHEAD: + case META_LOOKAHEADNOT: + case META_LOOKAHEAD_NA: + case META_NOCAPTURE: + case META_SCRIPT_RUN: + nestlevel++; + break; + case META_ACCEPT: case META_ALT: case META_ASTERISK: case META_ASTERISK_PLUS: case META_ASTERISK_QUERY: - case META_ATOMIC: case META_BACKREF: - case META_CAPTURE: case META_CIRCUMFLEX: case META_CLASS: case META_CLASS_EMPTY: @@ -9324,14 +9554,9 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) case META_CLASS_END: case META_CLASS_NOT: case META_COMMIT: - case META_COND_ASSERT: case META_DOLLAR: case META_DOT: case META_FAIL: - case META_KET: - case META_LOOKAHEAD: - case META_LOOKAHEADNOT: - case META_NOCAPTURE: case META_PLUS: case META_PLUS_PLUS: case META_PLUS_QUERY: @@ -9341,7 +9566,6 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) case META_QUERY_QUERY: case META_RANGE_ESCAPED: case META_RANGE_LITERAL: - case META_SCRIPT_RUN: case META_SKIP: case META_THEN: break; @@ -9351,13 +9575,22 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) break; case META_BACKREF_BYNAME: + case META_RECURSE_BYNAME: + pptr += 1 + SIZEOFFSET; + break; + case META_COND_DEFINE: case META_COND_NAME: case META_COND_NUMBER: case META_COND_RNAME: case META_COND_RNUMBER: - case META_RECURSE_BYNAME: pptr += 1 + SIZEOFFSET; + nestlevel++; + break; + + case META_COND_VERSION: + pptr += 3; + nestlevel++; break; case META_CALLOUT_STRING: @@ -9378,7 +9611,6 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) break; case META_CALLOUT_NUMBER: - case META_COND_VERSION: pptr += 3; break; @@ -9392,7 +9624,8 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) case META_LOOKBEHIND: case META_LOOKBEHINDNOT: - if (!set_lookbehind_lengths(&pptr, &errorcode, &loopcount, NULL, cb)) + case META_LOOKBEHIND_NA: + if (!set_lookbehind_lengths(&pptr, &errorcode, &loopcount, recurses, cb)) return errorcode; break; } @@ -9494,6 +9727,10 @@ if (pattern == NULL) if (ccontext == NULL) ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context)); +/* PCRE2_MATCH_INVALID_UTF implies UTF */ + +if ((options & PCRE2_MATCH_INVALID_UTF) != 0) options |= PCRE2_UTF; + /* Check that all undefined public option bits are zero. */ if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0 || @@ -9672,7 +9909,7 @@ if ((options & PCRE2_LITERAL) == 0) ptr += skipatstart; -/* Can't support UTF or UCP unless PCRE2 has been compiled with UTF support. */ +/* Can't support UTF or UCP if PCRE2 was built without Unicode support. */ #ifndef SUPPORT_UNICODE if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0) @@ -9842,7 +10079,7 @@ lengths. */ if (has_lookbehind) { - errorcode = check_lookbehinds(&cb); + errorcode = check_lookbehinds(cb.parsed_pattern, NULL, NULL, &cb); if (errorcode != 0) goto HAD_CB_ERROR; } @@ -9990,8 +10227,9 @@ re->max_lookbehind = cb.max_lookbehind; if (cb.had_accept) { - reqcu = 0; /* Must disable after (*ACCEPT) */ + reqcu = 0; /* Must disable after (*ACCEPT) */ reqcuflags = REQ_NONE; + re->flags |= PCRE2_HASACCEPT; /* Disables minimum length */ } /* Fill in the final opcode and check for disastrous overflow. If no overflow, @@ -10112,6 +10350,8 @@ unit. */ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) { + int minminlength = 0; /* For minimal minlength from first/required CU */ + /* If we do not have a first code unit, see if there is one that is asserted (these are not saved during the compile because they can cause conflicts with actual literals that follow). */ @@ -10119,12 +10359,14 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) if (firstcuflags < 0) firstcu = find_firstassertedcu(codestart, &firstcuflags, 0); - /* Save the data for a first code unit. */ + /* Save the data for a first code unit. The existence of one means the + minimum length must be at least 1. */ if (firstcuflags >= 0) { re->first_codeunit = firstcu; re->flags |= PCRE2_FIRSTSET; + minminlength++; /* Handle caseless first code units. */ @@ -10158,39 +10400,72 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0) is_startline(codestart, 0, &cb, 0, FALSE)) re->flags |= PCRE2_STARTLINE; - /* Handle the "required code unit", if one is set. In the case of an anchored - pattern, do this only if it follows a variable length item in the pattern. */ + /* Handle the "required code unit", if one is set. In the UTF case we can + increment the minimum minimum length only if we are sure this really is a + different character and not a non-starting code unit of the first character, + because the minimum length count is in characters, not code units. */ - if (reqcuflags >= 0 && - ((re->overall_options & PCRE2_ANCHORED) == 0 || - (reqcuflags & REQ_VARY) != 0)) + if (reqcuflags >= 0) { - re->last_codeunit = reqcu; - re->flags |= PCRE2_LASTSET; +#if PCRE2_CODE_UNIT_WIDTH == 16 + if ((re->overall_options & PCRE2_UTF) == 0 || /* Not UTF */ + firstcuflags < 0 || /* First not set */ + (firstcu & 0xf800) != 0xd800 || /* First not surrogate */ + (reqcu & 0xfc00) != 0xdc00) /* Req not low surrogate */ +#elif PCRE2_CODE_UNIT_WIDTH == 8 + if ((re->overall_options & PCRE2_UTF) == 0 || /* Not UTF */ + firstcuflags < 0 || /* First not set */ + (firstcu & 0x80) == 0 || /* First is ASCII */ + (reqcu & 0x80) == 0) /* Req is ASCII */ +#endif + { + minminlength++; + } - /* Handle caseless required code units as for first code units (above). */ + /* In the case of an anchored pattern, set up the value only if it follows + a variable length item in the pattern. */ - if ((reqcuflags & REQ_CASELESS) != 0) + if ((re->overall_options & PCRE2_ANCHORED) == 0 || + (reqcuflags & REQ_VARY) != 0) { - if (reqcu < 128 || (!utf && reqcu < 255)) + re->last_codeunit = reqcu; + re->flags |= PCRE2_LASTSET; + + /* Handle caseless required code units as for first code units (above). */ + + if ((reqcuflags & REQ_CASELESS) != 0) { - if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS; - } + if (reqcu < 128 || (!utf && reqcu < 255)) + { + if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS; + } #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8 - else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu) - re->flags |= PCRE2_LASTCASELESS; + else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu) + re->flags |= PCRE2_LASTCASELESS; #endif + } } } - /* Finally, study the compiled pattern to set up information such as a bitmap - of starting code units and a minimum matching length. */ + /* Study the compiled pattern to set up information such as a bitmap of + starting code units and a minimum matching length. */ if (PRIV(study)(re) != 0) { errorcode = ERR31; goto HAD_CB_ERROR; } + + /* If study() set a bitmap of starting code units, it implies a minimum + length of at least one. */ + + if ((re->flags & PCRE2_FIRSTMAPSET) != 0 && minminlength == 0) + minminlength = 1; + + /* If the minimum length set (or not set) by study() is less than the minimum + implied by required code units, override it. */ + + if (re->minlength < minminlength) re->minlength = minminlength; } /* End of start-of-match optimizations. */ /* Control ends up here in all cases. When running under valgrind, make a diff --git a/ext/pcre/pcre2lib/pcre2_context.c b/ext/pcre/pcre2lib/pcre2_context.c index 9c2886a6d02ad..f904a494a018b 100644 --- a/ext/pcre/pcre2lib/pcre2_context.c +++ b/ext/pcre/pcre2lib/pcre2_context.c @@ -323,7 +323,7 @@ data. */ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_character_tables(pcre2_compile_context *ccontext, - const unsigned char *tables) + const uint8_t *tables) { ccontext->tables = tables; return 0; diff --git a/ext/pcre/pcre2lib/pcre2_dfa_match.c b/ext/pcre/pcre2lib/pcre2_dfa_match.c index bbf3e21064b1e..7d8ffe8a3ec35 100644 --- a/ext/pcre/pcre2lib/pcre2_dfa_match.c +++ b/ext/pcre/pcre2lib/pcre2_dfa_match.c @@ -173,6 +173,8 @@ static const uint8_t coptable[] = { 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ + 0, /* NA assert */ + 0, /* NA assert behind */ 0, /* ONCE */ 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ @@ -248,6 +250,8 @@ static const uint8_t poptable[] = { 0, /* Assert not */ 0, /* Assert behind */ 0, /* Assert behind not */ + 0, /* NA assert */ + 0, /* NA assert behind */ 0, /* ONCE */ 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ @@ -962,7 +966,7 @@ for (;;) if (ptr >= end_subject) { if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) - could_continue = TRUE; + return PCRE2_ERROR_PARTIAL; else { ADD_ACTIVE(state_offset + 1, 0); } } break; @@ -1011,10 +1015,12 @@ for (;;) /*-----------------------------------------------------------------*/ case OP_EODN: - if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0) - could_continue = TRUE; - else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen)) - { ADD_ACTIVE(state_offset + 1, 0); } + if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen)) + { + if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0) + return PCRE2_ERROR_PARTIAL; + ADD_ACTIVE(state_offset + 1, 0); + } break; /*-----------------------------------------------------------------*/ @@ -3152,8 +3158,8 @@ for (;;) /* We have finished the processing at the current subject character. If no new states have been set for the next character, we have found all the - matches that we are going to find. If we are at the top level and partial - matching has been requested, check for appropriate conditions. + matches that we are going to find. If partial matching has been requested, + check for appropriate conditions. The "forced_ fail" variable counts the number of (*F) encountered for the character. If it is equal to the original active_count (saved in @@ -3165,22 +3171,24 @@ for (;;) if (new_count <= 0) { - if (rlevel == 1 && /* Top level, and */ - could_continue && /* Some could go on, and */ + if (could_continue && /* Some could go on, and */ forced_fail != workspace[1] && /* Not all forced fail & */ ( /* either... */ (mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */ || /* or... */ ((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */ - match_count < 0) /* no matches */ + match_count < 0) /* no matches */ ) && /* And... */ ( - partial_newline || /* Either partial NL */ - ( /* or ... */ - ptr >= end_subject && /* End of subject and */ - ptr > mb->start_used_ptr) /* Inspected non-empty string */ + partial_newline || /* Either partial NL */ + ( /* or ... */ + ptr >= end_subject && /* End of subject and */ + ( /* either */ + ptr > mb->start_used_ptr || /* Inspected non-empty string */ + mb->allowemptypartial /* or pattern has lookbehind */ + ) /* or could match empty */ ) - ) + )) match_count = PCRE2_ERROR_PARTIAL; break; /* Exit from loop along the subject string */ } @@ -3246,6 +3254,11 @@ BOOL utf, anchored, startline, firstline; BOOL has_first_cu = FALSE; BOOL has_req_cu = FALSE; +#if PCRE2_CODE_UNIT_WIDTH == 8 +BOOL memchr_not_found_first_cu = FALSE; +BOOL memchr_not_found_first_cu2 = FALSE; +#endif + PCRE2_UCHAR first_cu = 0; PCRE2_UCHAR first_cu2 = 0; PCRE2_UCHAR req_cu = 0; @@ -3295,6 +3308,11 @@ if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 && ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0) return PCRE2_ERROR_BADOPTION; +/* Invalid UTF support is not available for DFA matching. */ + +if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0) + return PCRE2_ERROR_DFA_UINVALID_UTF; + /* Check that the first field in the block is the magic number. If it is not, return with PCRE2_ERROR_BADMAGIC. */ @@ -3404,6 +3422,8 @@ mb->tables = re->tables; mb->start_subject = subject; mb->end_subject = end_subject; mb->start_offset = start_offset; +mb->allowemptypartial = (re->max_lookbehind > 0) || + (re->flags & PCRE2_MATCH_EMPTY) != 0; mb->moptions = options; mb->poptions = re->overall_options; mb->match_call_count = 0; @@ -3619,7 +3639,10 @@ for (;;) /* Not anchored. Advance to a unique first code unit if there is one. In 8-bit mode, the use of memchr() gives a big speed up, even though we have to call it twice in caseless mode, in order to find the earliest occurrence - of the character in either of its cases. */ + of the character in either of its cases. If a call to memchr() that + searches the rest of the subject fails to find one case, remember that in + order not to keep on repeating the search. This can make a huge difference + when the strings are very long and only one case is present. */ else { @@ -3633,11 +3656,29 @@ for (;;) (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2) start_match++; + #else /* 8-bit code units */ - PCRE2_SPTR pp1 = - memchr(start_match, first_cu, end_subject-start_match); - PCRE2_SPTR pp2 = - memchr(start_match, first_cu2, end_subject-start_match); + PCRE2_SPTR pp1 = NULL; + PCRE2_SPTR pp2 = NULL; + PCRE2_SIZE cu2size = end_subject - start_match; + + if (!memchr_not_found_first_cu) + { + pp1 = memchr(start_match, first_cu, end_subject - start_match); + if (pp1 == NULL) memchr_not_found_first_cu = TRUE; + else cu2size = pp1 - start_match; + } + + /* If pp1 is not NULL, we have arranged to search only as far as pp1, + to see if the other case is earlier, so we can set "not found" only + when both searches have returned NULL. */ + + if (!memchr_not_found_first_cu2) + { + pp2 = memchr(start_match, first_cu2, cu2size); + memchr_not_found_first_cu2 = (pp2 == NULL && pp1 == NULL); + } + if (pp1 == NULL) start_match = (pp2 == NULL)? end_subject : pp2; else @@ -3653,7 +3694,7 @@ for (;;) while (start_match < end_subject && UCHAR21TEST(start_match) != first_cu) start_match++; -#else +#else /* 8-bit code units */ start_match = memchr(start_match, first_cu, end_subject - start_match); if (start_match == NULL) start_match = end_subject; #endif @@ -3740,6 +3781,8 @@ for (;;) if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0) { + PCRE2_SPTR p; + /* The minimum matching length is a lower bound; no actual string of that length may actually match the pattern. Although the value is, strictly, in characters, we treat it as code units to avoid spending too much time @@ -3753,37 +3796,63 @@ for (;;) point. This optimization can save a huge amount of backtracking in patterns with nested unlimited repeats that aren't going to match. Writing separate code for cased/caseless versions makes it go faster, as - does using an autoincrement and backing off on a match. + does using an autoincrement and backing off on a match. As in the case of + the first code unit, using memchr() in the 8-bit library gives a big + speed up. Unlike the first_cu check above, we do not need to call + memchr() twice in the caseless case because we only need to check for the + presence of the character in either case, not find the first occurrence. + + The search can be skipped if the code unit was found later than the + current starting point in a previous iteration of the bumpalong loop. HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary patterns. This showed up when somebody was matching something like /^\d+C/ on a 32-megabyte string... so we don't do this when the string is - sufficiently long. */ + sufficiently long, but it's worth searching a lot more for unanchored + patterns. */ - if (has_req_cu && end_subject - start_match < REQ_CU_MAX) + p = start_match + (has_first_cu? 1:0); + if (has_req_cu && p > req_cu_ptr) { - PCRE2_SPTR p = start_match + (has_first_cu? 1:0); - - /* We don't need to repeat the search if we haven't yet reached the - place we found it at last time. */ + PCRE2_SIZE check_length = end_subject - start_match; - if (p > req_cu_ptr) + if (check_length < REQ_CU_MAX || + (!anchored && check_length < REQ_CU_MAX * 1000)) { - if (req_cu != req_cu2) + if (req_cu != req_cu2) /* Caseless */ { +#if PCRE2_CODE_UNIT_WIDTH != 8 while (p < end_subject) { uint32_t pp = UCHAR21INCTEST(p); if (pp == req_cu || pp == req_cu2) { p--; break; } } +#else /* 8-bit code units */ + PCRE2_SPTR pp = p; + p = memchr(pp, req_cu, end_subject - pp); + if (p == NULL) + { + p = memchr(pp, req_cu2, end_subject - pp); + if (p == NULL) p = end_subject; + } +#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */ } + + /* The caseful case */ + else { +#if PCRE2_CODE_UNIT_WIDTH != 8 while (p < end_subject) { if (UCHAR21INCTEST(p) == req_cu) { p--; break; } } + +#else /* 8-bit code units */ + p = memchr(p, req_cu, end_subject - p); + if (p == NULL) p = end_subject; +#endif } /* If we can't find the required code unit, break the matching loop, diff --git a/ext/pcre/pcre2lib/pcre2_error.c b/ext/pcre/pcre2lib/pcre2_error.c index 1d02cf14a3a2f..c61648cb7f466 100644 --- a/ext/pcre/pcre2lib/pcre2_error.c +++ b/ext/pcre/pcre2lib/pcre2_error.c @@ -184,6 +184,8 @@ static const unsigned char compile_error_texts[] = /* 95 */ "(*alpha_assertion) not recognized\0" "script runs require Unicode support, which this version of PCRE2 does not have\0" + "too many capturing groups (maximum 65535)\0" + "atomic assertion expected after (?( or (?(?C)\0" ; /* Match-time and UTF error texts are in the same format. */ @@ -268,6 +270,7 @@ static const unsigned char match_error_texts[] = "invalid syntax\0" /* 65 */ "internal error - duplicate substitution match\0" + "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0" ; diff --git a/ext/pcre/pcre2lib/pcre2_internal.h b/ext/pcre/pcre2lib/pcre2_internal.h index 814d91bddb515..fe8ffe5c80db0 100644 --- a/ext/pcre/pcre2lib/pcre2_internal.h +++ b/ext/pcre/pcre2lib/pcre2_internal.h @@ -517,6 +517,7 @@ bytes in a code unit in that mode. */ #define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */ #define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */ #define PCRE2_HASBKC 0x00400000 /* contains \C */ +#define PCRE2_HASACCEPT 0x00800000 /* contains (*ACCEPT) */ #define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32) @@ -535,13 +536,14 @@ enum { PCRE2_MATCHEDBY_INTERPRETER, /* pcre2_match() */ #define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ /* The maximum remaining length of subject we are prepared to search for a -req_unit match. In 8-bit mode, memchr() is used and is much faster than the -search loop that has to be used in 16-bit and 32-bit modes. */ +req_unit match from an anchored pattern. In 8-bit mode, memchr() is used and is +much faster than the search loop that has to be used in 16-bit and 32-bit +modes. */ #if PCRE2_CODE_UNIT_WIDTH == 8 -#define REQ_CU_MAX 2000 +#define REQ_CU_MAX 5000 #else -#define REQ_CU_MAX 1000 +#define REQ_CU_MAX 2000 #endif /* Offsets for the bitmap tables in the cbits set of tables. Each table @@ -881,12 +883,16 @@ a positive value. */ #define STRING_atomic0 "atomic\0" #define STRING_pla0 "pla\0" #define STRING_plb0 "plb\0" +#define STRING_napla0 "napla\0" +#define STRING_naplb0 "naplb\0" #define STRING_nla0 "nla\0" #define STRING_nlb0 "nlb\0" #define STRING_sr0 "sr\0" #define STRING_asr0 "asr\0" #define STRING_positive_lookahead0 "positive_lookahead\0" #define STRING_positive_lookbehind0 "positive_lookbehind\0" +#define STRING_non_atomic_positive_lookahead0 "non_atomic_positive_lookahead\0" +#define STRING_non_atomic_positive_lookbehind0 "non_atomic_positive_lookbehind\0" #define STRING_negative_lookahead0 "negative_lookahead\0" #define STRING_negative_lookbehind0 "negative_lookbehind\0" #define STRING_script_run0 "script_run\0" @@ -1171,12 +1177,16 @@ only. */ #define STRING_atomic0 STR_a STR_t STR_o STR_m STR_i STR_c "\0" #define STRING_pla0 STR_p STR_l STR_a "\0" #define STRING_plb0 STR_p STR_l STR_b "\0" +#define STRING_napla0 STR_n STR_a STR_p STR_l STR_a "\0" +#define STRING_naplb0 STR_n STR_a STR_p STR_l STR_b "\0" #define STRING_nla0 STR_n STR_l STR_a "\0" #define STRING_nlb0 STR_n STR_l STR_b "\0" #define STRING_sr0 STR_s STR_r "\0" #define STRING_asr0 STR_a STR_s STR_r "\0" #define STRING_positive_lookahead0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0" #define STRING_positive_lookbehind0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0" +#define STRING_non_atomic_positive_lookahead0 STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0" +#define STRING_non_atomic_positive_lookbehind0 STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0" #define STRING_negative_lookahead0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0" #define STRING_negative_lookbehind0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0" #define STRING_script_run0 STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n "\0" @@ -1301,7 +1311,7 @@ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in order to the list of escapes immediately above. Furthermore, values up to OP_DOLLM must not be changed without adjusting the table called autoposstab in -pcre2_auto_possess.c +pcre2_auto_possess.c. Whenever this list is updated, the two macro definitions that follow must be updated to match. The possessification table called "opcode_possessify" in @@ -1499,80 +1509,81 @@ enum { OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */ OP_KETRPOS, /* 124 Possessive unlimited repeat. */ - /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four - asserts must remain in order. */ + /* The assertions must come before BRA, CBRA, ONCE, and COND. */ OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */ OP_ASSERT, /* 126 Positive lookahead */ OP_ASSERT_NOT, /* 127 Negative lookahead */ OP_ASSERTBACK, /* 128 Positive lookbehind */ OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */ + OP_ASSERT_NA, /* 130 Positive non-atomic lookahead */ + OP_ASSERTBACK_NA, /* 131 Positive non-atomic lookbehind */ /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. The POS versions must immediately follow the non-POS versions in each case. */ - OP_ONCE, /* 130 Atomic group, contains captures */ - OP_SCRIPT_RUN, /* 131 Non-capture, but check characters' scripts */ - OP_BRA, /* 132 Start of non-capturing bracket */ - OP_BRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 134 Start of capturing bracket */ - OP_CBRAPOS, /* 135 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 136 Conditional group */ + OP_ONCE, /* 132 Atomic group, contains captures */ + OP_SCRIPT_RUN, /* 133 Non-capture, but check characters' scripts */ + OP_BRA, /* 134 Start of non-capturing bracket */ + OP_BRAPOS, /* 135 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 136 Start of capturing bracket */ + OP_CBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 138 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 137 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 139 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 141 Conditional group, check empty */ + OP_SBRA, /* 139 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 149 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 141 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 142 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 143 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 142 Used to hold a capture number as condition */ - OP_DNCREF, /* 143 Used to point to duplicate names as a condition */ - OP_RREF, /* 144 Used to hold a recursion number as condition */ - OP_DNRREF, /* 145 Used to point to duplicate names as a condition */ - OP_FALSE, /* 146 Always false (used by DEFINE and VERSION) */ - OP_TRUE, /* 147 Always true (used by VERSION) */ + OP_CREF, /* 144 Used to hold a capture number as condition */ + OP_DNCREF, /* 145 Used to point to duplicate names as a condition */ + OP_RREF, /* 146 Used to hold a recursion number as condition */ + OP_DNRREF, /* 147 Used to point to duplicate names as a condition */ + OP_FALSE, /* 148 Always false (used by DEFINE and VERSION) */ + OP_TRUE, /* 149 Always true (used by VERSION) */ - OP_BRAZERO, /* 148 These two must remain together and in this */ - OP_BRAMINZERO, /* 149 order. */ - OP_BRAPOSZERO, /* 150 */ + OP_BRAZERO, /* 150 These two must remain together and in this */ + OP_BRAMINZERO, /* 151 order. */ + OP_BRAPOSZERO, /* 152 */ /* These are backtracking control verbs */ - OP_MARK, /* 151 always has an argument */ - OP_PRUNE, /* 152 */ - OP_PRUNE_ARG, /* 153 same, but with argument */ - OP_SKIP, /* 154 */ - OP_SKIP_ARG, /* 155 same, but with argument */ - OP_THEN, /* 156 */ - OP_THEN_ARG, /* 157 same, but with argument */ - OP_COMMIT, /* 158 */ - OP_COMMIT_ARG, /* 159 same, but with argument */ + OP_MARK, /* 153 always has an argument */ + OP_PRUNE, /* 154 */ + OP_PRUNE_ARG, /* 155 same, but with argument */ + OP_SKIP, /* 156 */ + OP_SKIP_ARG, /* 157 same, but with argument */ + OP_THEN, /* 158 */ + OP_THEN_ARG, /* 159 same, but with argument */ + OP_COMMIT, /* 160 */ + OP_COMMIT_ARG, /* 161 same, but with argument */ /* These are forced failure and success verbs. FAIL and ACCEPT do accept an argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL) without the need for a special opcode. */ - OP_FAIL, /* 160 */ - OP_ACCEPT, /* 161 */ - OP_ASSERT_ACCEPT, /* 162 Used inside assertions */ - OP_CLOSE, /* 163 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 162 */ + OP_ACCEPT, /* 163 */ + OP_ASSERT_ACCEPT, /* 164 Used inside assertions */ + OP_CLOSE, /* 165 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 164 */ + OP_SKIPZERO, /* 166 */ /* This is used to identify a DEFINE group during compilation so that it can be checked for having only one branch. It is changed to OP_FALSE before compilation finishes. */ - OP_DEFINE, /* 165 */ + OP_DEFINE, /* 167 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1585,7 +1596,7 @@ enum { /* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro definitions that follow must also be updated to match. There are also tables called "opcode_possessify" in pcre2_compile.c and "coptable" and "poptable" in -pcre2_dfa_exec.c that must be updated. */ +pcre2_dfa_match.c that must be updated. */ /* This macro defines textual names for all the opcodes. These are used only @@ -1618,7 +1629,9 @@ some cases doesn't actually use these names at all). */ "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ "Recurse", "Callout", "CalloutStr", \ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ - "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ + "Reverse", "Assert", "Assert not", \ + "Assert back", "Assert back not", \ + "Non-atomic assert", "Non-atomic assert back", \ "Once", \ "Script run", \ "Bra", "BraPos", "CBra", "CBraPos", \ @@ -1703,6 +1716,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ 1+LINK_SIZE, /* Assert behind not */ \ + 1+LINK_SIZE, /* NA Assert */ \ + 1+LINK_SIZE, /* NA Assert behind */ \ 1+LINK_SIZE, /* ONCE */ \ 1+LINK_SIZE, /* SCRIPT_RUN */ \ 1+LINK_SIZE, /* BRA */ \ diff --git a/ext/pcre/pcre2lib/pcre2_intmodedep.h b/ext/pcre/pcre2lib/pcre2_intmodedep.h index bf3a235984ded..ea3b3ec698763 100644 --- a/ext/pcre/pcre2lib/pcre2_intmodedep.h +++ b/ext/pcre/pcre2lib/pcre2_intmodedep.h @@ -205,19 +205,19 @@ whether its argument, which is assumed to be one code unit, is less than 256. The CHMAX_255 macro does not assume one code unit. The maximum length of a MARK name must fit in one code unit; currently it is set to 255 or 65535. The TABLE_GET macro is used to access elements of tables containing exactly 256 -items. When code points can be greater than 255, a check is needed before -accessing these tables. */ +items. Its argument is a code unit. When code points can be greater than 255, a +check is needed before accessing these tables. */ #if PCRE2_CODE_UNIT_WIDTH == 8 #define MAX_255(c) TRUE #define MAX_MARK ((1u << 8) - 1) +#define TABLE_GET(c, table, default) ((table)[c]) #ifdef SUPPORT_UNICODE #define SUPPORT_WIDE_CHARS #define CHMAX_255(c) ((c) <= 255u) #else #define CHMAX_255(c) TRUE #endif /* SUPPORT_UNICODE */ -#define TABLE_GET(c, table, default) ((table)[c]) #else /* Code units are 16 or 32 bits */ #define CHMAX_255(c) ((c) <= 255u) @@ -228,7 +228,6 @@ accessing these tables. */ #endif - /* ----------------- Character-handling macros ----------------- */ /* There is a proposed future special "UTF-21" mode, in which only the lowest @@ -854,6 +853,7 @@ typedef struct match_block { uint32_t match_call_count; /* Number of times a new frame is created */ BOOL hitend; /* Hit the end of the subject at some point */ BOOL hasthen; /* Pattern contains (*THEN) */ + BOOL allowemptypartial; /* Allow empty hard partial */ const uint8_t *lcc; /* Points to lower casing table */ const uint8_t *fcc; /* Points to case-flipping table */ const uint8_t *ctypes; /* Points to table of type maps */ @@ -866,6 +866,7 @@ typedef struct match_block { PCRE2_SPTR name_table; /* Table of group names */ PCRE2_SPTR start_code; /* For use when recursing */ PCRE2_SPTR start_subject; /* Start of the subject string */ + PCRE2_SPTR check_subject; /* Where UTF-checked from */ PCRE2_SPTR end_subject; /* End of the subject string */ PCRE2_SPTR end_match_ptr; /* Subject position at end match */ PCRE2_SPTR start_used_ptr; /* Earliest consulted character */ @@ -908,6 +909,7 @@ typedef struct dfa_match_block { uint32_t poptions; /* Pattern options */ uint32_t nltype; /* Newline type */ uint32_t nllen; /* Newline string length */ + BOOL allowemptypartial; /* Allow empty hard partial */ PCRE2_UCHAR nl[4]; /* Newline string when fixed */ uint16_t bsr_convention; /* \R interpretation */ pcre2_callout_block *cb; /* Points to a callout block */ diff --git a/ext/pcre/pcre2lib/pcre2_jit_compile.c b/ext/pcre/pcre2lib/pcre2_jit_compile.c index 8b48cea2c69e4..f564127c2ae24 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_compile.c +++ b/ext/pcre/pcre2lib/pcre2_jit_compile.c @@ -6,8 +6,9 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel + This module by Zoltan Herczeg Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -212,12 +213,6 @@ typedef struct stub_list { struct stub_list *next; } stub_list; -typedef struct label_addr_list { - struct sljit_label *label; - sljit_uw *update_addr; - struct label_addr_list *next; -} label_addr_list; - enum frame_types { no_frame = -1, no_stack = -2 @@ -271,6 +266,8 @@ typedef struct bracket_backtrack { assert_backtrack *assert; /* For OP_ONCE. Less than 0 if not needed. */ int framesize; + /* For brackets with >3 alternatives. */ + struct sljit_put_label *matching_put_label; } u; /* Points to our private memory word on the stack. */ int private_data_ptr; @@ -416,6 +413,8 @@ typedef struct compiler_common { sljit_sw lcc; /* Mode can be PCRE2_JIT_COMPLETE and others. */ int mode; + /* TRUE, when empty match is accepted for partial matching. */ + BOOL allow_empty_partial; /* TRUE, when minlength is greater than 0. */ BOOL might_be_empty; /* \K is found in the pattern. */ @@ -454,7 +453,6 @@ typedef struct compiler_common { struct sljit_label *accept_label; struct sljit_label *ff_newline_shortcut; stub_list *stubs; - label_addr_list *label_addrs; recurse_entry *entries; recurse_entry *currententry; jump_list *partialmatch; @@ -563,6 +561,12 @@ typedef struct compare_context { #define ARGUMENTS SLJIT_S4 #define RETURN_ADDR SLJIT_R4 +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) +#define HAS_VIRTUAL_REGISTERS 1 +#else +#define HAS_VIRTUAL_REGISTERS 0 +#endif + /* Local space layout. */ /* These two locals can be used by the current opcode. */ #define LOCALS0 (0 * sizeof(sljit_sw)) @@ -696,11 +700,12 @@ the start pointers when the end of the capturing group has not yet reached. */ #define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \ { \ - if (ptr[-1] <= 0x7f) \ - c = *ptr--; \ + c = ptr[-1]; \ + if (c <= 0x7f) \ + ptr--; \ else if (ptr - 1 > start && ptr[-1] >= 0x80 && ptr[-1] < 0xc0) \ { \ - c = ptr[-1] - 0x80; \ + c -= 0x80; \ \ if (ptr[-2] >= 0xc2 && ptr[-2] <= 0xdf) \ { \ @@ -775,11 +780,12 @@ the start pointers when the end of the capturing group has not yet reached. */ #define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \ { \ - if (ptr[-1] < 0xd800 || ptr[-1] >= 0xe000) \ - c = *ptr--; \ - else if (ptr[-1] >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \ + c = ptr[-1]; \ + if (c < 0xd800 || c >= 0xe000) \ + ptr--; \ + else if (c >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \ { \ - c = (((ptr[-2] - 0xd800) << 10) | (ptr[-1] - 0xdc00)) + 0x10000; \ + c = (((ptr[-2] - 0xd800) << 10) | (c - 0xdc00)) + 0x10000; \ ptr -= 2; \ } \ else \ @@ -793,7 +799,7 @@ the start pointers when the end of the capturing group has not yet reached. */ #define GETCHARINC_INVALID(c, ptr, end, invalid_action) \ { \ - if (ptr[0] < 0x110000) \ + if (ptr[0] < 0xd800 || (ptr[0] >= 0xe000 && ptr[0] < 0x110000)) \ c = *ptr++; \ else \ { \ @@ -801,6 +807,17 @@ the start pointers when the end of the capturing group has not yet reached. */ } \ } +#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \ + { \ + c = ptr[-1]; \ + if (ptr[-1] < 0xd800 || (ptr[-1] >= 0xe000 && ptr[-1] < 0x110000)) \ + ptr--; \ + else \ + { \ + invalid_action; \ + } \ + } + #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ #endif /* SUPPORT_UNICODE */ @@ -1033,8 +1050,8 @@ switch(*cc) return cc + 1 + 2 + cc[1]; default: - /* All opcodes are supported now! */ - SLJIT_UNREACHABLE(); + /* Unsupported opcodes: OP_ASSERT_NA and OP_ASSERTBACK_NA */ + /* SLJIT_UNREACHABLE(); */ return NULL; } } @@ -2371,14 +2388,14 @@ if (base_reg != TMP2) else { status.saved_tmp_regs[1] = RETURN_ADDR; - if (sljit_get_register_index(RETURN_ADDR) == -1) + if (HAS_VIRTUAL_REGISTERS) status.tmp_regs[1] = STR_PTR; else status.tmp_regs[1] = RETURN_ADDR; } status.saved_tmp_regs[2] = TMP3; -if (sljit_get_register_index(TMP3) == -1) +if (HAS_VIRTUAL_REGISTERS) status.tmp_regs[2] = STR_END; else status.tmp_regs[2] = TMP3; @@ -2829,20 +2846,6 @@ while (list_item) common->stubs = NULL; } -static void add_label_addr(compiler_common *common, sljit_uw *update_addr) -{ -DEFINE_COMPILER; -label_addr_list *label_addr; - -label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list)); -if (label_addr == NULL) - return; -label_addr->label = LABEL(); -label_addr->update_addr = update_addr; -label_addr->next = common->label_addrs; -common->label_addrs = label_addr; -} - static SLJIT_INLINE void count_match(compiler_common *common) { DEFINE_COMPILER; @@ -2985,12 +2988,18 @@ else } } -OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); +if (!HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, stack)); +else + OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0); + if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0); if (common->control_head_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); +if (HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end)); } @@ -3029,21 +3038,36 @@ BOOL has_pre; OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0); -OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); -if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); -OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0); -if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0); -OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data), - SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE)); +if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); + if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); + OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0); + if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0); + OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data), + SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE)); + } +else + { + OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); + OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, match_data)); + if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); + OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, oveccount)); + OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0); + if (common->mark_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R0, 0); + OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE)); + } has_pre = sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS; GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0)); -OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? SLJIT_R0 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); loop = LABEL(); @@ -3105,20 +3129,22 @@ static SLJIT_INLINE void return_with_partial_match(compiler_common *common, stru { DEFINE_COMPILER; sljit_s32 mov_opcode; +sljit_s32 arguments_reg = !HAS_VIRTUAL_REGISTERS ? ARGUMENTS : SLJIT_R1; SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S0, str_end_must_be_saved_reg0); SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0 && (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0)); -OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); +if (arguments_reg != ARGUMENTS) + OP1(SLJIT_MOV, arguments_reg, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL); /* Store match begin and end. */ -OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0); -OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data)); +OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0); +OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, match_data)); mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV; @@ -3279,7 +3305,7 @@ SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE); if (common->mode == PCRE2_JIT_COMPLETE) return; -if (!force) +if (!force && !common->allow_empty_partial) jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); else if (common->mode == PCRE2_JIT_PARTIAL_SOFT) jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1); @@ -3341,7 +3367,11 @@ if (common->mode == PCRE2_JIT_COMPLETE) /* Partial matching mode. */ jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); -add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); +if (!common->allow_empty_partial) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); +else if (common->mode == PCRE2_JIT_PARTIAL_SOFT) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1)); + if (common->mode == PCRE2_JIT_PARTIAL_SOFT) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); @@ -3357,6 +3387,35 @@ else JUMPHERE(jump); } +static void process_partial_match(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; + +/* Partial matching mode. */ +if (common->mode == PCRE2_JIT_PARTIAL_SOFT) + { + jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0); + JUMPHERE(jump); + } +else if (common->mode == PCRE2_JIT_PARTIAL_HARD) + { + if (common->partialmatchlabel != NULL) + CMPTO(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0, common->partialmatchlabel); + else + add_jump(compiler, &common->partialmatch, CMP(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0)); + } +} + +static void detect_partial_match_to(compiler_common *common, struct sljit_label *label) +{ +DEFINE_COMPILER; + +CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, label); +process_partial_match(common); +} + static void peek_char(compiler_common *common, sljit_u32 max, sljit_s32 dst, sljit_sw dstw, jump_list **backtracks) { /* Reads the character into TMP1, keeps STR_PTR. @@ -3420,12 +3479,21 @@ if (common->utf) #elif PCRE2_CODE_UNIT_WIDTH == 32 if (common->invalid_utf) { + if (max < 0xd800) return; + if (backtracks != NULL) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800)); + } else { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000); CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); + CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); } } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ @@ -3490,8 +3558,12 @@ if (common->utf) JUMPHERE(jump); } #elif PCRE2_CODE_UNIT_WIDTH == 32 - if (common->invalid_utf) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); +if (common->invalid_utf) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800)); + } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ #endif /* SUPPORT_UNICODE */ } @@ -3653,7 +3725,7 @@ if (common->utf) /* Skip low surrogate if necessary. */ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); - if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && sljit_get_register_index(RETURN_ADDR) >= 0) + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS) { if (options & READ_CHAR_UPDATE_STR_PTR) OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -3677,11 +3749,18 @@ if (common->utf) if (common->invalid_utf) { if (backtracks != NULL) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800)); + } else { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000); CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); + CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); } } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ @@ -3832,7 +3911,7 @@ if (common->utf && negated) { OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); - if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && sljit_get_register_index(RETURN_ADDR) >= 0) + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS) { OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400); @@ -3865,9 +3944,9 @@ if (common->utf && negated) static void move_back(compiler_common *common, jump_list **backtracks, BOOL must_be_valid) { -/* Goes one character back. TMP2 must contain the start of -the subject buffer. Affects STR_PTR and TMP1. Does not modify -STR_PTR for invalid character sequences. */ +/* Goes one character back. Affects STR_PTR and TMP1. If must_be_valid is TRUE, +TMP2 is not used. Otherwise TMP2 must contain the start of the subject buffer, +and it is destroyed. Does not modify STR_PTR for invalid character sequences. */ DEFINE_COMPILER; SLJIT_UNUSED_ARG(backtracks); @@ -4407,7 +4486,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); static void do_utfpeakcharback(compiler_common *common) { -/* Peak a character back. */ +/* Peak a character back. Does not modify STR_PTR. */ DEFINE_COMPILER; struct sljit_jump *jump[2]; @@ -4444,7 +4523,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); static void do_utfpeakcharback_invalid(compiler_common *common) { -/* Peak a character back. */ +/* Peak a character back. Does not modify STR_PTR. */ DEFINE_COMPILER; sljit_s32 i; sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV); @@ -4672,7 +4751,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); static void do_utfpeakcharback_invalid(compiler_common *common) { -/* Peak a character back. */ +/* Peak a character back. Does not modify STR_PTR. */ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_jump *exit_invalid[3]; @@ -4786,18 +4865,12 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); -// PH hacking -//fprintf(stderr, "~~A\n"); - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); - +/* TMP2 is multiplied by 12. Same as (TMP2 << 2) + ((TMP2 << 2) << 1). */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 1); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0); - -// OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -4866,15 +4939,27 @@ else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0) /* Check whether offset limit is set and valid. */ SLJIT_ASSERT(common->match_end_ptr != 0); - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit)); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit)); + } + else + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, offset_limit)); + OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET); - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + if (HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + else + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); #endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + if (HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); @@ -5434,802 +5519,157 @@ CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00, label); } #endif -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg) -{ -#if PCRE2_CODE_UNIT_WIDTH == 8 -OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0); -return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80); -#elif PCRE2_CODE_UNIT_WIDTH == 16 -OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00); -return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00); -#else -#error "Unknown code width" -#endif -} -#endif +#include "pcre2_jit_simd_inc.h" -static sljit_s32 character_to_int32(PCRE2_UCHAR chr) -{ -sljit_u32 value = chr; -#if PCRE2_CODE_UNIT_WIDTH == 8 -#define SSE2_COMPARE_TYPE_INDEX 0 -return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value); -#elif PCRE2_CODE_UNIT_WIDTH == 16 -#define SSE2_COMPARE_TYPE_INDEX 1 -return (sljit_s32)((value << 16) | value); -#elif PCRE2_CODE_UNIT_WIDTH == 32 -#define SSE2_COMPARE_TYPE_INDEX 2 -return (sljit_s32)(value); -#else -#error "Unsupported unit width" -#endif -} +#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD -static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg) +static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forward_char_data *chars, int max) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -sljit_u8 instruction[5]; -#else -sljit_u8 instruction[4]; -#endif + sljit_s32 i, j, max_i = 0, max_j = 0; + sljit_u32 max_pri = 0; + PCRE2_UCHAR a1, a2, a_pri, b1, b2, b_pri; -SLJIT_ASSERT(dst_xmm_reg < 8); + for (i = max - 1; i >= 1; i--) + { + if (chars[i].last_count > 2) + { + a1 = chars[i].chars[0]; + a2 = chars[i].chars[1]; + a_pri = chars[i].last_count; -/* MOVDQA xmm1, xmm2/m128 */ -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -if (src_general_reg < 8) - { - instruction[0] = 0x66; - instruction[1] = 0x0f; - instruction[2] = 0x6f; - instruction[3] = (dst_xmm_reg << 3) | src_general_reg; - sljit_emit_op_custom(compiler, instruction, 4); - } -else - { - instruction[0] = 0x66; - instruction[1] = 0x41; - instruction[2] = 0x0f; - instruction[3] = 0x6f; - instruction[4] = (dst_xmm_reg << 3) | (src_general_reg & 0x7); - sljit_emit_op_custom(compiler, instruction, 4); - } -#else -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6f; -instruction[3] = (dst_xmm_reg << 3) | src_general_reg; -sljit_emit_op_custom(compiler, instruction, 4); -#endif -} + j = i - max_fast_forward_char_pair_offset(); + if (j < 0) + j = 0; -static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, PCRE2_UCHAR char1, PCRE2_UCHAR char2, - sljit_u32 bit, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) -{ -sljit_u8 instruction[4]; -instruction[0] = 0x66; -instruction[1] = 0x0f; + while (j < i) + { + b_pri = chars[j].last_count; + if (b_pri > 2 && a_pri + b_pri >= max_pri) + { + b1 = chars[j].chars[0]; + b2 = chars[j].chars[1]; -if (char1 == char2 || bit != 0) - { - if (bit != 0) - { - /* POR xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0xeb; - instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind; - sljit_emit_op_custom(compiler, instruction, 4); + if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2) + { + max_pri = a_pri + b_pri; + max_i = i; + max_j = j; + } + } + j++; + } + } } - /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; - instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } -else - { - /* MOVDQA xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x6f; - instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind; - sljit_emit_op_custom(compiler, instruction, 4); - - /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; - instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; - sljit_emit_op_custom(compiler, instruction, 4); - - instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind; - sljit_emit_op_custom(compiler, instruction, 4); +if (max_pri == 0) + return FALSE; - /* POR xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0xeb; - instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } +fast_forward_char_pair_simd(common, max_i, chars[max_i].chars[0], chars[max_i].chars[1], max_j, chars[max_j].chars[0], chars[max_j].chars[1]); +return TRUE; } -static void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) +#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */ + +static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) { DEFINE_COMPILER; struct sljit_label *start; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -struct sljit_label *restart; -#endif -struct sljit_jump *quit; -struct sljit_jump *partial_quit[2]; -sljit_u8 instruction[8]; -sljit_s32 tmp1_ind = sljit_get_register_index(TMP1); -sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data_ind = 0; -sljit_s32 tmp_ind = 1; -sljit_s32 cmp1_ind = 2; -sljit_s32 cmp2_ind = 3; -sljit_u32 bit = 0; - -SLJIT_UNUSED_ARG(offset); - -if (char1 != char2) - { - bit = char1 ^ char2; - if (!is_powerof2(bit)) - bit = 0; - } - -partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, &common->failed_match, partial_quit[0]); - -/* First part (unaligned start) */ +struct sljit_jump *match; +struct sljit_jump *partial_quit; +PCRE2_UCHAR mask; +BOOL has_match_end = (common->match_end_ptr != 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); +SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0); -SLJIT_ASSERT(tmp1_ind < 8); +if (has_match_end) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; -instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 4); +if (offset > 0) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); -if (char1 != char2) +if (has_match_end) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - /* MOVD xmm, r/m32 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_ind; - sljit_emit_op_custom(compiler, instruction, 4); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1)); + OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0); + CMOV(SLJIT_GREATER, STR_END, TMP1, 0); } -OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); - -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[3] = 0xc0 | (cmp1_ind << 3) | 2; -instruction[4] = 0; -sljit_emit_op_custom(compiler, instruction, 5); +#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD -if (char1 != char2) +if (JIT_HAS_FAST_FORWARD_CHAR_SIMD) { - /* PSHUFD xmm1, xmm2/m128, imm8 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | 3; - sljit_emit_op_custom(compiler, instruction, 5); - } - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -restart = LABEL(); -#endif -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); - -load_from_mem_sse2(compiler, data_ind, str_ptr_ind); -fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + fast_forward_char_simd(common, char1, char2, offset); -/* BSF r32, r/m32 */ -instruction[0] = 0x0f; -instruction[1] = 0xbc; -instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 3); -sljit_set_current_flags(compiler, SLJIT_SET_Z); + if (offset > 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); -quit = JUMP(SLJIT_NOT_ZERO); + if (has_match_end) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + return; + } -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +#endif start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); -partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, &common->failed_match, partial_quit[1]); - -/* Second part (aligned) */ - -load_from_mem_sse2(compiler, 0, str_ptr_ind); -fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); - -/* BSF r32, r/m32 */ -instruction[0] = 0x0f; -instruction[1] = 0xbc; -instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 3); -sljit_set_current_flags(compiler, SLJIT_SET_Z); - -JUMPTO(SLJIT_ZERO, start); + add_jump(compiler, &common->failed_match, partial_quit); -JUMPHERE(quit); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -if (common->mode != PCRE2_JIT_COMPLETE) +if (char1 == char2) + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1, start); +else { - JUMPHERE(partial_quit[0]); - JUMPHERE(partial_quit[1]); - OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + mask = char1 ^ char2; + if (is_powerof2(mask)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask, start); + } + else + { + match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char2, start); + JUMPHERE(match); + } } -else - add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 if (common->utf && offset > 0) { - SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE); - - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); - - quit = jump_if_utf_char_start(compiler, TMP1); - - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, restart); - - JUMPHERE(quit); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-(offset + 1))); + jumpto_if_not_utf_char_start(compiler, TMP1, start); } #endif -} -#ifndef _WIN64 +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset + 1)); -static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_sse2_offset(void) -{ -#if PCRE2_CODE_UNIT_WIDTH == 8 -return 15; -#elif PCRE2_CODE_UNIT_WIDTH == 16 -return 7; -#elif PCRE2_CODE_UNIT_WIDTH == 32 -return 3; -#else -#error "Unsupported unit width" -#endif +if (common->mode != PCRE2_JIT_COMPLETE) + JUMPHERE(partial_quit); + +if (has_match_end) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); } -static void fast_forward_char_pair_sse2(compiler_common *common, sljit_s32 offs1, - PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b) +static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common) { DEFINE_COMPILER; -sljit_u32 bit1 = 0; -sljit_u32 bit2 = 0; -sljit_u32 diff = IN_UCHARS(offs1 - offs2); -sljit_s32 tmp1_ind = sljit_get_register_index(TMP1); -sljit_s32 tmp2_ind = sljit_get_register_index(TMP2); -sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data1_ind = 0; -sljit_s32 data2_ind = 1; -sljit_s32 tmp_ind = 2; -sljit_s32 cmp1a_ind = 3; -sljit_s32 cmp1b_ind = 4; -sljit_s32 cmp2a_ind = 5; -sljit_s32 cmp2b_ind = 6; struct sljit_label *start; -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -struct sljit_label *restart; -#endif -struct sljit_jump *jump[2]; - -sljit_u8 instruction[8]; - -SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2); -SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_sse2_offset())); -SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1); - -/* Initialize. */ -if (common->match_end_ptr != 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); - - OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); - CMOV(SLJIT_LESS, STR_END, TMP1, 0); - } - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); -add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; - -if (char1a == char1b) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a)); -else - { - bit1 = char1a ^ char1b; - if (is_powerof2(bit1)) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1)); - } - else - { - bit1 = 0; - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b)); - } - } - -instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -if (char1a != char1b) - { - instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - -if (char2a == char2b) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); -else - { - bit2 = char2a ^ char2b; - if (is_powerof2(bit2)) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2)); - } - else - { - bit2 = 0; - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b)); - } - } - -instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -if (char2a != char2b) - { - instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[4] = 0; - -instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind; -sljit_emit_op_custom(compiler, instruction, 5); - -if (char1a != char1b) - { - instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } - -instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind; -sljit_emit_op_custom(compiler, instruction, 5); - -if (char2a != char2b) - { - instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -restart = LABEL(); -#endif - -OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1 - offs2)); -OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); -OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, ~0xf); - -load_from_mem_sse2(compiler, data1_ind, str_ptr_ind); - -jump[0] = CMP(SLJIT_EQUAL, STR_PTR, 0, TMP1, 0); - -load_from_mem_sse2(compiler, data2_ind, tmp1_ind); - -/* MOVDQA xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x6f; -instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PSLLDQ xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x73; -instruction[3] = 0xc0 | (7 << 3) | tmp_ind; -instruction[4] = diff; -sljit_emit_op_custom(compiler, instruction, 5); - -/* PSRLDQ xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -/* instruction[2] = 0x73; */ -instruction[3] = 0xc0 | (3 << 3) | data2_ind; -instruction[4] = 16 - diff; -sljit_emit_op_custom(compiler, instruction, 5); - -/* POR xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xeb; -instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -jump[1] = JUMP(SLJIT_JUMP); - -JUMPHERE(jump[0]); - -/* MOVDQA xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x6f; -instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PSLLDQ xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x73; -instruction[3] = 0xc0 | (7 << 3) | data2_ind; -instruction[4] = diff; -sljit_emit_op_custom(compiler, instruction, 5); - -JUMPHERE(jump[1]); - -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); - -fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind); -fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind); - -/* PAND xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xdb; -instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); - -/* Ignore matches before the first STR_PTR. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); - -/* BSF r32, r/m32 */ -instruction[0] = 0x0f; -instruction[1] = 0xbc; -instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 3); -sljit_set_current_flags(compiler, SLJIT_SET_Z); - -jump[0] = JUMP(SLJIT_NOT_ZERO); - -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); - -/* Main loop. */ -instruction[0] = 0x66; -instruction[1] = 0x0f; - -start = LABEL(); - -load_from_mem_sse2(compiler, data2_ind, str_ptr_ind); - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); -add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - -load_from_mem_sse2(compiler, data1_ind, str_ptr_ind); - -/* PSRLDQ xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x73; -instruction[3] = 0xc0 | (3 << 3) | data2_ind; -instruction[4] = 16 - diff; -sljit_emit_op_custom(compiler, instruction, 5); - -/* MOVDQA xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x6f; -instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PSLLDQ xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x73; -instruction[3] = 0xc0 | (7 << 3) | tmp_ind; -instruction[4] = diff; -sljit_emit_op_custom(compiler, instruction, 5); - -/* POR xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xeb; -instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind); -fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind); - -/* PAND xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xdb; -instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); - -/* BSF r32, r/m32 */ -instruction[0] = 0x0f; -instruction[1] = 0xbc; -instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; -sljit_emit_op_custom(compiler, instruction, 3); -sljit_set_current_flags(compiler, SLJIT_SET_Z); - -JUMPTO(SLJIT_ZERO, start); - -JUMPHERE(jump[0]); - -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - -add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - -if (common->match_end_ptr != 0) - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -if (common->utf) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1)); - - jump[0] = jump_if_utf_char_start(compiler, TMP1); - - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart); - - add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP)); - - JUMPHERE(jump[0]); - } -#endif - -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); - -if (common->match_end_ptr != 0) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); -} - -static BOOL check_fast_forward_char_pair_sse2(compiler_common *common, fast_forward_char_data *chars, int max) -{ -sljit_s32 i, j, priority, count; -sljit_u32 priorities; -PCRE2_UCHAR a1, a2, b1, b2; - -priorities = 0; - -count = 0; -for (i = 0; i < max; i++) - { - if (chars[i].last_count > 2) - { - SLJIT_ASSERT(chars[i].last_count <= 7); - - priorities |= (1 << chars[i].last_count); - count++; - } - } - -if (count < 2) - return FALSE; - -for (priority = 7; priority > 2; priority--) - { - if ((priorities & (1 << priority)) == 0) - continue; - - for (i = max - 1; i >= 1; i--) - if (chars[i].last_count >= priority) - { - SLJIT_ASSERT(chars[i].count <= 2 && chars[i].count >= 1); - - a1 = chars[i].chars[0]; - a2 = chars[i].chars[1]; - - j = i - max_fast_forward_char_pair_sse2_offset(); - if (j < 0) - j = 0; - - while (j < i) - { - if (chars[j].last_count >= priority) - { - b1 = chars[j].chars[0]; - b2 = chars[j].chars[1]; - - if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2) - { - fast_forward_char_pair_sse2(common, i, a1, a2, j, b1, b2); - return TRUE; - } - } - j++; - } - } - } - -return FALSE; -} - -#endif - -#undef SSE2_COMPARE_TYPE_INDEX - -#endif - -static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) -{ -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *match; -struct sljit_jump *partial_quit; -PCRE2_UCHAR mask; -BOOL has_match_end = (common->match_end_ptr != 0); - -SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE || offset == 0); - -if (has_match_end) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); - -if (offset > 0) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); - -if (has_match_end) - { - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1)); - OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0); - CMOV(SLJIT_GREATER, STR_END, TMP1, 0); - } - -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) - -/* SSE2 accelerated first character search. */ - -if (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) - { - fast_forward_first_char2_sse2(common, char1, char2, offset); - - if (offset > 0) - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); - - if (has_match_end) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); - return; - } - -#endif - -start = LABEL(); - -partial_quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, &common->failed_match, partial_quit); - -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -if (char1 == char2) - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1, start); -else - { - mask = char1 ^ char2; - if (is_powerof2(mask)) - { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask, start); - } - else - { - match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, char2, start); - JUMPHERE(match); - } - } - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -if (common->utf && offset > 0) - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-(offset + 1))); - jumpto_if_not_utf_char_start(compiler, TMP1, start); - } -#endif - -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset + 1)); - -if (common->mode != PCRE2_JIT_COMPLETE) - JUMPHERE(partial_quit); - -if (has_match_end) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); -} - -static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common) -{ -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *match; -fast_forward_char_data chars[MAX_N_CHARS]; -sljit_s32 offset; -PCRE2_UCHAR mask; -PCRE2_UCHAR *char_set, *char_set_end; -int i, max, from; -int range_right = -1, range_len; -sljit_u8 *update_table = NULL; -BOOL in_range; -sljit_u32 rec_count; +struct sljit_jump *match; +fast_forward_char_data chars[MAX_N_CHARS]; +sljit_s32 offset; +PCRE2_UCHAR mask; +PCRE2_UCHAR *char_set, *char_set_end; +int i, max, from; +int range_right = -1, range_len; +sljit_u8 *update_table = NULL; +BOOL in_range; +sljit_u32 rec_count; for (i = 0; i < MAX_N_CHARS; i++) { @@ -6267,8 +5707,8 @@ for (i = 0; i < max; i++) chars[i].last_count = (chars[i].count == 255) ? 0 : 1; } -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) && !(defined _WIN64) -if (sljit_has_cpu_feature(SLJIT_HAS_SSE2) && check_fast_forward_char_pair_sse2(common, chars, max)) +#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD +if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && check_fast_forward_char_pair_simd(common, chars, max)) return TRUE; #endif @@ -6353,18 +5793,21 @@ if (common->match_end_ptr != 0) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS)); OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0); CMOV(SLJIT_GREATER, STR_END, TMP1, 0); } else - OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + { + OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); + add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS)); + } SLJIT_ASSERT(range_right >= 0); -#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); -#endif +if (!HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); start = LABEL(); add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); @@ -6375,11 +5818,11 @@ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); #endif -#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); -#else -OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); -#endif +if (!HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); +else + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); @@ -6473,9 +5916,17 @@ if (common->match_end_ptr != 0) if (common->nltype == NLTYPE_FIXED && common->newline > 255) { lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + } firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); @@ -6503,9 +5954,15 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255) return; } -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + } +else + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); + /* Example: match /^/ to \r\n from offset 1. */ -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); move_back(common, NULL, FALSE); @@ -6586,7 +6043,7 @@ if (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0, FALSE, &ma OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); - if (sljit_get_register_index(TMP3) >= 0) + if (!HAS_VIRTUAL_REGISTERS) { OP2(SLJIT_SHL, TMP3, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP3, 0); @@ -6693,7 +6150,7 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -sizeof(sljit_sw)); jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); -if (sljit_get_register_index(TMP3) < 0) +if (HAS_VIRTUAL_REGISTERS) { OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw))); OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(STACK_TOP), -(3 * sizeof(sljit_sw))); @@ -6718,7 +6175,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); OP1(SLJIT_NEG, TMP2, 0, TMP2, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); -if (sljit_get_register_index(TMP3) < 0) +if (HAS_VIRTUAL_REGISTERS) { OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw))); OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); @@ -6737,7 +6194,11 @@ static void check_wordboundary(compiler_common *common) DEFINE_COMPILER; struct sljit_jump *skipread; jump_list *skipread_list = NULL; -jump_list *invalid_utf = NULL; +#ifdef SUPPORT_UNICODE +struct sljit_label *valid_utf; +jump_list *invalid_utf1 = NULL; +#endif /* SUPPORT_UNICODE */ +jump_list *invalid_utf2 = NULL; #if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE struct sljit_jump *jump; #endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */ @@ -6751,14 +6212,30 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); -if (common->mode == PCRE2_JIT_COMPLETE) - peek_char_back(common, READ_CHAR_MAX, &invalid_utf); +#ifdef SUPPORT_UNICODE +if (common->invalid_utf) + { + peek_char_back(common, READ_CHAR_MAX, &invalid_utf1); + + if (common->mode != PCRE2_JIT_COMPLETE) + { + OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); + move_back(common, NULL, TRUE); + check_start_used_ptr(common); + OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); + } + } else +#endif /* SUPPORT_UNICODE */ { - move_back(common, &invalid_utf, FALSE); - check_start_used_ptr(common); - /* No need precise read since match fails anyway. */ - read_char(common, 0, READ_CHAR_MAX, &invalid_utf, READ_CHAR_UPDATE_STR_PTR); + if (common->mode == PCRE2_JIT_COMPLETE) + peek_char_back(common, READ_CHAR_MAX, NULL); + else + { + move_back(common, NULL, TRUE); + check_start_used_ptr(common); + read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR); + } } /* Testing char type. */ @@ -6802,10 +6279,13 @@ JUMPHERE(skipread); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); check_str_end(common, &skipread_list); -peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf); +peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2); /* Testing char type. This is a code duplication. */ #ifdef SUPPORT_UNICODE + +valid_utf = LABEL(); + if (common->use_ucp) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); @@ -6851,13 +6331,19 @@ sljit_emit_fast_return(compiler, TMP1, 0); #ifdef SUPPORT_UNICODE if (common->invalid_utf) { - SLJIT_ASSERT(invalid_utf != NULL); + set_jumps(invalid_utf1, LABEL()); + + peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, NULL); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR, valid_utf); - set_jumps(invalid_utf, LABEL()); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1); sljit_emit_fast_return(compiler, TMP1, 0); - return; + + set_jumps(invalid_utf2, LABEL()); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); + sljit_emit_fast_return(compiler, TMP1, 0); } #endif /* SUPPORT_UNICODE */ } @@ -7225,7 +6711,7 @@ struct sljit_label *label; int char1_reg; int char2_reg; -if (sljit_get_register_index(TMP3) < 0) +if (HAS_VIRTUAL_REGISTERS) { char1_reg = STR_END; char2_reg = STACK_TOP; @@ -7307,7 +6793,7 @@ int char2_reg; int lcc_table; int opt_type = 0; -if (sljit_get_register_index(TMP3) < 0) +if (HAS_VIRTUAL_REGISTERS) { char2_reg = STACK_TOP; lcc_table = STACK_LIMIT; @@ -7790,8 +7276,6 @@ if (needstype || needsscript) if (needsscript) { // PH hacking -//fprintf(stderr, "~~B\n"); - OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); @@ -7845,7 +7329,6 @@ if (needstype || needsscript) if (!needschar) { // PH hacking -//fprintf(stderr, "~~C\n"); OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); @@ -7860,7 +7343,6 @@ if (needstype || needsscript) else { // PH hacking -//fprintf(stderr, "~~D\n"); OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); @@ -8174,14 +7656,24 @@ struct sljit_label *label; switch(type) { case OP_SOD: - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } + else + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); return cc; case OP_SOM: - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + } + else + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); return cc; @@ -8191,9 +7683,7 @@ switch(type) #ifdef SUPPORT_UNICODE if (common->invalid_utf) { - OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_SIG_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); - add_jump(compiler, backtracks, JUMP(SLJIT_SIG_LESS)); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); return cc; } #endif /* SUPPORT_UNICODE */ @@ -8267,17 +7757,24 @@ switch(type) JUMPHERE(jump[3]); } JUMPHERE(jump[0]); - check_partial(common, FALSE); + if (common->mode != PCRE2_JIT_COMPLETE) + check_partial(common, TRUE); return cc; case OP_EOD: add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - check_partial(common, FALSE); + if (common->mode != PCRE2_JIT_COMPLETE) + check_partial(common, TRUE); return cc; case OP_DOLL: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + } + else + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32)); if (!common->endonly) @@ -8291,8 +7788,13 @@ switch(type) case OP_DOLLM: jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); + } + else + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL); add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32)); check_partial(common, FALSE); jump[0] = JUMP(SLJIT_JUMP); @@ -8327,18 +7829,38 @@ switch(type) return cc; case OP_CIRC: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32)); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32)); + } + else + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32)); + } return cc; case OP_CIRCM: - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); - OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + /* TMP2 might be used by peek_char_back. */ + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + } + else + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + } add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32)); jump[0] = JUMP(SLJIT_JUMP); JUMPHERE(jump[1]); @@ -8367,11 +7889,16 @@ switch(type) length = GET(cc, 0); if (length == 0) return cc + LINK_SIZE; - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } + else + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); #ifdef SUPPORT_UNICODE if (common->utf) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, length); label = LABEL(); add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0)); @@ -8382,9 +7909,8 @@ switch(type) else #endif { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0)); } check_start_used_ptr(common); return cc + LINK_SIZE; @@ -8402,12 +7928,12 @@ static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc) PCRE2_SPTR start_subject = args->begin; PCRE2_SPTR end_subject = args->end; int lgb, rgb, ricount; -PCRE2_SPTR prevcc, startcc, bptr; +PCRE2_SPTR prevcc, endcc, bptr; BOOL first = TRUE; uint32_t c; prevcc = cc; -startcc = NULL; +endcc = NULL; do { GETCHARINC(c, cc); @@ -8416,7 +7942,7 @@ do if (first) { lgb = rgb; - startcc = cc; + endcc = cc; first = FALSE; continue; } @@ -8455,25 +7981,27 @@ do lgb != ucp_gbExtended_Pictographic) lgb = rgb; - prevcc = startcc; - startcc = cc; + prevcc = endcc; + endcc = cc; } while (cc < end_subject); -return startcc; +return endcc; } +#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ + static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc) { PCRE2_SPTR start_subject = args->begin; PCRE2_SPTR end_subject = args->end; int lgb, rgb, ricount; -PCRE2_SPTR prevcc, startcc, bptr; +PCRE2_SPTR prevcc, endcc, bptr; BOOL first = TRUE; uint32_t c; prevcc = cc; -startcc = NULL; +endcc = NULL; do { GETCHARINC_INVALID(c, cc, end_subject, break); @@ -8482,7 +8010,7 @@ do if (first) { lgb = rgb; - startcc = cc; + endcc = cc; first = FALSE; continue; } @@ -8520,16 +8048,14 @@ do lgb != ucp_gbExtended_Pictographic) lgb = rgb; - prevcc = startcc; - startcc = cc; + prevcc = endcc; + endcc = cc; } while (cc < end_subject); -return startcc; +return endcc; } -#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ - static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc) { PCRE2_SPTR start_subject = args->begin; @@ -8538,7 +8064,10 @@ int lgb, rgb, ricount; PCRE2_SPTR bptr; uint32_t c; +/* Patch by PH */ +/* GETCHARINC(c, cc); */ c = *cc++; + #if PCRE2_CODE_UNIT_WIDTH == 32 if (c >= 0x110000) return NULL; @@ -8800,8 +8329,10 @@ switch(type) if (common->invalid_utf) add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); #else - sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_extuni_no_utf)); - add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, + common->invalid_utf ? SLJIT_FUNC_OFFSET(do_extuni_utf_invalid) : SLJIT_FUNC_OFFSET(do_extuni_no_utf)); + if (!common->utf || common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); #endif OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); @@ -9198,8 +8729,6 @@ if (common->utf && *cc == OP_REFI) CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); // PH hacking -//fprintf(stderr, "~~E\n"); - OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); @@ -10759,10 +10288,23 @@ if (ket != OP_KET || bra != OP_BRA) if (offset != 0) stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); +/* Skip and count the other alternatives. */ +i = 1; +while (*cc == OP_ALT) + { + cc += GET(cc, 1); + i++; + } + if (has_alternatives) { if (opcode != OP_ONCE) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + { + if (i <= 3) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); + else + BACKTRACK_AS(bracket_backtrack)->u.matching_put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize)); + } if (ket != OP_KETRMAX) BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); } @@ -10851,9 +10393,6 @@ if (bra == OP_BRAMINZERO) if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO) count_match(common); -/* Skip the other alternatives. */ -while (*cc == OP_ALT) - cc += GET(cc, 1); cc += 1 + LINK_SIZE; if (opcode == OP_ONCE) @@ -11412,174 +10951,232 @@ switch(opcode) JUMPTO(SLJIT_JUMP, label); if (jump != NULL) JUMPHERE(jump); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; } - else +#ifdef SUPPORT_UNICODE + else if (type == OP_ALLANY && !common->invalid_utf) +#else + else if (type == OP_ALLANY) +#endif { - charpos_enabled = FALSE; - charpos_char = 0; - charpos_othercasebit = 0; + if (opcode == OP_STAR) + { + if (private_data_ptr == 0) + allocate_stack(common, 2); + + OP1(SLJIT_MOV, base, offset0, STR_END, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + + OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); + process_partial_match(common); - if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI)) + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; + } +#ifdef SUPPORT_UNICODE + else if (!common->utf) +#else + else +#endif { - charpos_enabled = TRUE; + if (private_data_ptr == 0) + allocate_stack(common, 2); + + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max)); + + if (common->mode == PCRE2_JIT_COMPLETE) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); + CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + } + else + { + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0); + process_partial_match(common); + JUMPHERE(jump); + } + + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + break; + } + } + + charpos_enabled = FALSE; + charpos_char = 0; + charpos_othercasebit = 0; + + if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI)) + { #ifdef SUPPORT_UNICODE - charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]); + charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]); +#else + charpos_enabled = TRUE; #endif - if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1)) - { - charpos_othercasebit = char_get_othercase_bit(common, end + 1); - if (charpos_othercasebit == 0) - charpos_enabled = FALSE; - } + if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1)) + { + charpos_othercasebit = char_get_othercase_bit(common, end + 1); + if (charpos_othercasebit == 0) + charpos_enabled = FALSE; + } - if (charpos_enabled) - { - charpos_char = end[1]; - /* Consumpe the OP_CHAR opcode. */ - end += 2; + if (charpos_enabled) + { + charpos_char = end[1]; + /* Consumpe the OP_CHAR opcode. */ + end += 2; #if PCRE2_CODE_UNIT_WIDTH == 8 - SLJIT_ASSERT((charpos_othercasebit >> 8) == 0); + SLJIT_ASSERT((charpos_othercasebit >> 8) == 0); #elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 - SLJIT_ASSERT((charpos_othercasebit >> 9) == 0); - if ((charpos_othercasebit & 0x100) != 0) - charpos_othercasebit = (charpos_othercasebit & 0xff) << 8; + SLJIT_ASSERT((charpos_othercasebit >> 9) == 0); + if ((charpos_othercasebit & 0x100) != 0) + charpos_othercasebit = (charpos_othercasebit & 0xff) << 8; #endif - if (charpos_othercasebit != 0) - charpos_char |= charpos_othercasebit; + if (charpos_othercasebit != 0) + charpos_char |= charpos_othercasebit; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char; - BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit; - } + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit; } + } - if (charpos_enabled) + if (charpos_enabled) + { + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1); + + /* Search the first instance of charpos_char. */ + jump = JUMP(SLJIT_JUMP); + label = LABEL(); + if (opcode == OP_UPTO) { - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); + } + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + JUMPHERE(jump); - /* Search the first instance of charpos_char. */ - jump = JUMP(SLJIT_JUMP); - label = LABEL(); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); - } - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - JUMPHERE(jump); + detect_partial_match(common, &backtrack->topbacktracks); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); - detect_partial_match(common, &backtrack->topbacktracks); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (charpos_othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + } - if (private_data_ptr == 0) - allocate_stack(common, 2); + /* Search the last instance of charpos_char. */ + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + detect_partial_match(common, &no_match); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + if (opcode == OP_STAR) + { + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); - } - - /* Search the last instance of charpos_char. */ - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, FALSE); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - detect_partial_match(common, &no_match); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (charpos_othercasebit != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); - if (opcode == OP_STAR) - { - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - } - else - { - jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPHERE(jump); - } - - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else - JUMPTO(SLJIT_JUMP, label); - - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } + else + { + jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPHERE(jump); } -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - else if (common->utf) + + if (opcode == OP_UPTO) { - if (private_data_ptr == 0) - allocate_stack(common, 2); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else + JUMPTO(SLJIT_JUMP, label); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + else if (common->utf) + { + if (private_data_ptr == 0) + allocate_stack(common, 2); - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else - JUMPTO(SLJIT_JUMP, label); + detect_partial_match(common, &no_match); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); - } -#endif - else + if (opcode == OP_UPTO) { - if (private_data_ptr == 0) - allocate_stack(common, 2); + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + } - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - if (opcode == OP_UPTO) - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + detect_partial_match_to(common, label); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - label = LABEL(); - detect_partial_match(common, &no_match); - compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - if (opcode == OP_UPTO) - { - OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - } - else - JUMPTO(SLJIT_JUMP, label); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + } +#endif + else + { + if (private_data_ptr == 0) + allocate_stack(common, 2); - set_jumps(no_char1_match, LABEL()); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - set_jumps(no_match, LABEL()); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + + detect_partial_match(common, &no_match); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); } + + detect_partial_match_to(common, label); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + set_jumps(no_char1_match, LABEL()); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); } + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; @@ -11616,25 +11213,47 @@ switch(opcode) break; case OP_POSSTAR: +#if defined SUPPORT_UNICODE + if (type == OP_ALLANY && !common->invalid_utf) +#else + if (type == OP_ALLANY) +#endif + { + OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); + process_partial_match(common); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0); + break; + } + #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 if (common->utf) { OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + detect_partial_match(common, &no_match); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, label); + detect_partial_match_to(common, label); + set_jumps(no_match, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); if (fast_str_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + { + if (tmp_base == TMP3) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, TMP3, 0); + else + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + } break; } #endif - label = LABEL(); detect_partial_match(common, &no_match); + label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); - JUMPTO(SLJIT_JUMP, label); + detect_partial_match_to(common, label); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_char1_match, LABEL()); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_match, LABEL()); @@ -11649,23 +11268,52 @@ switch(opcode) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + + detect_partial_match(common, &no_match); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + detect_partial_match_to(common, label); + set_jumps(no_match, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); break; } #endif + + if (type == OP_ALLANY) + { + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max)); + + if (common->mode == PCRE2_JIT_COMPLETE) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); + CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + } + else + { + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0); + process_partial_match(common); + JUMPHERE(jump); + } + + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + break; + } + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - label = LABEL(); + detect_partial_match(common, &no_match); + label = LABEL(); compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + detect_partial_match_to(common, label); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_char1_match, LABEL()); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); set_jumps(no_match, LABEL()); @@ -11719,8 +11367,15 @@ if (common->accept_label == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0))); else CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); -OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); + +if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options)); + } +else + OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options)); + OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO)); OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); @@ -11728,7 +11383,8 @@ if (common->accept_label == NULL) add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO)); else JUMPTO(SLJIT_ZERO, common->accept_label); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str)); if (common->accept_label == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); else @@ -11778,10 +11434,11 @@ if (opcode == OP_SKIP) if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG) { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + if (HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); } return ccend; @@ -12072,11 +11729,12 @@ while (cc < ccend) SLJIT_ASSERT(common->mark_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); allocate_stack(common, common->has_skip_arg ? 5 : 1); - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + if (HAS_VIRTUAL_REGISTERS) + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); if (common->has_skip_arg) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); @@ -12403,16 +12061,15 @@ PCRE2_SPTR ccprev; PCRE2_UCHAR bra = OP_BRA; PCRE2_UCHAR ket; assert_backtrack *assert; -sljit_uw *next_update_addr = NULL; BOOL has_alternatives; BOOL needs_control_head = FALSE; struct sljit_jump *brazero = NULL; -struct sljit_jump *alt1 = NULL; -struct sljit_jump *alt2 = NULL; +struct sljit_jump *next_alt = NULL; struct sljit_jump *once = NULL; struct sljit_jump *cond = NULL; struct sljit_label *rmin_label = NULL; struct sljit_label *exact_label = NULL; +struct sljit_put_label *put_label = NULL; if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) { @@ -12561,7 +12218,7 @@ else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND) free_stack(common, 1); alt_max = 2; - alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); + next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); } } else if (has_alternatives) @@ -12569,21 +12226,15 @@ else if (has_alternatives) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); - if (alt_max > 4) + if (alt_max > 3) { - /* Table jump if alt_max is greater than 4. */ - next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw)); - if (SLJIT_UNLIKELY(next_update_addr == NULL)) - return; - sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr); - add_label_addr(common, next_update_addr++); + sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0); + + SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_put_label); + sljit_set_put_label(CURRENT_AS(bracket_backtrack)->u.matching_put_label, LABEL()); } else - { - if (alt_max == 4) - alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); - alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); - } + next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); } COMPILE_BACKTRACKINGPATH(current->top); @@ -12620,7 +12271,7 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) if (has_alternatives) { - alt_count = sizeof(sljit_uw); + alt_count = 1; do { current->top = NULL; @@ -12699,7 +12350,12 @@ if (has_alternatives) stacksize = match_capture_common(common, stacksize, offset, private_data_ptr); if (opcode != OP_ONCE) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count); + { + if (alt_max <= 3) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count); + else + put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize)); + } if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0) { @@ -12712,24 +12368,18 @@ if (has_alternatives) if (opcode != OP_ONCE) { - if (alt_max > 4) - add_label_addr(common, next_update_addr++); - else + if (alt_max <= 3) { - if (alt_count != 2 * sizeof(sljit_uw)) - { - JUMPHERE(alt1); - if (alt_max == 3 && alt_count == sizeof(sljit_uw)) - alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); - } - else + JUMPHERE(next_alt); + alt_count++; + if (alt_count < alt_max) { - JUMPHERE(alt2); - if (alt_max == 4) - alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw)); + SLJIT_ASSERT(alt_count == 2 && alt_max == 3); + next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1); } } - alt_count += sizeof(sljit_uw); + else + sljit_set_put_label(put_label, LABEL()); } COMPILE_BACKTRACKINGPATH(current->top); @@ -13219,11 +12869,10 @@ int private_data_size = get_recurse_data_length(common, ccbegin, ccend, &needs_c int alt_count, alt_max, local_size; backtrack_common altbacktrack; jump_list *match = NULL; -sljit_uw *next_update_addr = NULL; -struct sljit_jump *alt1 = NULL; -struct sljit_jump *alt2 = NULL; +struct sljit_jump *next_alt = NULL; struct sljit_jump *accept_exit = NULL; struct sljit_label *quit; +struct sljit_put_label *put_label; /* Recurse captures then. */ common->then_trap = NULL; @@ -13284,7 +12933,12 @@ while (1) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr); if (alt_max > 1 || has_accept) - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count); + { + if (alt_max > 3) + put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(1)); + else + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count); + } add_jump(compiler, &match, JUMP(SLJIT_JUMP)); @@ -13298,7 +12952,7 @@ while (1) sljit_emit_fast_enter(compiler, TMP1, 0); if (has_accept) - accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_max * sizeof (sljit_sw)); + accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); /* Save return address. */ @@ -13311,44 +12965,30 @@ while (1) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); free_stack(common, 2); - if (alt_max > 4) + if (alt_max > 3) { - /* Table jump if alt_max is greater than 4. */ - next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw)); - if (SLJIT_UNLIKELY(next_update_addr == NULL)) - return; - sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr); - add_label_addr(common, next_update_addr++); + sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0); + sljit_set_put_label(put_label, LABEL()); } else - { - if (alt_max == 4) - alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); - alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw)); - } + next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0); } else free_stack(common, has_accept ? 2 : 1); } - else if (alt_max > 4) - add_label_addr(common, next_update_addr++); + else if (alt_max > 3) + sljit_set_put_label(put_label, LABEL()); else { - if (alt_count != 2 * sizeof(sljit_uw)) + JUMPHERE(next_alt); + if (alt_count + 1 < alt_max) { - JUMPHERE(alt1); - if (alt_max == 3 && alt_count == sizeof(sljit_uw)) - alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw)); - } - else - { - JUMPHERE(alt2); - if (alt_max == 4) - alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw)); + SLJIT_ASSERT(alt_count == 1 && alt_max == 3); + next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1); } } - alt_count += sizeof(sljit_uw); + alt_count++; compile_backtrackingpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) @@ -13409,7 +13049,7 @@ if (common->accept != NULL) OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0); allocate_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1); } set_jumps(match, LABEL()); @@ -13444,7 +13084,6 @@ executable_functions *functions; void *executable_func; sljit_uw executable_size; sljit_uw total_length; -label_addr_list *label_addr; struct sljit_label *mainloop_label = NULL; struct sljit_label *continue_match_label; struct sljit_label *empty_match_found_label = NULL; @@ -13459,6 +13098,14 @@ struct sljit_jump *end_anchor_failed = NULL; SLJIT_ASSERT(tables); +#if HAS_VIRTUAL_REGISTERS == 1 +SLJIT_ASSERT(sljit_get_register_index(TMP3) < 0 && sljit_get_register_index(ARGUMENTS) < 0 && sljit_get_register_index(RETURN_ADDR) < 0); +#elif HAS_VIRTUAL_REGISTERS == 0 +SLJIT_ASSERT(sljit_get_register_index(TMP3) >= 0 && sljit_get_register_index(ARGUMENTS) >= 0 && sljit_get_register_index(RETURN_ADDR) >= 0); +#else +#error "Invalid value for HAS_VIRTUAL_REGISTERS" +#endif + memset(&rootbacktrack, 0, sizeof(backtrack_common)); memset(common, 0, sizeof(compiler_common)); common->re = re; @@ -13476,6 +13123,7 @@ common->fcc = tables + fcc_offset; common->lcc = (sljit_sw)(tables + lcc_offset); common->mode = mode; common->might_be_empty = re->minlength == 0; +common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY) != 0; common->nltype = NLTYPE_FIXED; switch(re->newline_convention) { @@ -14028,13 +13676,8 @@ SLJIT_FREE(common->private_data_ptrs, allocator_data); executable_func = sljit_generate_code(compiler); executable_size = sljit_get_generated_code_size(compiler); -label_addr = common->label_addrs; -while (label_addr != NULL) - { - *label_addr->update_addr = sljit_get_label_addr(label_addr->label); - label_addr = label_addr->next; - } sljit_free_compiler(compiler); + if (executable_func == NULL) { PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data); @@ -14097,18 +13740,12 @@ Returns: 0: success or (*NOJIT) was used PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_jit_compile(pcre2_code *code, uint32_t options) { -#ifndef SUPPORT_JIT - -(void)code; -(void)options; -return PCRE2_ERROR_JIT_BADOPTION; - -#else /* SUPPORT_JIT */ - pcre2_real_code *re = (pcre2_real_code *)code; -executable_functions *functions; -uint32_t excluded_options; -int result; + +#ifdef SUPPORT_JIT +executable_functions *functions = (executable_functions *)re->executable_jit; +static int executable_allocator_is_working = 0; +#endif if (code == NULL) return PCRE2_ERROR_NULL; @@ -14116,30 +13753,98 @@ if (code == NULL) if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0) return PCRE2_ERROR_JIT_BADOPTION; +/* Support for invalid UTF was first introduced in JIT, with the option +PCRE2_JIT_INVALID_UTF. Later, support was added to the interpreter, and the +compile-time option PCRE2_MATCH_INVALID_UTF was created. This is now the +preferred feature, with the earlier option deprecated. However, for backward +compatibility, if the earlier option is set, it forces the new option so that +if JIT matching falls back to the interpreter, there is still support for +invalid UTF. However, if this function has already been successfully called +without PCRE2_JIT_INVALID_UTF and without PCRE2_MATCH_INVALID_UTF (meaning that +non-invalid-supporting JIT code was compiled), give an error. + +If in the future support for PCRE2_JIT_INVALID_UTF is withdrawn, the following +actions are needed: + + 1. Remove the definition from pcre2.h.in and from the list in + PUBLIC_JIT_COMPILE_OPTIONS above. + + 2. Replace PCRE2_JIT_INVALID_UTF with a local flag in this module. + + 3. Replace PCRE2_JIT_INVALID_UTF in pcre2_jit_test.c. + + 4. Delete the following short block of code. The setting of "re" and + "functions" can be moved into the JIT-only block below, but if that is + done, (void)re and (void)functions will be needed in the non-JIT case, to + avoid compiler warnings. +*/ + +if ((options & PCRE2_JIT_INVALID_UTF) != 0) + { + if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) == 0) + { +#ifdef SUPPORT_JIT + if (functions != NULL) return PCRE2_ERROR_JIT_BADOPTION; +#endif + re->overall_options |= PCRE2_MATCH_INVALID_UTF; + } + } + +/* The above tests are run with and without JIT support. This means that +PCRE2_JIT_INVALID_UTF propagates back into the regex options (ensuring +interpreter support) even in the absence of JIT. But now, if there is no JIT +support, give an error return. */ + +#ifndef SUPPORT_JIT +return PCRE2_ERROR_JIT_BADOPTION; +#else /* SUPPORT_JIT */ + +/* There is JIT support. Do the necessary. */ + if ((re->flags & PCRE2_NOJIT) != 0) return 0; -functions = (executable_functions *)re->executable_jit; +if (executable_allocator_is_working == 0) + { + /* Checks whether the executable allocator is working. This check + might run multiple times in multi-threaded environments, but the + result should not be affected by it. */ + void *ptr = SLJIT_MALLOC_EXEC(32); + + executable_allocator_is_working = -1; + + if (ptr != NULL) + { + SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr)); + executable_allocator_is_working = 1; + } + } + +if (executable_allocator_is_working < 0) + return PCRE2_ERROR_NOMEMORY; + +if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0) + options |= PCRE2_JIT_INVALID_UTF; if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL || functions->executable_funcs[0] == NULL)) { - excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD); - result = jit_compile(code, options & ~excluded_options); + uint32_t excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD); + int result = jit_compile(code, options & ~excluded_options); if (result != 0) return result; } if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL || functions->executable_funcs[1] == NULL)) { - excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD); - result = jit_compile(code, options & ~excluded_options); + uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD); + int result = jit_compile(code, options & ~excluded_options); if (result != 0) return result; } if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL || functions->executable_funcs[2] == NULL)) { - excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT); - result = jit_compile(code, options & ~excluded_options); + uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT); + int result = jit_compile(code, options & ~excluded_options); if (result != 0) return result; } diff --git a/ext/pcre/pcre2lib/pcre2_jit_match.c b/ext/pcre/pcre2lib/pcre2_jit_match.c index eee038644dd0d..7e13b8cfeedca 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_match.c +++ b/ext/pcre/pcre2lib/pcre2_jit_match.c @@ -74,7 +74,6 @@ return executable_func(arguments); options option bits match_data points to a match_data block mcontext points to a match context - jit_stack points to a JIT stack Returns: > 0 => success; value is the number of ovector pairs filled = 0 => success, but ovector is not big enough diff --git a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h new file mode 100644 index 0000000000000..55b1f32ac9cef --- /dev/null +++ b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h @@ -0,0 +1,321 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + This module by Zoltan Herczeg and Sebastian Pop + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +# if defined(FFCS) +# if defined(FF_UTF) +# define FF_FUN ffcs_utf +# else +# define FF_FUN ffcs +# endif + +# elif defined(FFCS_2) +# if defined(FF_UTF) +# define FF_FUN ffcs_2_utf +# else +# define FF_FUN ffcs_2 +# endif + +# elif defined(FFCS_MASK) +# if defined(FF_UTF) +# define FF_FUN ffcs_mask_utf +# else +# define FF_FUN ffcs_mask +# endif + +# elif defined(FFCPS_0) +# if defined (FF_UTF) +# define FF_FUN ffcps_0_utf +# else +# define FF_FUN ffcps_0 +# endif + +# elif defined (FFCPS_1) +# if defined (FF_UTF) +# define FF_FUN ffcps_1_utf +# else +# define FF_FUN ffcps_1 +# endif + +# elif defined (FFCPS_DEFAULT) +# if defined (FF_UTF) +# define FF_FUN ffcps_default_utf +# else +# define FF_FUN ffcps_default +# endif +# endif + +static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars) +#undef FF_FUN +{ +quad_word qw; +int_char ic; +ic.x = chars; + +#if defined(FFCS) +sljit_u8 c1 = ic.c.c1; +vect_t vc1 = VDUPQ(c1); + +#elif defined(FFCS_2) +sljit_u8 c1 = ic.c.c1; +vect_t vc1 = VDUPQ(c1); +sljit_u8 c2 = ic.c.c2; +vect_t vc2 = VDUPQ(c2); + +#elif defined(FFCS_MASK) +sljit_u8 c1 = ic.c.c1; +vect_t vc1 = VDUPQ(c1); +sljit_u8 mask = ic.c.c2; +vect_t vmask = VDUPQ(mask); +#endif + +#if defined(FFCPS) +compare_type compare1_type = compare_match1; +compare_type compare2_type = compare_match1; +vect_t cmp1a, cmp1b, cmp2a, cmp2b; +const sljit_u32 diff = IN_UCHARS(offs1 - offs2); +PCRE2_UCHAR char1a = ic.c.c1; +PCRE2_UCHAR char2a = ic.c.c3; + +# ifdef FFCPS_CHAR1A2A +cmp1a = VDUPQ(char1a); +cmp2a = VDUPQ(char2a); +# else +PCRE2_UCHAR char1b = ic.c.c2; +PCRE2_UCHAR char2b = ic.c.c4; +if (char1a == char1b) + cmp1a = VDUPQ(char1a); +else + { + sljit_u32 bit1 = char1a ^ char1b; + if (is_powerof2(bit1)) + { + compare1_type = compare_match1i; + cmp1a = VDUPQ(char1a | bit1); + cmp1b = VDUPQ(bit1); + } + else + { + compare1_type = compare_match2; + cmp1a = VDUPQ(char1a); + cmp1b = VDUPQ(char1b); + } + } + +if (char2a == char2b) + cmp2a = VDUPQ(char2a); +else + { + sljit_u32 bit2 = char2a ^ char2b; + if (is_powerof2(bit2)) + { + compare2_type = compare_match1i; + cmp2a = VDUPQ(char2a | bit2); + cmp2b = VDUPQ(bit2); + } + else + { + compare2_type = compare_match2; + cmp2a = VDUPQ(char2a); + cmp2b = VDUPQ(char2b); + } + } +# endif + +str_ptr += IN_UCHARS(offs1); +#endif + +#if PCRE2_CODE_UNIT_WIDTH != 8 +vect_t char_mask = VDUPQ(0xff); +#endif + +#if defined(FF_UTF) +restart:; +#endif + +#if defined(FFCPS) +sljit_u8 *p1 = str_ptr - diff; +#endif +sljit_s32 align_offset = ((uint64_t)str_ptr & 0xf); +str_ptr = (sljit_u8 *) ((uint64_t)str_ptr & ~0xf); +vect_t data = VLD1Q(str_ptr); +#if PCRE2_CODE_UNIT_WIDTH != 8 +data = VANDQ(data, char_mask); +#endif + +#if defined(FFCS) +vect_t eq = VCEQQ(data, vc1); + +#elif defined(FFCS_2) +vect_t eq1 = VCEQQ(data, vc1); +vect_t eq2 = VCEQQ(data, vc2); +vect_t eq = VORRQ(eq1, eq2); + +#elif defined(FFCS_MASK) +vect_t eq = VORRQ(data, vmask); +eq = VCEQQ(eq, vc1); + +#elif defined(FFCPS) +# if defined(FFCPS_DIFF1) +vect_t prev_data = data; +# endif + +vect_t data2; +if (p1 < str_ptr) + { + data2 = VLD1Q(str_ptr - diff); +#if PCRE2_CODE_UNIT_WIDTH != 8 + data2 = VANDQ(data2, char_mask); +#endif + } +else + data2 = shift_left_n_lanes(data, offs1 - offs2); + +data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); +data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); +vect_t eq = VANDQ(data, data2); +#endif + +VST1Q(qw.mem, eq); +/* Ignore matches before the first STR_PTR. */ +if (align_offset < 8) + { + qw.dw[0] >>= align_offset * 8; + if (qw.dw[0]) + { + str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8; + goto match; + } + if (qw.dw[1]) + { + str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; + goto match; + } + } +else + { + qw.dw[1] >>= (align_offset - 8) * 8; + if (qw.dw[1]) + { + str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8; + goto match; + } + } +str_ptr += 16; + +while (str_ptr < str_end) + { + vect_t orig_data = VLD1Q(str_ptr); +#if PCRE2_CODE_UNIT_WIDTH != 8 + orig_data = VANDQ(orig_data, char_mask); +#endif + data = orig_data; + +#if defined(FFCS) + eq = VCEQQ(data, vc1); + +#elif defined(FFCS_2) + eq1 = VCEQQ(data, vc1); + eq2 = VCEQQ(data, vc2); + eq = VORRQ(eq1, eq2); + +#elif defined(FFCS_MASK) + eq = VORRQ(data, vmask); + eq = VCEQQ(eq, vc1); +#endif + +#if defined(FFCPS) +# if defined (FFCPS_DIFF1) + data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1); +# else + data2 = VLD1Q(str_ptr - diff); +# if PCRE2_CODE_UNIT_WIDTH != 8 + data2 = VANDQ(data2, char_mask); +# endif +# endif + +# ifdef FFCPS_CHAR1A2A + data = VCEQQ(data, cmp1a); + data2 = VCEQQ(data2, cmp2a); +# else + data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); + data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); +# endif + + eq = VANDQ(data, data2); +#endif + + VST1Q(qw.mem, eq); + if (qw.dw[0]) + str_ptr += __builtin_ctzll(qw.dw[0]) / 8; + else if (qw.dw[1]) + str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; + else { + str_ptr += 16; +#if defined (FFCPS_DIFF1) + prev_data = orig_data; +#endif + continue; + } + +match:; + if (str_ptr >= str_end) + /* Failed match. */ + return NULL; + +#if defined(FF_UTF) + if (utf_continue(str_ptr + IN_UCHARS(-offs1))) + { + /* Not a match. */ + str_ptr += IN_UCHARS(1); + goto restart; + } +#endif + + /* Match. */ +#if defined (FFCPS) + str_ptr -= IN_UCHARS(offs1); +#endif + return str_ptr; + } + +/* Failed match. */ +return NULL; +} diff --git a/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h b/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h new file mode 100644 index 0000000000000..f7d56b29f8d07 --- /dev/null +++ b/ext/pcre/pcre2lib/pcre2_jit_simd_inc.h @@ -0,0 +1,993 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + This module by Zoltan Herczeg + Original API code Copyright (c) 1997-2012 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg) +{ +#if PCRE2_CODE_UNIT_WIDTH == 8 +OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0); +return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80); +#elif PCRE2_CODE_UNIT_WIDTH == 16 +OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00); +return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00); +#else +#error "Unknown code width" +#endif +} +#endif + +static sljit_s32 character_to_int32(PCRE2_UCHAR chr) +{ +sljit_u32 value = chr; +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define SSE2_COMPARE_TYPE_INDEX 0 +return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value); +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#define SSE2_COMPARE_TYPE_INDEX 1 +return (sljit_s32)((value << 16) | value); +#elif PCRE2_CODE_UNIT_WIDTH == 32 +#define SSE2_COMPARE_TYPE_INDEX 2 +return (sljit_s32)(value); +#else +#error "Unsupported unit width" +#endif +} + +static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg, sljit_s8 offset) +{ +sljit_u8 instruction[5]; + +SLJIT_ASSERT(dst_xmm_reg < 8); +SLJIT_ASSERT(src_general_reg < 8); + +/* MOVDQA xmm1, xmm2/m128 */ +instruction[0] = ((sljit_u8)offset & 0xf) == 0 ? 0x66 : 0xf3; +instruction[1] = 0x0f; +instruction[2] = 0x6f; + +if (offset == 0) + { + instruction[3] = (dst_xmm_reg << 3) | src_general_reg; + sljit_emit_op_custom(compiler, instruction, 4); + return; + } + +instruction[3] = 0x40 | (dst_xmm_reg << 3) | src_general_reg; +instruction[4] = (sljit_u8)offset; +sljit_emit_op_custom(compiler, instruction, 5); +} + +typedef enum { + sse2_compare_match1, + sse2_compare_match1i, + sse2_compare_match2, +} sse2_compare_type; + +static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, sse2_compare_type compare_type, + int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) +{ +sljit_u8 instruction[4]; +instruction[0] = 0x66; +instruction[1] = 0x0f; + +SLJIT_ASSERT(step >= 0 && step <= 3); + +if (compare_type != sse2_compare_match2) + { + if (step == 0) + { + if (compare_type == sse2_compare_match1i) + { + /* POR xmm1, xmm2/m128 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0xeb; + instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + return; + } + + if (step != 2) + return; + + /* PCMPEQB/W/D xmm1, xmm2/m128 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; + sljit_emit_op_custom(compiler, instruction, 4); + return; + } + +switch (step) + { + case 0: + /* MOVDQA xmm1, xmm2/m128 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0x6f; + instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind; + sljit_emit_op_custom(compiler, instruction, 4); + return; + + case 1: + /* PCMPEQB/W/D xmm1, xmm2/m128 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; + sljit_emit_op_custom(compiler, instruction, 4); + return; + + case 2: + /* PCMPEQB/W/D xmm1, xmm2/m128 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind; + sljit_emit_op_custom(compiler, instruction, 4); + return; + + case 3: + /* POR xmm1, xmm2/m128 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0xeb; + instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind; + sljit_emit_op_custom(compiler, instruction, 4); + return; + } +} + +#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) + +static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) +{ +DEFINE_COMPILER; +struct sljit_label *start; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_label *restart; +#endif +struct sljit_jump *quit; +struct sljit_jump *partial_quit[2]; +sse2_compare_type compare_type = sse2_compare_match1; +sljit_u8 instruction[8]; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); +sljit_s32 data_ind = 0; +sljit_s32 tmp_ind = 1; +sljit_s32 cmp1_ind = 2; +sljit_s32 cmp2_ind = 3; +sljit_u32 bit = 0; +int i; + +SLJIT_UNUSED_ARG(offset); + +if (char1 != char2) + { + bit = char1 ^ char2; + compare_type = sse2_compare_match1i; + + if (!is_powerof2(bit)) + { + bit = 0; + compare_type = sse2_compare_match2; + } + } + +partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, &common->failed_match, partial_quit[0]); + +/* First part (unaligned start) */ + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); + +SLJIT_ASSERT(tmp1_reg_ind < 8); + +/* MOVD xmm, r/m32 */ +instruction[0] = 0x66; +instruction[1] = 0x0f; +instruction[2] = 0x6e; +instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (char1 != char2) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + + /* MOVD xmm, r/m32 */ + instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); + +/* PSHUFD xmm1, xmm2/m128, imm8 */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0x70; +instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind; +instruction[4] = 0; +sljit_emit_op_custom(compiler, instruction, 5); + +if (char1 != char2) + { + /* PSHUFD xmm1, xmm2/m128, imm8 */ + instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +restart = LABEL(); +#endif +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); + +load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +for (i = 0; i < 4; i++) + fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* PMOVMSKB reg, xmm */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Second part (aligned) */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); + +partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, &common->failed_match, partial_quit[1]); + +load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +for (i = 0; i < 4; i++) + fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* PMOVMSKB reg, xmm */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(quit); + +/* BSF r32, r/m32 */ +instruction[0] = 0x0f; +instruction[1] = 0xbc; +instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind; +sljit_emit_op_custom(compiler, instruction, 3); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +if (common->mode != PCRE2_JIT_COMPLETE) + { + JUMPHERE(partial_quit[0]); + JUMPHERE(partial_quit[1]); + OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); + CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + } +else + add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && offset > 0) + { + SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); + + quit = jump_if_utf_char_start(compiler, TMP1); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, restart); + + JUMPHERE(quit); + } +#endif +} + +#ifndef _WIN64 + +static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void) +{ +#if PCRE2_CODE_UNIT_WIDTH == 8 +return 15; +#elif PCRE2_CODE_UNIT_WIDTH == 16 +return 7; +#elif PCRE2_CODE_UNIT_WIDTH == 32 +return 3; +#else +#error "Unsupported unit width" +#endif +} + +#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) + +static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1, + PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b) +{ +DEFINE_COMPILER; +sse2_compare_type compare1_type = sse2_compare_match1; +sse2_compare_type compare2_type = sse2_compare_match1; +sljit_u32 bit1 = 0; +sljit_u32 bit2 = 0; +sljit_u32 diff = IN_UCHARS(offs1 - offs2); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); +sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); +sljit_s32 data1_ind = 0; +sljit_s32 data2_ind = 1; +sljit_s32 tmp1_ind = 2; +sljit_s32 tmp2_ind = 3; +sljit_s32 cmp1a_ind = 4; +sljit_s32 cmp1b_ind = 5; +sljit_s32 cmp2a_ind = 6; +sljit_s32 cmp2b_ind = 7; +struct sljit_label *start; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_label *restart; +#endif +struct sljit_jump *jump[2]; +sljit_u8 instruction[8]; +int i; + +SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2); +SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); +SLJIT_ASSERT(tmp1_reg_ind < 8 && tmp2_reg_ind == 1); + +/* Initialize. */ +if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); + + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); + CMOV(SLJIT_LESS, STR_END, TMP1, 0); + } + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +/* MOVD xmm, r/m32 */ +instruction[0] = 0x66; +instruction[1] = 0x0f; +instruction[2] = 0x6e; + +if (char1a == char1b) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a)); +else + { + bit1 = char1a ^ char1b; + if (is_powerof2(bit1)) + { + compare1_type = sse2_compare_match1i; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1)); + } + else + { + compare1_type = sse2_compare_match2; + bit1 = 0; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b)); + } + } + +instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_reg_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (char1a != char1b) + { + instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_reg_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +if (char2a == char2b) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); +else + { + bit2 = char2a ^ char2b; + if (is_powerof2(bit2)) + { + compare2_type = sse2_compare_match1i; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2)); + } + else + { + compare2_type = sse2_compare_match2; + bit2 = 0; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b)); + } + } + +instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_reg_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (char2a != char2b) + { + instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_reg_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PSHUFD xmm1, xmm2/m128, imm8 */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0x70; +instruction[4] = 0; + +instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind; +sljit_emit_op_custom(compiler, instruction, 5); + +if (char1a != char1b) + { + instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + +instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind; +sljit_emit_op_custom(compiler, instruction, 5); + +if (char2a != char2b) + { + instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +restart = LABEL(); +#endif + +OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff); +OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); + +load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0); + +jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0); + +load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff); +jump[1] = JUMP(SLJIT_JUMP); + +JUMPHERE(jump[0]); + +/* MOVDQA xmm1, xmm2/m128 */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0x6f; +instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +/* PSLLDQ xmm1, imm8 */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0x73; +instruction[3] = 0xc0 | (7 << 3) | data2_ind; +instruction[4] = diff; +sljit_emit_op_custom(compiler, instruction, 5); + +JUMPHERE(jump[1]); + +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); + +for (i = 0; i < 4; i++) + { + fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind); + fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); + } + +/* PAND xmm1, xmm2/m128 */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xdb; +instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +/* PMOVMSKB reg, xmm */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0; +sljit_emit_op_custom(compiler, instruction, 4); + +/* Ignore matches before the first STR_PTR. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +jump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Main loop. */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0); +load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff); + +for (i = 0; i < 4; i++) + { + fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind); + fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); + } + +/* PAND xmm1, xmm2/m128 */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xdb; +instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +/* PMOVMSKB reg, xmm */ +/* instruction[0] = 0x66; */ +/* instruction[1] = 0x0f; */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0; +sljit_emit_op_custom(compiler, instruction, 4); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(jump[0]); + +/* BSF r32, r/m32 */ +instruction[0] = 0x0f; +instruction[1] = 0xbc; +instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind; +sljit_emit_op_custom(compiler, instruction, 3); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +if (common->match_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1)); + + jump[0] = jump_if_utf_char_start(compiler, TMP1); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart); + + add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[0]); + } +#endif + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); + +if (common->match_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +} + +#endif /* !_WIN64 */ + +#undef SSE2_COMPARE_TYPE_INDEX + +#endif /* SLJIT_CONFIG_X86 && !SUPPORT_VALGRIND */ + +#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 && (defined __ARM_NEON || defined __ARM_NEON__)) + +#include + +typedef union { + unsigned int x; + struct { unsigned char c1, c2, c3, c4; } c; +} int_char; + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +static SLJIT_INLINE int utf_continue(sljit_u8 *s) +{ +#if PCRE2_CODE_UNIT_WIDTH == 8 +return (*s & 0xc0) == 0x80; +#elif PCRE2_CODE_UNIT_WIDTH == 16 +return (*s & 0xfc00) == 0xdc00; +#else +#error "Unknown code width" +#endif +} +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 +# define VECTOR_FACTOR 16 +# define vect_t uint8x16_t +# define VLD1Q(X) vld1q_u8((sljit_u8 *)(X)) +# define VCEQQ vceqq_u8 +# define VORRQ vorrq_u8 +# define VST1Q vst1q_u8 +# define VDUPQ vdupq_n_u8 +# define VEXTQ vextq_u8 +# define VANDQ vandq_u8 +typedef union { + uint8_t mem[16]; + uint64_t dw[2]; +} quad_word; +#elif PCRE2_CODE_UNIT_WIDTH == 16 +# define VECTOR_FACTOR 8 +# define vect_t uint16x8_t +# define VLD1Q(X) vld1q_u16((sljit_u16 *)(X)) +# define VCEQQ vceqq_u16 +# define VORRQ vorrq_u16 +# define VST1Q vst1q_u16 +# define VDUPQ vdupq_n_u16 +# define VEXTQ vextq_u16 +# define VANDQ vandq_u16 +typedef union { + uint16_t mem[8]; + uint64_t dw[2]; +} quad_word; +#else +# define VECTOR_FACTOR 4 +# define vect_t uint32x4_t +# define VLD1Q(X) vld1q_u32((sljit_u32 *)(X)) +# define VCEQQ vceqq_u32 +# define VORRQ vorrq_u32 +# define VST1Q vst1q_u32 +# define VDUPQ vdupq_n_u32 +# define VEXTQ vextq_u32 +# define VANDQ vandq_u32 +typedef union { + uint32_t mem[4]; + uint64_t dw[2]; +} quad_word; +#endif + +#define FFCS +#include "pcre2_jit_neon_inc.h" +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +# define FF_UTF +# include "pcre2_jit_neon_inc.h" +# undef FF_UTF +#endif +#undef FFCS + +#define FFCS_2 +#include "pcre2_jit_neon_inc.h" +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +# define FF_UTF +# include "pcre2_jit_neon_inc.h" +# undef FF_UTF +#endif +#undef FFCS_2 + +#define FFCS_MASK +#include "pcre2_jit_neon_inc.h" +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +# define FF_UTF +# include "pcre2_jit_neon_inc.h" +# undef FF_UTF +#endif +#undef FFCS_MASK + +#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1 + +static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) +{ +DEFINE_COMPILER; +int_char ic; +struct sljit_jump *partial_quit; +/* Save temporary registers. */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0); + +/* Prepare function arguments */ +OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0); +OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0); +OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset); + +if (char1 == char2) + { + ic.c.c1 = char1; + ic.c.c2 = char2; + OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf && offset > 0) + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_utf)); + else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs)); +#else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs)); +#endif + } +else + { + PCRE2_UCHAR mask = char1 ^ char2; + if (is_powerof2(mask)) + { + ic.c.c1 = char1 | mask; + ic.c.c2 = mask; + OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf && offset > 0) + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask_utf)); + else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask)); +#else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask)); +#endif + } + else + { + ic.c.c1 = char1; + ic.c.c2 = char2; + OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf && offset > 0) + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2_utf)); + else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2)); +#else + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2)); +#endif + } + } +/* Restore registers. */ +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); +OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); + +/* Check return value. */ +partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); +if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, &common->failed_match, partial_quit); + +/* Fast forward STR_PTR to the result of memchr. */ +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + +if (common->mode != PCRE2_JIT_COMPLETE) + JUMPHERE(partial_quit); +} + +typedef enum { + compare_match1, + compare_match1i, + compare_match2, +} compare_type; + +static inline vect_t fast_forward_char_pair_compare(compare_type ctype, vect_t dst, vect_t cmp1, vect_t cmp2) +{ +if (ctype == compare_match2) + { + vect_t tmp = dst; + dst = VCEQQ(dst, cmp1); + tmp = VCEQQ(tmp, cmp2); + dst = VORRQ(dst, tmp); + return dst; + } + +if (ctype == compare_match1i) + dst = VORRQ(dst, cmp2); +dst = VCEQQ(dst, cmp1); +return dst; +} + +static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void) +{ +#if PCRE2_CODE_UNIT_WIDTH == 8 +return 15; +#elif PCRE2_CODE_UNIT_WIDTH == 16 +return 7; +#elif PCRE2_CODE_UNIT_WIDTH == 32 +return 3; +#else +#error "Unsupported unit width" +#endif +} + +/* ARM doesn't have a shift left across lanes. */ +static SLJIT_INLINE vect_t shift_left_n_lanes(vect_t a, sljit_u8 n) +{ +vect_t zero = VDUPQ(0); +SLJIT_ASSERT(0 < n && n < VECTOR_FACTOR); +/* VEXTQ takes an immediate as last argument. */ +#define C(X) case X: return VEXTQ(zero, a, VECTOR_FACTOR - X); +switch (n) + { + C(1); C(2); C(3); +#if PCRE2_CODE_UNIT_WIDTH != 32 + C(4); C(5); C(6); C(7); +# if PCRE2_CODE_UNIT_WIDTH != 16 + C(8); C(9); C(10); C(11); C(12); C(13); C(14); C(15); +# endif +#endif + default: + /* Based on the ASSERT(0 < n && n < VECTOR_FACTOR) above, this won't + happen. The return is still here for compilers to not warn. */ + return a; + } +} + +#define FFCPS +#define FFCPS_DIFF1 +#define FFCPS_CHAR1A2A + +#define FFCPS_0 +#include "pcre2_jit_neon_inc.h" +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +# define FF_UTF +# include "pcre2_jit_neon_inc.h" +# undef FF_UTF +#endif +#undef FFCPS_0 + +#undef FFCPS_CHAR1A2A + +#define FFCPS_1 +#include "pcre2_jit_neon_inc.h" +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +# define FF_UTF +# include "pcre2_jit_neon_inc.h" +# undef FF_UTF +#endif +#undef FFCPS_1 + +#undef FFCPS_DIFF1 + +#define FFCPS_DEFAULT +#include "pcre2_jit_neon_inc.h" +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +# define FF_UTF +# include "pcre2_jit_neon_inc.h" +# undef FF_UTF +#endif +#undef FFCPS + +#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1 + +static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1, + PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b) +{ +DEFINE_COMPILER; +sljit_u32 diff = IN_UCHARS(offs1 - offs2); +struct sljit_jump *partial_quit; +int_char ic; +SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2); +SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); +SLJIT_ASSERT(compiler->scratches == 5); + +/* Save temporary register STR_PTR. */ +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); + +/* Prepare arguments for the function call. */ +if (common->match_end_ptr == 0) + OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0); +else + { + OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); + + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, STR_END, 0, SLJIT_R0, 0); + CMOV(SLJIT_LESS, SLJIT_R0, STR_END, 0); + } + +OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0); +OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1); +OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2); +ic.c.c1 = char1a; +ic.c.c2 = char1b; +ic.c.c3 = char2a; +ic.c.c4 = char2b; +OP1(SLJIT_MOV_U32, SLJIT_R4, 0, SLJIT_IMM, ic.x); + +if (diff == 1) { + if (char1a == char1b && char2a == char2b) { +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_0_utf)); + else +#endif + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_0)); + } else { +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_1_utf)); + else +#endif + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_1)); + } +} else { +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 + if (common->utf) + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_default_utf)); + else +#endif + sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), + SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_default)); +} + +/* Restore STR_PTR register. */ +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + +/* Check return value. */ +partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); +add_jump(compiler, &common->failed_match, partial_quit); + +/* Fast forward STR_PTR to the result of memchr. */ +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + +JUMPHERE(partial_quit); +} + +#endif /* SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 */ diff --git a/ext/pcre/pcre2lib/pcre2_maketables.c b/ext/pcre/pcre2lib/pcre2_maketables.c index 5921e9079308f..8c93b4b57373e 100644 --- a/ext/pcre/pcre2lib/pcre2_maketables.c +++ b/ext/pcre/pcre2lib/pcre2_maketables.c @@ -147,4 +147,15 @@ for (i = 0; i < 256; i++) return yield; } +#ifndef DFTABLES +PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION +pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables) +{ + if (gcontext) + gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data); + else + free((void *)tables); +} +#endif + /* End of pcre2_maketables.c */ diff --git a/ext/pcre/pcre2lib/pcre2_match.c b/ext/pcre/pcre2lib/pcre2_match.c index 419561fd6457b..48e7b9dbb2c40 100644 --- a/ext/pcre/pcre2lib/pcre2_match.c +++ b/ext/pcre/pcre2lib/pcre2_match.c @@ -415,8 +415,7 @@ if (caseless) else #endif - /* Not in UTF mode */ - + /* Not in UTF mode */ { for (; length > 0; length--) { @@ -491,27 +490,32 @@ heap is used for a larger vector. *************************************************/ /* These macros pack up tests that are used for partial matching several times -in the code. We set the "hit end" flag if the pointer is at the end of the -subject and also past the earliest inspected character (i.e. something has been -matched, even if not part of the actual matched string). For hard partial -matching, we then return immediately. The second one is used when we already -know we are past the end of the subject. */ +in the code. The second one is used when we already know we are past the end of +the subject. We set the "hit end" flag if the pointer is at the end of the +subject and either (a) the pointer is past the earliest inspected character +(i.e. something has been matched, even if not part of the actual matched +string), or (b) the pattern contains a lookbehind. These are the conditions for +which adding more characters may allow the current match to continue. + +For hard partial matching, we immediately return a partial match. Otherwise, +carrying on means that a complete match on the current subject will be sought. +A partial match is returned only if no complete match can be found. */ #define CHECK_PARTIAL()\ - if (mb->partial != 0 && Feptr >= mb->end_subject && \ - Feptr > mb->start_used_ptr) \ + if (Feptr >= mb->end_subject) \ { \ - mb->hitend = TRUE; \ - if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \ + SCHECK_PARTIAL(); \ } #define SCHECK_PARTIAL()\ - if (mb->partial != 0 && Feptr > mb->start_used_ptr) \ + if (mb->partial != 0 && \ + (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \ { \ mb->hitend = TRUE; \ if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \ } + /* These macros are used to implement backtracking. They simulate a recursive call to the match() function by means of a local vector of frames which remember the backtracking points. */ @@ -5127,6 +5131,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case OP_ASSERT: case OP_ASSERTBACK: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: Lframe_type = GF_NOCAPTURE | Fop; for (;;) { @@ -5412,7 +5418,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); { while (number-- > 0) { - if (Feptr <= mb->start_subject) RRETURN(MATCH_NOMATCH); + if (Feptr <= mb->check_subject) RRETURN(MATCH_NOMATCH); Feptr--; BACKCHAR(Feptr); } @@ -5420,7 +5426,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); else #endif - /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ + /* No UTF-8 support, or not in UTF-8 mode: count is code unit count */ { if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH); @@ -5472,15 +5478,16 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* If we are at the end of an assertion that is a condition, return a match, discarding any intermediate backtracking points. Copy back the - captures into the frame before N so that they are set on return. Doing - this for all assertions, both positive and negative, seems to match what - Perl does. */ + mark setting and the captures into the frame before N so that they are + set on return. Doing this for all assertions, both positive and negative, + seems to match what Perl does. */ if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT) { memcpy((char *)P + offsetof(heapframe, ovector), Fovector, Foffset_top * sizeof(PCRE2_SIZE)); P->offset_top = Foffset_top; + P->mark = Fmark; Fback_frame = (char *)F - (char *)P; RRETURN(MATCH_MATCH); } @@ -5496,10 +5503,20 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case OP_SCOND: break; - /* Positive assertions are like OP_ONCE, except that in addition the + /* Non-atomic positive assertions are like OP_BRA, except that the subject pointer must be put back to where it was at the start of the assertion. */ + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: + if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; + Feptr = P->eptr; + break; + + /* Atomic positive assertions are like OP_ONCE, except that in addition + the subject pointer must be put back to where it was at the start of the + assertion. */ + case OP_ASSERT: case OP_ASSERTBACK: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -5640,7 +5657,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case OP_EOD: if (Feptr < mb->end_subject) RRETURN(MATCH_NOMATCH); - SCHECK_PARTIAL(); + if (mb->partial != 0) + { + mb->hitend = TRUE; + if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; + } Fecode++; break; @@ -5665,7 +5686,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* Either at end of string or \n before end. */ - SCHECK_PARTIAL(); + if (mb->partial != 0) + { + mb->hitend = TRUE; + if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; + } Fecode++; break; @@ -5743,7 +5768,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: - if (Feptr == mb->start_subject) prev_is_word = FALSE; else + if (Feptr == mb->check_subject) prev_is_word = FALSE; else { PCRE2_SPTR lastptr = Feptr - 1; #ifdef SUPPORT_UNICODE @@ -5946,6 +5971,7 @@ in rrc. */ #define LBL(val) case val: goto L_RM##val; RETURN_SWITCH: +if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; if (Frdepth == 0) return rrc; /* Exit from the top level */ F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */ mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */ @@ -5999,9 +6025,9 @@ each substring: the offsets to the start and end of the substring. Returns: > 0 => success; value is the number of ovector pairs filled = 0 => success, but ovector is not big enough - -1 => failed to match (PCRE2_ERROR_NOMATCH) - -2 => partial match (PCRE2_ERROR_PARTIAL) - < -2 => some kind of unexpected problem + = -1 => failed to match (PCRE2_ERROR_NOMATCH) + = -2 => partial match (PCRE2_ERROR_PARTIAL) + < -2 => some kind of unexpected problem */ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION @@ -6014,7 +6040,6 @@ int was_zero_terminated = 0; const uint8_t *start_bits = NULL; const pcre2_real_code *re = (const pcre2_real_code *)code; - BOOL anchored; BOOL firstline; BOOL has_first_cu = FALSE; @@ -6022,6 +6047,11 @@ BOOL has_req_cu = FALSE; BOOL startline; BOOL utf; +#if PCRE2_CODE_UNIT_WIDTH == 8 +BOOL memchr_not_found_first_cu = FALSE; +BOOL memchr_not_found_first_cu2 = FALSE; +#endif + PCRE2_UCHAR first_cu = 0; PCRE2_UCHAR first_cu2 = 0; PCRE2_UCHAR req_cu = 0; @@ -6029,10 +6059,23 @@ PCRE2_UCHAR req_cu2 = 0; PCRE2_SPTR bumpalong_limit; PCRE2_SPTR end_subject; +PCRE2_SPTR true_end_subject; PCRE2_SPTR start_match = subject + start_offset; PCRE2_SPTR req_cu_ptr = start_match - 1; -PCRE2_SPTR start_partial = NULL; -PCRE2_SPTR match_partial = NULL; +PCRE2_SPTR start_partial; +PCRE2_SPTR match_partial; + +#ifdef SUPPORT_JIT +BOOL use_jit; +#endif + +#ifdef SUPPORT_UNICODE +BOOL allow_invalid; +uint32_t fragment_options = 0; +#ifdef SUPPORT_JIT +BOOL jit_checked_utf = FALSE; +#endif +#endif PCRE2_SIZE frame_size; @@ -6059,7 +6102,7 @@ if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); was_zero_terminated = 1; } -end_subject = subject + length; +true_end_subject = end_subject = subject + length; /* Plausibility checks */ @@ -6095,12 +6138,24 @@ options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1))); #undef FF #undef OO -/* These two settings are used in the code for checking a UTF string that -follows immediately afterwards. Other values in the mb block are used only -during interpretive processing, not when the JIT support is in use, so they are -set up later. */ +/* If the pattern was successfully studied with JIT support, we will run the +JIT executable instead of the rest of this function. Most options must be set +at compile time for the JIT code to be usable. */ + +#ifdef SUPPORT_JIT +use_jit = (re->executable_jit != NULL && + (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0); +#endif + +/* Initialize UTF parameters. */ utf = (re->overall_options & PCRE2_UTF) != 0; +#ifdef SUPPORT_UNICODE +allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0; +#endif + +/* Convert the partial matching flags into an integer. */ + mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 : ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0; @@ -6111,88 +6166,107 @@ if (mb->partial != 0 && ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0) return PCRE2_ERROR_BADOPTION; -/* Check a UTF string for validity if required. For 8-bit and 16-bit strings, -we must also check that a starting offset does not point into the middle of a -multiunit character. We check only the portion of the subject that is going to -be inspected during matching - from the offset minus the maximum back reference -to the given length. This saves time when a small part of a large subject is -being matched by the use of a starting offset. Note that the maximum lookbehind -is a number of characters, not code units. */ +/* It is an error to set an offset limit without setting the flag at compile +time. */ -#ifdef SUPPORT_UNICODE -if (utf && (options & PCRE2_NO_UTF_CHECK) == 0) +if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET && + (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0) + return PCRE2_ERROR_BADOFFSETLIMIT; + +/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT, +free the memory that was obtained. Set the field to NULL for no match cases. */ + +if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0) { - PCRE2_SPTR check_subject = start_match; /* start_match includes offset */ + match_data->memctl.free((void *)match_data->subject, + match_data->memctl.memory_data); + match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT; + } +match_data->subject = NULL; + +/* Zero the error offset in case the first code unit is invalid UTF. */ + +match_data->startchar = 0; + + +/* ============================= JIT matching ============================== */ + +/* Prepare for JIT matching. Check a UTF string for validity unless no check is +requested or invalid UTF can be handled. We check only the portion of the +subject that might be be inspected during matching - from the offset minus the +maximum lookbehind to the given length. This saves time when a small part of a +large subject is being matched by the use of a starting offset. Note that the +maximum lookbehind is a number of characters, not code units. */ - if (start_offset > 0) +#ifdef SUPPORT_JIT +if (use_jit) + { +#ifdef SUPPORT_UNICODE + if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid) { #if PCRE2_CODE_UNIT_WIDTH != 32 unsigned int i; +#endif + + /* For 8-bit and 16-bit UTF, check that the first code unit is a valid + character start. */ + +#if PCRE2_CODE_UNIT_WIDTH != 32 if (start_match < end_subject && NOT_FIRSTCU(*start_match)) - return PCRE2_ERROR_BADUTFOFFSET; - for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--) { - check_subject--; - while (check_subject > subject && + if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET; +#if PCRE2_CODE_UNIT_WIDTH == 8 + return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */ +#else + return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */ +#endif + } +#endif /* WIDTH != 32 */ + + /* Move back by the maximum lookbehind, just in case it happens at the very + start of matching. */ + +#if PCRE2_CODE_UNIT_WIDTH != 32 + for (i = re->max_lookbehind; i > 0 && start_match > subject; i--) + { + start_match--; + while (start_match > subject && #if PCRE2_CODE_UNIT_WIDTH == 8 - (*check_subject & 0xc0) == 0x80) + (*start_match & 0xc0) == 0x80) #else /* 16-bit */ - (*check_subject & 0xfc00) == 0xdc00) -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - check_subject--; + (*start_match & 0xfc00) == 0xdc00) +#endif + start_match--; } -#else +#else /* PCRE2_CODE_UNIT_WIDTH != 32 */ + /* In the 32-bit library, one code unit equals one character. However, we cannot just subtract the lookbehind and then compare pointers, because a very large lookbehind could create an invalid pointer. */ if (start_offset >= re->max_lookbehind) - check_subject -= re->max_lookbehind; + start_match -= re->max_lookbehind; else - check_subject = subject; + start_match = subject; #endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ - } - /* Validate the relevant portion of the subject. After an error, adjust the - offset to be an absolute offset in the whole string. */ + /* Validate the relevant portion of the subject. Adjust the offset of an + invalid code point to be an absolute offset in the whole string. */ - match_data->rc = PRIV(valid_utf)(check_subject, - length - (check_subject - subject), &(match_data->startchar)); - if (match_data->rc != 0) - { - match_data->startchar += check_subject - subject; - return match_data->rc; + match_data->rc = PRIV(valid_utf)(start_match, + length - (start_match - subject), &(match_data->startchar)); + if (match_data->rc != 0) + { + match_data->startchar += start_match - subject; + return match_data->rc; + } + jit_checked_utf = TRUE; } - } #endif /* SUPPORT_UNICODE */ -/* It is an error to set an offset limit without setting the flag at compile -time. */ - -if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET && - (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0) - return PCRE2_ERROR_BADOFFSETLIMIT; - -/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT, -free the memory that was obtained. Set the field to NULL for no match cases. */ + /* If JIT returns BADOPTION, which means that the selected complete or + partial matching mode was not compiled, fall through to the interpreter. */ -if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0) - { - match_data->memctl.free((void *)match_data->subject, - match_data->memctl.memory_data); - match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT; - } -match_data->subject = NULL; - -/* If the pattern was successfully studied with JIT support, run the JIT -executable instead of the rest of this function. Most options must be set at -compile time for the JIT code to be usable. Fallback to the normal code path if -an unsupported option is set or if JIT returns BADOPTION (which means that the -selected normal or partial matching mode was not compiled). */ - -#ifdef SUPPORT_JIT -if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0) - { rc = pcre2_jit_match(code, subject, length, start_offset, options, match_data, mcontext); if (rc != PCRE2_ERROR_JIT_BADOPTION) @@ -6209,10 +6283,152 @@ if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0) return rc; } } +#endif /* SUPPORT_JIT */ + +/* ========================= End of JIT matching ========================== */ + + +/* Proceed with non-JIT matching. The default is to allow lookbehinds to the +start of the subject. A UTF check when there is a non-zero offset may change +this. */ + +mb->check_subject = subject; + +/* If a UTF subject string was not checked for validity in the JIT code above, +check it here, and handle support for invalid UTF strings. The check above +happens only when invalid UTF is not supported and PCRE2_NO_CHECK_UTF is unset. +If we get here in those circumstances, it means the subject string is valid, +but for some reason JIT matching was not successful. There is no need to check +the subject again. + +We check only the portion of the subject that might be be inspected during +matching - from the offset minus the maximum lookbehind to the given length. +This saves time when a small part of a large subject is being matched by the +use of a starting offset. Note that the maximum lookbehind is a number of +characters, not code units. + +Note also that support for invalid UTF forces a check, overriding the setting +of PCRE2_NO_CHECK_UTF. */ + +#ifdef SUPPORT_UNICODE +if (utf && +#ifdef SUPPORT_JIT + !jit_checked_utf && +#endif + ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid)) + { +#if PCRE2_CODE_UNIT_WIDTH != 32 + BOOL skipped_bad_start = FALSE; +#endif + + /* For 8-bit and 16-bit UTF, check that the first code unit is a valid + character start. If we are handling invalid UTF, just skip over such code + units. Otherwise, give an appropriate error. */ + +#if PCRE2_CODE_UNIT_WIDTH != 32 + if (allow_invalid) + { + while (start_match < end_subject && NOT_FIRSTCU(*start_match)) + { + start_match++; + skipped_bad_start = TRUE; + } + } + else if (start_match < end_subject && NOT_FIRSTCU(*start_match)) + { + if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET; +#if PCRE2_CODE_UNIT_WIDTH == 8 + return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */ +#else + return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */ +#endif + } +#endif /* WIDTH != 32 */ + + /* The mb->check_subject field points to the start of UTF checking; + lookbehinds can go back no further than this. */ + + mb->check_subject = start_match; + + /* Move back by the maximum lookbehind, just in case it happens at the very + start of matching, but don't do this if we skipped bad 8-bit or 16-bit code + units above. */ + +#if PCRE2_CODE_UNIT_WIDTH != 32 + if (!skipped_bad_start) + { + unsigned int i; + for (i = re->max_lookbehind; i > 0 && mb->check_subject > subject; i--) + { + mb->check_subject--; + while (mb->check_subject > subject && +#if PCRE2_CODE_UNIT_WIDTH == 8 + (*mb->check_subject & 0xc0) == 0x80) +#else /* 16-bit */ + (*mb->check_subject & 0xfc00) == 0xdc00) +#endif + mb->check_subject--; + } + } +#else /* PCRE2_CODE_UNIT_WIDTH != 32 */ + + /* In the 32-bit library, one code unit equals one character. However, + we cannot just subtract the lookbehind and then compare pointers, because + a very large lookbehind could create an invalid pointer. */ + + if (start_offset >= re->max_lookbehind) + mb->check_subject -= re->max_lookbehind; + else + mb->check_subject = subject; +#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ + + /* Validate the relevant portion of the subject. There's a loop in case we + encounter bad UTF in the characters preceding start_match which we are + scanning because of a lookbehind. */ + + for (;;) + { + match_data->rc = PRIV(valid_utf)(mb->check_subject, + length - (mb->check_subject - subject), &(match_data->startchar)); + + if (match_data->rc == 0) break; /* Valid UTF string */ + + /* Invalid UTF string. Adjust the offset to be an absolute offset in the + whole string. If we are handling invalid UTF strings, set end_subject to + stop before the bad code unit, and set the options to "not end of line". + Otherwise return the error. */ + + match_data->startchar += mb->check_subject - subject; + if (!allow_invalid || match_data->rc > 0) return match_data->rc; + end_subject = subject + match_data->startchar; + + /* If the end precedes start_match, it means there is invalid UTF in the + extra code units we reversed over because of a lookbehind. Advance past the + first bad code unit, and then skip invalid character starting code units in + 8-bit and 16-bit modes, and try again. */ + + if (end_subject < start_match) + { + mb->check_subject = end_subject + 1; +#if PCRE2_CODE_UNIT_WIDTH != 32 + while (mb->check_subject < start_match && NOT_FIRSTCU(*mb->check_subject)) + mb->check_subject++; #endif + } + + /* Otherwise, set the not end of line option, and do the match. */ + + else + { + fragment_options = PCRE2_NOTEOL; + break; + } + } + } +#endif /* SUPPORT_UNICODE */ -/* Carry on with non-JIT matching. A NULL match context means "use a default -context", but we take the memory control functions from the pattern. */ +/* A NULL match context means "use a default context", but we take the memory +control functions from the pattern. */ if (mcontext == NULL) { @@ -6224,8 +6440,8 @@ else mb->memctl = mcontext->memctl; anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0; firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; startline = (re->flags & PCRE2_STARTLINE) != 0; -bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)? - end_subject : subject + mcontext->offset_limit; +bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)? + true_end_subject : subject + mcontext->offset_limit; /* Initialize and set up the fixed fields in the callout block, with a pointer in the match block. */ @@ -6236,7 +6452,8 @@ cb.subject = subject; cb.subject_length = (PCRE2_SIZE)(end_subject - subject); cb.callout_flags = 0; -/* Fill in the remaining fields in the match block. */ +/* Fill in the remaining fields in the match block, except for moptions, which +gets set later. */ mb->callout = mcontext->callout; mb->callout_data = mcontext->callout_data; @@ -6245,13 +6462,11 @@ mb->start_subject = subject; mb->start_offset = start_offset; mb->end_subject = end_subject; mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0; - -mb->moptions = options; /* Match options */ -mb->poptions = re->overall_options; /* Pattern options */ - +mb->allowemptypartial = (re->max_lookbehind > 0) || + (re->flags & PCRE2_MATCH_EMPTY) != 0; +mb->poptions = re->overall_options; /* Pattern options */ mb->ignore_skip_arg = 0; -mb->mark = mb->nomatch_mark = NULL; /* In case never set */ -mb->hitend = FALSE; +mb->mark = mb->nomatch_mark = NULL; /* In case never set */ /* The name table is needed for finding all the numbers associated with a given name, for condition testing. The code follows the name table. */ @@ -6404,6 +6619,13 @@ if ((re->flags & PCRE2_LASTSET) != 0) /* Loop for handling unanchored repeated matching attempts; for anchored regexs the loop runs just once. */ +#ifdef SUPPORT_UNICODE +FRAGMENT_RESTART: +#endif + +start_partial = match_partial = NULL; +mb->hitend = FALSE; + for(;;) { PCRE2_SPTR new_start_match; @@ -6473,7 +6695,10 @@ for(;;) /* Not anchored. Advance to a unique first code unit if there is one. In 8-bit mode, the use of memchr() gives a big speed up, even though we have to call it twice in caseless mode, in order to find the earliest occurrence - of the character in either of its cases. */ + of the character in either of its cases. If a call to memchr() that + searches the rest of the subject fails to find one case, remember that in + order not to keep on repeating the search. This can make a huge difference + when the strings are very long and only one case is present. */ else { @@ -6487,11 +6712,29 @@ for(;;) (smc = UCHAR21TEST(start_match)) != first_cu && smc != first_cu2) start_match++; + #else /* 8-bit code units */ - PCRE2_SPTR pp1 = - memchr(start_match, first_cu, end_subject-start_match); - PCRE2_SPTR pp2 = - memchr(start_match, first_cu2, end_subject-start_match); + PCRE2_SPTR pp1 = NULL; + PCRE2_SPTR pp2 = NULL; + PCRE2_SIZE cu2size = end_subject - start_match; + + if (!memchr_not_found_first_cu) + { + pp1 = memchr(start_match, first_cu, end_subject - start_match); + if (pp1 == NULL) memchr_not_found_first_cu = TRUE; + else cu2size = pp1 - start_match; + } + + /* If pp1 is not NULL, we have arranged to search only as far as pp1, + to see if the other case is earlier, so we can set "not found" only + when both searches have returned NULL. */ + + if (!memchr_not_found_first_cu2) + { + pp2 = memchr(start_match, first_cu2, cu2size); + memchr_not_found_first_cu2 = (pp2 == NULL && pp1 == NULL); + } + if (pp1 == NULL) start_match = (pp2 == NULL)? end_subject : pp2; else @@ -6523,7 +6766,7 @@ for(;;) we also let the cycle run, because the matching string is legitimately allowed to start with the first code unit of a newline. */ - if (!mb->partial && start_match >= mb->end_subject) + if (mb->partial == 0 && start_match >= mb->end_subject) { rc = MATCH_NOMATCH; break; @@ -6582,7 +6825,7 @@ for(;;) /* See comment above in first_cu checking about the next few lines. */ - if (!mb->partial && start_match >= mb->end_subject) + if (mb->partial == 0 && start_match >= mb->end_subject) { rc = MATCH_NOMATCH; break; @@ -6596,8 +6839,10 @@ for(;;) /* The following two optimizations must be disabled for partial matching. */ - if (!mb->partial) + if (mb->partial == 0) { + PCRE2_SPTR p; + /* The minimum matching length is a lower bound; no string of that length may actually match the pattern. Although the value is, strictly, in characters, we treat it as code units to avoid spending too much time in @@ -6621,60 +6866,57 @@ for(;;) memchr() twice in the caseless case because we only need to check for the presence of the character in either case, not find the first occurrence. + The search can be skipped if the code unit was found later than the + current starting point in a previous iteration of the bumpalong loop. + HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary - patterns. This showed up when somebody was matching something like - /^\d+C/ on a 32-megabyte string... so we don't do this when the string is - sufficiently long. */ + anchored patterns. This showed up when somebody was matching something + like /^\d+C/ on a 32-megabyte string... so we don't do this when the + string is sufficiently long, but it's worth searching a lot more for + unanchored patterns. */ - if (has_req_cu && end_subject - start_match < REQ_CU_MAX) + p = start_match + (has_first_cu? 1:0); + if (has_req_cu && p > req_cu_ptr) { - PCRE2_SPTR p = start_match + (has_first_cu? 1:0); - - /* We don't need to repeat the search if we haven't yet reached the - place we found it last time round the bumpalong loop. */ + PCRE2_SIZE check_length = end_subject - start_match; - if (p > req_cu_ptr) + if (check_length < REQ_CU_MAX || + (!anchored && check_length < REQ_CU_MAX * 1000)) { - if (p < end_subject) + if (req_cu != req_cu2) /* Caseless */ { - if (req_cu != req_cu2) /* Caseless */ - { #if PCRE2_CODE_UNIT_WIDTH != 8 - do - { - uint32_t pp = UCHAR21INCTEST(p); - if (pp == req_cu || pp == req_cu2) { p--; break; } - } - while (p < end_subject); - + while (p < end_subject) + { + uint32_t pp = UCHAR21INCTEST(p); + if (pp == req_cu || pp == req_cu2) { p--; break; } + } #else /* 8-bit code units */ - PCRE2_SPTR pp = p; - p = memchr(pp, req_cu, end_subject - pp); - if (p == NULL) - { - p = memchr(pp, req_cu2, end_subject - pp); - if (p == NULL) p = end_subject; - } -#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */ + PCRE2_SPTR pp = p; + p = memchr(pp, req_cu, end_subject - pp); + if (p == NULL) + { + p = memchr(pp, req_cu2, end_subject - pp); + if (p == NULL) p = end_subject; } +#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */ + } - /* The caseful case */ + /* The caseful case */ - else - { + else + { #if PCRE2_CODE_UNIT_WIDTH != 8 - do - { - if (UCHAR21INCTEST(p) == req_cu) { p--; break; } - } - while (p < end_subject); + while (p < end_subject) + { + if (UCHAR21INCTEST(p) == req_cu) { p--; break; } + } #else /* 8-bit code units */ - p = memchr(p, req_cu, end_subject - p); - if (p == NULL) p = end_subject; + p = memchr(p, req_cu, end_subject - p); + if (p == NULL) p = end_subject; #endif - } } /* If we can't find the required code unit, break the bumpalong loop, @@ -6714,6 +6956,11 @@ for(;;) mb->start_used_ptr = start_match; mb->last_used_ptr = start_match; +#ifdef SUPPORT_UNICODE + mb->moptions = options | fragment_options; +#else + mb->moptions = options; +#endif mb->match_call_count = 0; mb->end_offset_top = 0; mb->skip_arg_count = 0; @@ -6839,6 +7086,68 @@ for(;;) ENDLOOP: +/* If end_subject != true_end_subject, it means we are handling invalid UTF, +and have just processed a non-terminal fragment. If this resulted in no match +or a partial match we must carry on to the next fragment (a partial match is +returned to the caller only at the very end of the subject). A loop is used to +avoid trying to match against empty fragments; if the pattern can match an +empty string it would have done so already. */ + +#ifdef SUPPORT_UNICODE +if (utf && end_subject != true_end_subject && + (rc == MATCH_NOMATCH || rc == PCRE2_ERROR_PARTIAL)) + { + for (;;) + { + /* Advance past the first bad code unit, and then skip invalid character + starting code units in 8-bit and 16-bit modes. */ + + start_match = end_subject + 1; +#if PCRE2_CODE_UNIT_WIDTH != 32 + while (start_match < true_end_subject && NOT_FIRSTCU(*start_match)) + start_match++; +#endif + + /* If we have hit the end of the subject, there isn't another non-empty + fragment, so give up. */ + + if (start_match >= true_end_subject) + { + rc = MATCH_NOMATCH; /* In case it was partial */ + break; + } + + /* Check the rest of the subject */ + + mb->check_subject = start_match; + rc = PRIV(valid_utf)(start_match, length - (start_match - subject), + &(match_data->startchar)); + + /* The rest of the subject is valid UTF. */ + + if (rc == 0) + { + mb->end_subject = end_subject = true_end_subject; + fragment_options = PCRE2_NOTBOL; + goto FRAGMENT_RESTART; + } + + /* A subsequent UTF error has been found; if the next fragment is + non-empty, set up to process it. Otherwise, let the loop advance. */ + + else if (rc < 0) + { + mb->end_subject = end_subject = start_match + match_data->startchar; + if (end_subject > start_match) + { + fragment_options = PCRE2_NOTBOL|PCRE2_NOTEOL; + goto FRAGMENT_RESTART; + } + } + } + } +#endif /* SUPPORT_UNICODE */ + /* Release an enlarged frame vector that is on the heap. */ if (mb->match_frames != mb->stack_frames) diff --git a/ext/pcre/pcre2lib/pcre2_match_data.c b/ext/pcre/pcre2lib/pcre2_match_data.c index ccc5f6740e003..53e4698707964 100644 --- a/ext/pcre/pcre2lib/pcre2_match_data.c +++ b/ext/pcre/pcre2lib/pcre2_match_data.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -150,4 +150,17 @@ pcre2_get_startchar(pcre2_match_data *match_data) return match_data->startchar; } + + +/************************************************* +* Get size of match data block * +*************************************************/ + +PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION +pcre2_get_match_data_size(pcre2_match_data *match_data) +{ +return offsetof(pcre2_match_data, ovector) + + 2 * (match_data->oveccount) * sizeof(PCRE2_SIZE); +} + /* End of pcre2_match_data.c */ diff --git a/ext/pcre/pcre2lib/pcre2_printint.c b/ext/pcre/pcre2lib/pcre2_printint.c index b132d44f8c262..b9bab025ab38f 100644 --- a/ext/pcre/pcre2lib/pcre2_printint.c +++ b/ext/pcre/pcre2lib/pcre2_printint.c @@ -392,6 +392,8 @@ for(;;) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_COND: diff --git a/ext/pcre/pcre2lib/pcre2_study.c b/ext/pcre/pcre2lib/pcre2_study.c index e883c2eb4c229..2883868618d9c 100644 --- a/ext/pcre/pcre2lib/pcre2_study.c +++ b/ext/pcre/pcre2lib/pcre2_study.c @@ -88,11 +88,13 @@ value. countptr pointer to call count (to catch over complexity) backref_cache vector for caching back references. +This function is no longer called when the pattern contains (*ACCEPT); however, +the old code for returning -1 is retained, just in case. + Returns: the minimum length -1 \C in UTF-8 mode or (*ACCEPT) or pattern too complicated - or back reference to duplicate name/number -2 internal error (missing capturing bracket) -3 internal error (opcode not listed) */ @@ -103,6 +105,7 @@ find_minlength(const pcre2_real_code *re, PCRE2_SPTR code, int *backref_cache) { int length = -1; +int branchlength = 0; int prev_cap_recno = -1; int prev_cap_d = 0; int prev_recurse_recno = -1; @@ -110,9 +113,9 @@ int prev_recurse_d = 0; uint32_t once_fudge = 0; BOOL had_recurse = FALSE; BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0; -recurse_check this_recurse; -int branchlength = 0; +PCRE2_SPTR nextbranch = code + GET(code, 1); PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE; +recurse_check this_recurse; /* If this is a "could be empty" group, its minimum length is 0. */ @@ -128,16 +131,20 @@ if ((*countptr)++ > 1000) return -1; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. If the accumulated length -passes 16-bits, stop. */ +passes 16-bits, reset to that value and skip the rest of the branch. */ for (;;) { int d, min, recno; - PCRE2_UCHAR *cs, *ce; - PCRE2_UCHAR op = *cc; + PCRE2_UCHAR op, *cs, *ce; - if (branchlength >= UINT16_MAX) return UINT16_MAX; + if (branchlength >= UINT16_MAX) + { + branchlength = UINT16_MAX; + cc = (PCRE2_UCHAR *)nextbranch; + } + op = *cc; switch (op) { case OP_COND: @@ -206,7 +213,9 @@ for (;;) cc += 1 + LINK_SIZE; break; - /* ACCEPT makes things far too complicated; we have to give up. */ + /* ACCEPT makes things far too complicated; we have to give up. In fact, + from 10.34 onwards, if a pattern contains (*ACCEPT), this function is not + used. However, leave the code in place, just in case. */ case OP_ACCEPT: case OP_ASSERT_ACCEPT: @@ -214,9 +223,9 @@ for (;;) /* Reached end of a branch; if it's a ket it is the end of a nested call. If it's ALT it is an alternation in a nested call. If it is END it's - the end of the outer call. All can be handled by the same code. If an - ACCEPT was previously encountered, use the length that was in force at that - time, and pass back the shortest ACCEPT length. */ + the end of the outer call. All can be handled by the same code. If the + length of any branch is zero, there is no need to scan any subsequent + branches. */ case OP_ALT: case OP_KET: @@ -226,7 +235,8 @@ for (;;) case OP_END: if (length < 0 || (!had_recurse && branchlength < length)) length = branchlength; - if (op != OP_ALT) return length; + if (op != OP_ALT || length == 0) return length; + nextbranch = cc + GET(cc, 1); cc += 1 + LINK_SIZE; branchlength = 0; had_recurse = FALSE; @@ -238,6 +248,8 @@ for (;;) case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); /* Fall through */ @@ -451,15 +463,17 @@ for (;;) If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket matches an empty string (by default it causes a matching failure), so in - that case we must set the minimum length to zero. */ + that case we must set the minimum length to zero. + + For backreferenes, if duplicate numbers are present in the pattern we check + for a reference to a duplicate. If it is, we don't know which version will + be referenced, so we have to set the minimum length to zero. */ - /* Duplicate named pattern back reference. We cannot reliably find a length - for this if duplicate numbers are present in the pattern. */ + /* Duplicate named pattern back reference. */ case OP_DNREF: case OP_DNREFI: - if (dupcapused) return -1; - if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) + if (!dupcapused && (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) { int count = GET2(cc, 1+IMM2_SIZE); PCRE2_UCHAR *slot = @@ -482,28 +496,32 @@ for (;;) ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); - if (cc > cs && cc < ce) /* Simple recursion */ - { - dd = 0; - had_recurse = TRUE; - } - else + + dd = 0; + if (!dupcapused || + (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL) { - recurse_check *r = recurses; - for (r = recurses; r != NULL; r = r->prev) - if (r->group == cs) break; - if (r != NULL) /* Mutual recursion */ + if (cc > cs && cc < ce) /* Simple recursion */ { - dd = 0; had_recurse = TRUE; } else { - this_recurse.prev = recurses; - this_recurse.group = cs; - dd = find_minlength(re, cs, startcode, utf, &this_recurse, - countptr, backref_cache); - if (dd < 0) return dd; + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) + if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + { + had_recurse = TRUE; + } + else + { + this_recurse.prev = recurses; /* No recursion */ + this_recurse.group = cs; + dd = find_minlength(re, cs, startcode, utf, &this_recurse, + countptr, backref_cache); + if (dd < 0) return dd; + } } } @@ -521,48 +539,51 @@ for (;;) cc += 1 + 2*IMM2_SIZE; goto REPEAT_BACK_REFERENCE; - /* Single back reference. We cannot find a length for this if duplicate - numbers are present in the pattern. */ + /* Single back reference by number. References by name are converted to by + number when there is no duplication. */ case OP_REF: case OP_REFI: - if (dupcapused) return -1; recno = GET2(cc, 1); if (recno <= backref_cache[0] && backref_cache[recno] >= 0) d = backref_cache[recno]; else { int i; + d = 0; + if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0) { ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno); if (cs == NULL) return -2; do ce += GET(ce, 1); while (*ce == OP_ALT); - if (cc > cs && cc < ce) /* Simple recursion */ - { - d = 0; - had_recurse = TRUE; - } - else + + if (!dupcapused || + (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL) { - recurse_check *r = recurses; - for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; - if (r != NULL) /* Mutual recursion */ + if (cc > cs && cc < ce) /* Simple recursion */ { - d = 0; had_recurse = TRUE; } else { - this_recurse.prev = recurses; - this_recurse.group = cs; - d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr, - backref_cache); - if (d < 0) return d; + recurse_check *r = recurses; + for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break; + if (r != NULL) /* Mutual recursion */ + { + had_recurse = TRUE; + } + else /* No recursion */ + { + this_recurse.prev = recurses; + this_recurse.group = cs; + d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr, + backref_cache); + if (d < 0) return d; + } } } } - else d = 0; backref_cache[recno] = d; for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1; @@ -888,7 +909,7 @@ if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff; /************************************************* -* Create bitmap of starting bytes * +* Create bitmap of starting code units * *************************************************/ /* This function scans a compiled unanchored expression recursively and @@ -938,6 +959,9 @@ do { int rc; uint8_t *classmap = NULL; +#ifdef SUPPORT_WIDE_CHARS + PCRE2_UCHAR xclassflags; +#endif switch(*tcode) { @@ -1078,6 +1102,7 @@ do case OP_ONCE: case OP_SCRIPT_RUN: case OP_ASSERT: + case OP_ASSERT_NA: rc = set_start_bits(re, tcode, utf); if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; if (rc == SSB_DONE) try_next = FALSE; else @@ -1120,6 +1145,7 @@ do case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: + case OP_ASSERTBACK_NA: do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1 + LINK_SIZE; break; @@ -1444,20 +1470,59 @@ do negative XCLASS without a map, give up. If there are no property checks, there must be wide characters on the XCLASS list, because otherwise an XCLASS would not have been created. This means that code points >= 255 - are always potential starters. */ + are potential starters. In the UTF-8 case we can scan them and set bits + for the relevant leading bytes. */ #ifdef SUPPORT_WIDE_CHARS case OP_XCLASS: - if ((tcode[1 + LINK_SIZE] & XCL_HASPROP) != 0 || - (tcode[1 + LINK_SIZE] & (XCL_MAP|XCL_NOT)) == XCL_NOT) + xclassflags = tcode[1 + LINK_SIZE]; + if ((xclassflags & XCL_HASPROP) != 0 || + (xclassflags & (XCL_MAP|XCL_NOT)) == XCL_NOT) return SSB_FAIL; /* We have a positive XCLASS or a negative one without a map. Set up the map pointer if there is one, and fall through. */ - classmap = ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0)? NULL : + classmap = ((xclassflags & XCL_MAP) == 0)? NULL : (uint8_t *)(tcode + 1 + LINK_SIZE + 1); -#endif + + /* In UTF-8 mode, scan the character list and set bits for leading bytes, + then jump to handle the map. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (utf && (xclassflags & XCL_NOT) == 0) + { + PCRE2_UCHAR b, e; + PCRE2_SPTR p = tcode + 1 + LINK_SIZE + 1 + ((classmap == NULL)? 0:32); + tcode += GET(tcode, 1); + + for (;;) switch (*p++) + { + case XCL_SINGLE: + b = *p++; + while ((*p & 0xc0) == 0x80) p++; + re->start_bitmap[b/8] |= (1u << (b&7)); + break; + + case XCL_RANGE: + b = *p++; + while ((*p & 0xc0) == 0x80) p++; + e = *p++; + while ((*p & 0xc0) == 0x80) p++; + for (; b <= e; b++) + re->start_bitmap[b/8] |= (1u << (b&7)); + break; + + case XCL_END: + goto HANDLE_CLASSMAP; + + default: + return SSB_UNKNOWN; /* Internal error, should not occur */ + } + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ +#endif /* SUPPORT_WIDE_CHARS */ + /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ @@ -1499,6 +1564,9 @@ do greater than 127. In fact, there are only two possible starting bytes for characters in the range 128 - 255. */ +#if defined SUPPORT_WIDE_CHARS && PCRE2_CODE_UNIT_WIDTH == 8 + HANDLE_CLASSMAP: +#endif if (classmap != NULL) { #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 @@ -1569,7 +1637,9 @@ return yield; /* This function is handed a compiled expression that it must study to produce information that will speed up the matching. -Argument: points to the compiled expression +Argument: + re points to the compiled expression + Returns: 0 normally; non-zero should never normally occur 1 unknown opcode in set_start_bits 2 missing capturing bracket @@ -1579,7 +1649,6 @@ Returns: 0 normally; non-zero should never normally occur int PRIV(study)(pcre2_real_code *re) { -int min; int count = 0; PCRE2_UCHAR *code; BOOL utf = (re->overall_options & PCRE2_UTF) != 0; @@ -1597,25 +1666,121 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0) { int rc = set_start_bits(re, code, utf); if (rc == SSB_UNKNOWN) return 1; - if (rc == SSB_DONE) re->flags |= PCRE2_FIRSTMAPSET; + + /* If a list of starting code units was set up, scan the list to see if only + one or two were listed. Having only one listed is rare because usually a + single starting code unit will have been recognized and PCRE2_FIRSTSET set. + If two are listed, see if they are caseless versions of the same character; + if so we can replace the list with a caseless first code unit. This gives + better performance and is plausibly worth doing for patterns such as [Ww]ord + or (word|WORD). */ + + if (rc == SSB_DONE) + { + int i; + int a = -1; + int b = -1; + uint8_t *p = re->start_bitmap; + uint32_t flags = PCRE2_FIRSTMAPSET; + + for (i = 0; i < 256; p++, i += 8) + { + uint8_t x = *p; + if (x != 0) + { + int c; + uint8_t y = x & (~x + 1); /* Least significant bit */ + if (y != x) goto DONE; /* More than one bit set */ + + /* In the 16-bit and 32-bit libraries, the bit for 0xff means "0xff and + all wide characters", so we cannot use it here. */ + +#if PCRE2_CODE_UNIT_WIDTH != 8 + if (i == 248 && x == 0x80) goto DONE; +#endif + + /* Compute the character value */ + + c = i; + switch (x) + { + case 1: break; + case 2: c += 1; break; case 4: c += 2; break; + case 8: c += 3; break; case 16: c += 4; break; + case 32: c += 5; break; case 64: c += 6; break; + case 128: c += 7; break; + } + + /* c contains the code unit value, in the range 0-255. In 8-bit UTF + mode, only values < 128 can be used. */ + +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (c > 127) goto DONE; +#endif + if (a < 0) a = c; /* First one found */ + else if (b < 0) /* Second one found */ + { + int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c); + +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + if (utf && UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */ +#else /* 16-bit or 32-bit */ + if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */ + if (utf && c > 127) d = UCD_OTHERCASE(c); +#endif /* Code width */ +#endif /* SUPPORT_UNICODE */ + + if (d != a) goto DONE; /* Not other case of a */ + b = c; + } + else goto DONE; /* More than two characters found */ + } + } + + /* Replace the start code unit bits with a first code unit, but only if it + is not the same as a required later code unit. This is because a search for + a required code unit starts after an explicit first code unit, but at a + code unit found from the bitmap. Patterns such as /a*a/ don't work + if both the start unit and required unit are the same. */ + + if (a >= 0 && + ( + (re->flags & PCRE2_LASTSET) == 0 || + ( + re->last_codeunit != (uint32_t)a && + (b < 0 || re->last_codeunit != (uint32_t)b) + ) + )) + { + re->first_codeunit = a; + flags = PCRE2_FIRSTSET; + if (b >= 0) flags |= PCRE2_FIRSTCASELESS; + } + + DONE: + re->flags |= flags; + } } /* Find the minimum length of subject string. If the pattern can match an empty -string, the minimum length is already known. If there are more back references -than the size of the vector we are going to cache them in, do nothing. A -pattern that complicated will probably take a long time to analyze and may in -any case turn out to be too complicated. Note that back reference minima are -held as 16-bit numbers. */ - -if ((re->flags & PCRE2_MATCH_EMPTY) == 0 && +string, the minimum length is already known. If the pattern contains (*ACCEPT) +all bets are off, and we don't even try to find a minimum length. If there are +more back references than the size of the vector we are going to cache them in, +do nothing. A pattern that complicated will probably take a long time to +analyze and may in any case turn out to be too complicated. Note that back +reference minima are held as 16-bit numbers. */ + +if ((re->flags & (PCRE2_MATCH_EMPTY|PCRE2_HASACCEPT)) == 0 && re->top_backref <= MAX_CACHE_BACKREF) { + int min; int backref_cache[MAX_CACHE_BACKREF+1]; backref_cache[0] = 0; /* Highest one that is set */ min = find_minlength(re, code, code, utf, NULL, &count, backref_cache); switch(min) { - case -1: /* \C in UTF mode or (*ACCEPT) or over-complex regex */ + case -1: /* \C in UTF mode or over-complex regex */ break; /* Leave minlength unchanged (will be zero) */ case -2: @@ -1625,8 +1790,7 @@ if ((re->flags & PCRE2_MATCH_EMPTY) == 0 && return 3; /* unrecognized opcode */ default: - if (min > UINT16_MAX) min = UINT16_MAX; - re->minlength = min; + re->minlength = (min > UINT16_MAX)? UINT16_MAX : min; break; } } diff --git a/ext/pcre/pcre2lib/pcre2_tables.c b/ext/pcre/pcre2lib/pcre2_tables.c index 84019361fce34..25531d98c6890 100644 --- a/ext/pcre/pcre2lib/pcre2_tables.c +++ b/ext/pcre/pcre2lib/pcre2_tables.c @@ -279,6 +279,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0" #define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0" #define STRING_Elbasan0 STR_E STR_l STR_b STR_a STR_s STR_a STR_n "\0" +#define STRING_Elymaic0 STR_E STR_l STR_y STR_m STR_a STR_i STR_c "\0" #define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0" #define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0" #define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0" @@ -348,6 +349,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0" #define STRING_N0 STR_N "\0" #define STRING_Nabataean0 STR_N STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0" +#define STRING_Nandinagari0 STR_N STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i "\0" #define STRING_Nd0 STR_N STR_d "\0" #define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0" #define STRING_Newa0 STR_N STR_e STR_w STR_a "\0" @@ -355,6 +357,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Nl0 STR_N STR_l "\0" #define STRING_No0 STR_N STR_o "\0" #define STRING_Nushu0 STR_N STR_u STR_s STR_h STR_u "\0" +#define STRING_Nyiakeng_Puachue_Hmong0 STR_N STR_y STR_i STR_a STR_k STR_e STR_n STR_g STR_UNDERSCORE STR_P STR_u STR_a STR_c STR_h STR_u STR_e STR_UNDERSCORE STR_H STR_m STR_o STR_n STR_g "\0" #define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0" #define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0" #define STRING_Old_Hungarian0 STR_O STR_l STR_d STR_UNDERSCORE STR_H STR_u STR_n STR_g STR_a STR_r STR_i STR_a STR_n "\0" @@ -419,6 +422,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0" #define STRING_Unknown0 STR_U STR_n STR_k STR_n STR_o STR_w STR_n "\0" #define STRING_Vai0 STR_V STR_a STR_i "\0" +#define STRING_Wancho0 STR_W STR_a STR_n STR_c STR_h STR_o "\0" #define STRING_Warang_Citi0 STR_W STR_a STR_r STR_a STR_n STR_g STR_UNDERSCORE STR_C STR_i STR_t STR_i "\0" #define STRING_Xan0 STR_X STR_a STR_n "\0" #define STRING_Xps0 STR_X STR_p STR_s "\0" @@ -474,6 +478,7 @@ const char PRIV(utt_names)[] = STRING_Duployan0 STRING_Egyptian_Hieroglyphs0 STRING_Elbasan0 + STRING_Elymaic0 STRING_Ethiopic0 STRING_Georgian0 STRING_Glagolitic0 @@ -543,6 +548,7 @@ const char PRIV(utt_names)[] = STRING_Myanmar0 STRING_N0 STRING_Nabataean0 + STRING_Nandinagari0 STRING_Nd0 STRING_New_Tai_Lue0 STRING_Newa0 @@ -550,6 +556,7 @@ const char PRIV(utt_names)[] = STRING_Nl0 STRING_No0 STRING_Nushu0 + STRING_Nyiakeng_Puachue_Hmong0 STRING_Ogham0 STRING_Ol_Chiki0 STRING_Old_Hungarian0 @@ -614,6 +621,7 @@ const char PRIV(utt_names)[] = STRING_Ugaritic0 STRING_Unknown0 STRING_Vai0 + STRING_Wancho0 STRING_Warang_Citi0 STRING_Xan0 STRING_Xps0 @@ -669,158 +677,162 @@ const ucp_type_table PRIV(utt)[] = { { 299, PT_SC, ucp_Duployan }, { 308, PT_SC, ucp_Egyptian_Hieroglyphs }, { 329, PT_SC, ucp_Elbasan }, - { 337, PT_SC, ucp_Ethiopic }, - { 346, PT_SC, ucp_Georgian }, - { 355, PT_SC, ucp_Glagolitic }, - { 366, PT_SC, ucp_Gothic }, - { 373, PT_SC, ucp_Grantha }, - { 381, PT_SC, ucp_Greek }, - { 387, PT_SC, ucp_Gujarati }, - { 396, PT_SC, ucp_Gunjala_Gondi }, - { 410, PT_SC, ucp_Gurmukhi }, - { 419, PT_SC, ucp_Han }, - { 423, PT_SC, ucp_Hangul }, - { 430, PT_SC, ucp_Hanifi_Rohingya }, - { 446, PT_SC, ucp_Hanunoo }, - { 454, PT_SC, ucp_Hatran }, - { 461, PT_SC, ucp_Hebrew }, - { 468, PT_SC, ucp_Hiragana }, - { 477, PT_SC, ucp_Imperial_Aramaic }, - { 494, PT_SC, ucp_Inherited }, - { 504, PT_SC, ucp_Inscriptional_Pahlavi }, - { 526, PT_SC, ucp_Inscriptional_Parthian }, - { 549, PT_SC, ucp_Javanese }, - { 558, PT_SC, ucp_Kaithi }, - { 565, PT_SC, ucp_Kannada }, - { 573, PT_SC, ucp_Katakana }, - { 582, PT_SC, ucp_Kayah_Li }, - { 591, PT_SC, ucp_Kharoshthi }, - { 602, PT_SC, ucp_Khmer }, - { 608, PT_SC, ucp_Khojki }, - { 615, PT_SC, ucp_Khudawadi }, - { 625, PT_GC, ucp_L }, - { 627, PT_LAMP, 0 }, - { 630, PT_SC, ucp_Lao }, - { 634, PT_SC, ucp_Latin }, - { 640, PT_SC, ucp_Lepcha }, - { 647, PT_SC, ucp_Limbu }, - { 653, PT_SC, ucp_Linear_A }, - { 662, PT_SC, ucp_Linear_B }, - { 671, PT_SC, ucp_Lisu }, - { 676, PT_PC, ucp_Ll }, - { 679, PT_PC, ucp_Lm }, - { 682, PT_PC, ucp_Lo }, - { 685, PT_PC, ucp_Lt }, - { 688, PT_PC, ucp_Lu }, - { 691, PT_SC, ucp_Lycian }, - { 698, PT_SC, ucp_Lydian }, - { 705, PT_GC, ucp_M }, - { 707, PT_SC, ucp_Mahajani }, - { 716, PT_SC, ucp_Makasar }, - { 724, PT_SC, ucp_Malayalam }, - { 734, PT_SC, ucp_Mandaic }, - { 742, PT_SC, ucp_Manichaean }, - { 753, PT_SC, ucp_Marchen }, - { 761, PT_SC, ucp_Masaram_Gondi }, - { 775, PT_PC, ucp_Mc }, - { 778, PT_PC, ucp_Me }, - { 781, PT_SC, ucp_Medefaidrin }, - { 793, PT_SC, ucp_Meetei_Mayek }, - { 806, PT_SC, ucp_Mende_Kikakui }, - { 820, PT_SC, ucp_Meroitic_Cursive }, - { 837, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 858, PT_SC, ucp_Miao }, - { 863, PT_PC, ucp_Mn }, - { 866, PT_SC, ucp_Modi }, - { 871, PT_SC, ucp_Mongolian }, - { 881, PT_SC, ucp_Mro }, - { 885, PT_SC, ucp_Multani }, - { 893, PT_SC, ucp_Myanmar }, - { 901, PT_GC, ucp_N }, - { 903, PT_SC, ucp_Nabataean }, - { 913, PT_PC, ucp_Nd }, - { 916, PT_SC, ucp_New_Tai_Lue }, - { 928, PT_SC, ucp_Newa }, - { 933, PT_SC, ucp_Nko }, - { 937, PT_PC, ucp_Nl }, - { 940, PT_PC, ucp_No }, - { 943, PT_SC, ucp_Nushu }, - { 949, PT_SC, ucp_Ogham }, - { 955, PT_SC, ucp_Ol_Chiki }, - { 964, PT_SC, ucp_Old_Hungarian }, - { 978, PT_SC, ucp_Old_Italic }, - { 989, PT_SC, ucp_Old_North_Arabian }, - { 1007, PT_SC, ucp_Old_Permic }, - { 1018, PT_SC, ucp_Old_Persian }, - { 1030, PT_SC, ucp_Old_Sogdian }, - { 1042, PT_SC, ucp_Old_South_Arabian }, - { 1060, PT_SC, ucp_Old_Turkic }, - { 1071, PT_SC, ucp_Oriya }, - { 1077, PT_SC, ucp_Osage }, - { 1083, PT_SC, ucp_Osmanya }, - { 1091, PT_GC, ucp_P }, - { 1093, PT_SC, ucp_Pahawh_Hmong }, - { 1106, PT_SC, ucp_Palmyrene }, - { 1116, PT_SC, ucp_Pau_Cin_Hau }, - { 1128, PT_PC, ucp_Pc }, - { 1131, PT_PC, ucp_Pd }, - { 1134, PT_PC, ucp_Pe }, - { 1137, PT_PC, ucp_Pf }, - { 1140, PT_SC, ucp_Phags_Pa }, - { 1149, PT_SC, ucp_Phoenician }, - { 1160, PT_PC, ucp_Pi }, - { 1163, PT_PC, ucp_Po }, - { 1166, PT_PC, ucp_Ps }, - { 1169, PT_SC, ucp_Psalter_Pahlavi }, - { 1185, PT_SC, ucp_Rejang }, - { 1192, PT_SC, ucp_Runic }, - { 1198, PT_GC, ucp_S }, - { 1200, PT_SC, ucp_Samaritan }, - { 1210, PT_SC, ucp_Saurashtra }, - { 1221, PT_PC, ucp_Sc }, - { 1224, PT_SC, ucp_Sharada }, - { 1232, PT_SC, ucp_Shavian }, - { 1240, PT_SC, ucp_Siddham }, - { 1248, PT_SC, ucp_SignWriting }, - { 1260, PT_SC, ucp_Sinhala }, - { 1268, PT_PC, ucp_Sk }, - { 1271, PT_PC, ucp_Sm }, - { 1274, PT_PC, ucp_So }, - { 1277, PT_SC, ucp_Sogdian }, - { 1285, PT_SC, ucp_Sora_Sompeng }, - { 1298, PT_SC, ucp_Soyombo }, - { 1306, PT_SC, ucp_Sundanese }, - { 1316, PT_SC, ucp_Syloti_Nagri }, - { 1329, PT_SC, ucp_Syriac }, - { 1336, PT_SC, ucp_Tagalog }, - { 1344, PT_SC, ucp_Tagbanwa }, - { 1353, PT_SC, ucp_Tai_Le }, - { 1360, PT_SC, ucp_Tai_Tham }, - { 1369, PT_SC, ucp_Tai_Viet }, - { 1378, PT_SC, ucp_Takri }, - { 1384, PT_SC, ucp_Tamil }, - { 1390, PT_SC, ucp_Tangut }, - { 1397, PT_SC, ucp_Telugu }, - { 1404, PT_SC, ucp_Thaana }, - { 1411, PT_SC, ucp_Thai }, - { 1416, PT_SC, ucp_Tibetan }, - { 1424, PT_SC, ucp_Tifinagh }, - { 1433, PT_SC, ucp_Tirhuta }, - { 1441, PT_SC, ucp_Ugaritic }, - { 1450, PT_SC, ucp_Unknown }, - { 1458, PT_SC, ucp_Vai }, - { 1462, PT_SC, ucp_Warang_Citi }, - { 1474, PT_ALNUM, 0 }, - { 1478, PT_PXSPACE, 0 }, - { 1482, PT_SPACE, 0 }, - { 1486, PT_UCNC, 0 }, - { 1490, PT_WORD, 0 }, - { 1494, PT_SC, ucp_Yi }, - { 1497, PT_GC, ucp_Z }, - { 1499, PT_SC, ucp_Zanabazar_Square }, - { 1516, PT_PC, ucp_Zl }, - { 1519, PT_PC, ucp_Zp }, - { 1522, PT_PC, ucp_Zs } + { 337, PT_SC, ucp_Elymaic }, + { 345, PT_SC, ucp_Ethiopic }, + { 354, PT_SC, ucp_Georgian }, + { 363, PT_SC, ucp_Glagolitic }, + { 374, PT_SC, ucp_Gothic }, + { 381, PT_SC, ucp_Grantha }, + { 389, PT_SC, ucp_Greek }, + { 395, PT_SC, ucp_Gujarati }, + { 404, PT_SC, ucp_Gunjala_Gondi }, + { 418, PT_SC, ucp_Gurmukhi }, + { 427, PT_SC, ucp_Han }, + { 431, PT_SC, ucp_Hangul }, + { 438, PT_SC, ucp_Hanifi_Rohingya }, + { 454, PT_SC, ucp_Hanunoo }, + { 462, PT_SC, ucp_Hatran }, + { 469, PT_SC, ucp_Hebrew }, + { 476, PT_SC, ucp_Hiragana }, + { 485, PT_SC, ucp_Imperial_Aramaic }, + { 502, PT_SC, ucp_Inherited }, + { 512, PT_SC, ucp_Inscriptional_Pahlavi }, + { 534, PT_SC, ucp_Inscriptional_Parthian }, + { 557, PT_SC, ucp_Javanese }, + { 566, PT_SC, ucp_Kaithi }, + { 573, PT_SC, ucp_Kannada }, + { 581, PT_SC, ucp_Katakana }, + { 590, PT_SC, ucp_Kayah_Li }, + { 599, PT_SC, ucp_Kharoshthi }, + { 610, PT_SC, ucp_Khmer }, + { 616, PT_SC, ucp_Khojki }, + { 623, PT_SC, ucp_Khudawadi }, + { 633, PT_GC, ucp_L }, + { 635, PT_LAMP, 0 }, + { 638, PT_SC, ucp_Lao }, + { 642, PT_SC, ucp_Latin }, + { 648, PT_SC, ucp_Lepcha }, + { 655, PT_SC, ucp_Limbu }, + { 661, PT_SC, ucp_Linear_A }, + { 670, PT_SC, ucp_Linear_B }, + { 679, PT_SC, ucp_Lisu }, + { 684, PT_PC, ucp_Ll }, + { 687, PT_PC, ucp_Lm }, + { 690, PT_PC, ucp_Lo }, + { 693, PT_PC, ucp_Lt }, + { 696, PT_PC, ucp_Lu }, + { 699, PT_SC, ucp_Lycian }, + { 706, PT_SC, ucp_Lydian }, + { 713, PT_GC, ucp_M }, + { 715, PT_SC, ucp_Mahajani }, + { 724, PT_SC, ucp_Makasar }, + { 732, PT_SC, ucp_Malayalam }, + { 742, PT_SC, ucp_Mandaic }, + { 750, PT_SC, ucp_Manichaean }, + { 761, PT_SC, ucp_Marchen }, + { 769, PT_SC, ucp_Masaram_Gondi }, + { 783, PT_PC, ucp_Mc }, + { 786, PT_PC, ucp_Me }, + { 789, PT_SC, ucp_Medefaidrin }, + { 801, PT_SC, ucp_Meetei_Mayek }, + { 814, PT_SC, ucp_Mende_Kikakui }, + { 828, PT_SC, ucp_Meroitic_Cursive }, + { 845, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 866, PT_SC, ucp_Miao }, + { 871, PT_PC, ucp_Mn }, + { 874, PT_SC, ucp_Modi }, + { 879, PT_SC, ucp_Mongolian }, + { 889, PT_SC, ucp_Mro }, + { 893, PT_SC, ucp_Multani }, + { 901, PT_SC, ucp_Myanmar }, + { 909, PT_GC, ucp_N }, + { 911, PT_SC, ucp_Nabataean }, + { 921, PT_SC, ucp_Nandinagari }, + { 933, PT_PC, ucp_Nd }, + { 936, PT_SC, ucp_New_Tai_Lue }, + { 948, PT_SC, ucp_Newa }, + { 953, PT_SC, ucp_Nko }, + { 957, PT_PC, ucp_Nl }, + { 960, PT_PC, ucp_No }, + { 963, PT_SC, ucp_Nushu }, + { 969, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 992, PT_SC, ucp_Ogham }, + { 998, PT_SC, ucp_Ol_Chiki }, + { 1007, PT_SC, ucp_Old_Hungarian }, + { 1021, PT_SC, ucp_Old_Italic }, + { 1032, PT_SC, ucp_Old_North_Arabian }, + { 1050, PT_SC, ucp_Old_Permic }, + { 1061, PT_SC, ucp_Old_Persian }, + { 1073, PT_SC, ucp_Old_Sogdian }, + { 1085, PT_SC, ucp_Old_South_Arabian }, + { 1103, PT_SC, ucp_Old_Turkic }, + { 1114, PT_SC, ucp_Oriya }, + { 1120, PT_SC, ucp_Osage }, + { 1126, PT_SC, ucp_Osmanya }, + { 1134, PT_GC, ucp_P }, + { 1136, PT_SC, ucp_Pahawh_Hmong }, + { 1149, PT_SC, ucp_Palmyrene }, + { 1159, PT_SC, ucp_Pau_Cin_Hau }, + { 1171, PT_PC, ucp_Pc }, + { 1174, PT_PC, ucp_Pd }, + { 1177, PT_PC, ucp_Pe }, + { 1180, PT_PC, ucp_Pf }, + { 1183, PT_SC, ucp_Phags_Pa }, + { 1192, PT_SC, ucp_Phoenician }, + { 1203, PT_PC, ucp_Pi }, + { 1206, PT_PC, ucp_Po }, + { 1209, PT_PC, ucp_Ps }, + { 1212, PT_SC, ucp_Psalter_Pahlavi }, + { 1228, PT_SC, ucp_Rejang }, + { 1235, PT_SC, ucp_Runic }, + { 1241, PT_GC, ucp_S }, + { 1243, PT_SC, ucp_Samaritan }, + { 1253, PT_SC, ucp_Saurashtra }, + { 1264, PT_PC, ucp_Sc }, + { 1267, PT_SC, ucp_Sharada }, + { 1275, PT_SC, ucp_Shavian }, + { 1283, PT_SC, ucp_Siddham }, + { 1291, PT_SC, ucp_SignWriting }, + { 1303, PT_SC, ucp_Sinhala }, + { 1311, PT_PC, ucp_Sk }, + { 1314, PT_PC, ucp_Sm }, + { 1317, PT_PC, ucp_So }, + { 1320, PT_SC, ucp_Sogdian }, + { 1328, PT_SC, ucp_Sora_Sompeng }, + { 1341, PT_SC, ucp_Soyombo }, + { 1349, PT_SC, ucp_Sundanese }, + { 1359, PT_SC, ucp_Syloti_Nagri }, + { 1372, PT_SC, ucp_Syriac }, + { 1379, PT_SC, ucp_Tagalog }, + { 1387, PT_SC, ucp_Tagbanwa }, + { 1396, PT_SC, ucp_Tai_Le }, + { 1403, PT_SC, ucp_Tai_Tham }, + { 1412, PT_SC, ucp_Tai_Viet }, + { 1421, PT_SC, ucp_Takri }, + { 1427, PT_SC, ucp_Tamil }, + { 1433, PT_SC, ucp_Tangut }, + { 1440, PT_SC, ucp_Telugu }, + { 1447, PT_SC, ucp_Thaana }, + { 1454, PT_SC, ucp_Thai }, + { 1459, PT_SC, ucp_Tibetan }, + { 1467, PT_SC, ucp_Tifinagh }, + { 1476, PT_SC, ucp_Tirhuta }, + { 1484, PT_SC, ucp_Ugaritic }, + { 1493, PT_SC, ucp_Unknown }, + { 1501, PT_SC, ucp_Vai }, + { 1505, PT_SC, ucp_Wancho }, + { 1512, PT_SC, ucp_Warang_Citi }, + { 1524, PT_ALNUM, 0 }, + { 1528, PT_PXSPACE, 0 }, + { 1532, PT_SPACE, 0 }, + { 1536, PT_UCNC, 0 }, + { 1540, PT_WORD, 0 }, + { 1544, PT_SC, ucp_Yi }, + { 1547, PT_GC, ucp_Z }, + { 1549, PT_SC, ucp_Zanabazar_Square }, + { 1566, PT_PC, ucp_Zl }, + { 1569, PT_PC, ucp_Zp }, + { 1572, PT_PC, ucp_Zs } }; const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); diff --git a/ext/pcre/pcre2lib/pcre2_ucd.c b/ext/pcre/pcre2lib/pcre2_ucd.c index cc53c24001825..55ba03bd43304 100644 --- a/ext/pcre/pcre2lib/pcre2_ucd.c +++ b/ext/pcre/pcre2lib/pcre2_ucd.c @@ -20,7 +20,7 @@ needed. */ /* Unicode character database. */ /* This file was autogenerated by the MultiStage2.py script. */ -/* Total size: 97152 bytes, block size: 128. */ +/* Total size: 99316 bytes, block size: 128. */ /* The tables herein are needed only when UCP support is built, and in PCRE2 that happens automatically with UTF support. @@ -39,7 +39,7 @@ const uint16_t PRIV(ucd_stage2)[] = {0}; const uint32_t PRIV(ucd_caseless_sets)[] = {0}; #else -const char *PRIV(unicode_version) = "11.0.0"; +const char *PRIV(unicode_version) = "12.1.0"; /* If the 32-bit library is run in non-32-bit mode, character values greater than 0x10ffff may be encountered. For these we set up a @@ -116,7 +116,7 @@ set of decimal digits. It is used to ensure that all the digits in a script run come from the same set. */ const uint32_t PRIV(ucd_digit_sets)[] = { - 61, /* Number of subsequent values */ + 63, /* Number of subsequent values */ 0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef, 0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9, 0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89, @@ -124,7 +124,7 @@ const uint32_t PRIV(ucd_digit_sets)[] = { 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f, 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9, 0x11739, 0x118e9, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16b59, 0x1d7d7, - 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e959, + 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, 0x1e959, }; /* This vector is a list of lists of scripts for the Script Extension @@ -145,38 +145,42 @@ const uint8_t PRIV(ucd_script_sets)[] = { /* 31 */ 13, 34, 0, /* 34 */ 13, 118, 0, /* 37 */ 15, 107, 0, - /* 40 */ 15, 100, 0, - /* 43 */ 15, 54, 0, - /* 46 */ 17, 34, 0, - /* 49 */ 107, 54, 0, - /* 52 */ 21, 108, 0, - /* 55 */ 22, 129, 0, - /* 58 */ 27, 30, 0, - /* 61 */ 38, 65, 0, - /* 64 */ 1, 50, 56, 0, - /* 68 */ 3, 96, 49, 0, - /* 72 */ 96, 39, 53, 0, - /* 76 */ 12, 110, 36, 0, - /* 80 */ 15, 107, 29, 0, - /* 84 */ 15, 107, 34, 0, - /* 88 */ 23, 27, 30, 0, - /* 92 */ 69, 34, 39, 0, - /* 96 */ 1, 144, 50, 56, 0, - /* 101 */ 3, 15, 107, 29, 0, - /* 106 */ 7, 25, 52, 51, 0, - /* 111 */ 15, 142, 85, 111, 0, - /* 116 */ 4, 24, 23, 27, 30, 0, - /* 122 */ 4, 24, 23, 27, 30, 61, 0, - /* 129 */ 15, 29, 37, 44, 54, 55, 0, - /* 136 */ 132, 1, 95, 112, 121, 144, 148, 50, 0, - /* 145 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0, - /* 157 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0, - /* 170 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 109, 102, 124, 0, - /* 183 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0, - /* 197 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 109, 102, 124, 0, - /* 211 */ 3, 15, 142, 143, 107, 21, 22, 29, 111, 37, 44, 109, 48, 49, 102, 54, 55, 124, 0, - /* 230 */ 3, 15, 142, 143, 107, 21, 22, 29, 35, 111, 37, 44, 109, 48, 49, 102, 54, 55, 124, 0, - /* 250 */ + /* 40 */ 15, 150, 0, + /* 43 */ 15, 100, 0, + /* 46 */ 15, 54, 0, + /* 49 */ 17, 34, 0, + /* 52 */ 107, 54, 0, + /* 55 */ 21, 108, 0, + /* 58 */ 22, 129, 0, + /* 61 */ 27, 30, 0, + /* 64 */ 29, 150, 0, + /* 67 */ 34, 38, 0, + /* 70 */ 38, 65, 0, + /* 73 */ 1, 50, 56, 0, + /* 77 */ 3, 96, 49, 0, + /* 81 */ 96, 39, 53, 0, + /* 85 */ 12, 110, 36, 0, + /* 89 */ 15, 107, 29, 0, + /* 93 */ 15, 107, 34, 0, + /* 97 */ 23, 27, 30, 0, + /* 101 */ 69, 34, 39, 0, + /* 105 */ 1, 144, 50, 56, 0, + /* 110 */ 3, 15, 107, 29, 0, + /* 115 */ 7, 25, 52, 51, 0, + /* 120 */ 15, 142, 85, 111, 0, + /* 125 */ 4, 24, 23, 27, 30, 0, + /* 131 */ 4, 24, 23, 27, 30, 61, 0, + /* 138 */ 15, 29, 37, 44, 54, 55, 0, + /* 145 */ 132, 1, 95, 112, 121, 144, 148, 50, 0, + /* 154 */ 3, 15, 107, 29, 150, 44, 55, 124, 0, + /* 163 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0, + /* 175 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0, + /* 188 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0, + /* 202 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 150, 109, 102, 124, 0, + /* 216 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 150, 109, 102, 124, 0, + /* 231 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0, + /* 252 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 35, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0, + /* 274 */ }; /* These are the main two-stage UCD tables. The fields in each record are: @@ -185,7 +189,7 @@ offset to multichar other cases or zero (8 bits), offset to other case or zero (32 bits, signed), script extension (16 bits, signed), and a dummy 16-bit field to make the whole thing a multiple of 4 bytes. */ -const ucd_record PRIV(ucd_records)[] = { /* 11136 bytes, record size 12 */ +const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */ { 10, 0, 2, 0, 0, 10, 256, }, /* 0 */ { 10, 0, 2, 0, 0, 10, 0, }, /* 1 */ { 10, 0, 1, 0, 0, 10, 0, }, /* 2 */ @@ -288,832 +292,863 @@ const ucd_record PRIV(ucd_records)[] = { /* 11136 bytes, record size 12 */ { 34, 5, 12, 0, -214, 34, 0, }, /* 99 */ { 34, 5, 12, 0, 10727, 34, 0, }, /* 100 */ { 34, 5, 12, 0, -218, 34, 0, }, /* 101 */ - { 34, 5, 12, 0, 42282, 34, 0, }, /* 102 */ - { 34, 5, 12, 0, -69, 34, 0, }, /* 103 */ - { 34, 5, 12, 0, -217, 34, 0, }, /* 104 */ - { 34, 5, 12, 0, -71, 34, 0, }, /* 105 */ - { 34, 5, 12, 0, -219, 34, 0, }, /* 106 */ - { 34, 5, 12, 0, 42261, 34, 0, }, /* 107 */ - { 34, 5, 12, 0, 42258, 34, 0, }, /* 108 */ - { 34, 6, 12, 0, 0, 34, 0, }, /* 109 */ - { 10, 6, 12, 0, 0, 10, 0, }, /* 110 */ - { 4, 24, 12, 0, 0, 4, 0, }, /* 111 */ - { 28, 12, 3, 0, 0, 28, 0, }, /* 112 */ - { 28, 12, 3, 0, 0, 20, 0, }, /* 113 */ - { 28, 12, 3, 21, 116, 20, 0, }, /* 114 */ - { 28, 12, 3, 0, 0, 34, 0, }, /* 115 */ - { 20, 9, 12, 0, 1, 20, 0, }, /* 116 */ - { 20, 5, 12, 0, -1, 20, 0, }, /* 117 */ - { 20, 24, 12, 0, 0, 20, 0, }, /* 118 */ - { 0, 2, 12, 0, 0, 0, 0, }, /* 119 */ - { 20, 6, 12, 0, 0, 20, 0, }, /* 120 */ - { 20, 5, 12, 0, 130, 20, 0, }, /* 121 */ - { 20, 9, 12, 0, 116, 20, 0, }, /* 122 */ - { 20, 9, 12, 0, 38, 20, 0, }, /* 123 */ - { 20, 9, 12, 0, 37, 20, 0, }, /* 124 */ - { 20, 9, 12, 0, 64, 20, 0, }, /* 125 */ - { 20, 9, 12, 0, 63, 20, 0, }, /* 126 */ - { 20, 5, 12, 0, 0, 20, 0, }, /* 127 */ - { 20, 9, 12, 0, 32, 20, 0, }, /* 128 */ - { 20, 9, 12, 34, 32, 20, 0, }, /* 129 */ - { 20, 9, 12, 59, 32, 20, 0, }, /* 130 */ - { 20, 9, 12, 38, 32, 20, 0, }, /* 131 */ - { 20, 9, 12, 21, 32, 20, 0, }, /* 132 */ - { 20, 9, 12, 51, 32, 20, 0, }, /* 133 */ - { 20, 9, 12, 26, 32, 20, 0, }, /* 134 */ - { 20, 9, 12, 47, 32, 20, 0, }, /* 135 */ - { 20, 9, 12, 55, 32, 20, 0, }, /* 136 */ - { 20, 9, 12, 30, 32, 20, 0, }, /* 137 */ - { 20, 9, 12, 43, 32, 20, 0, }, /* 138 */ - { 20, 9, 12, 96, 32, 20, 0, }, /* 139 */ - { 20, 5, 12, 0, -38, 20, 0, }, /* 140 */ - { 20, 5, 12, 0, -37, 20, 0, }, /* 141 */ - { 20, 5, 12, 0, -32, 20, 0, }, /* 142 */ - { 20, 5, 12, 34, -32, 20, 0, }, /* 143 */ - { 20, 5, 12, 59, -32, 20, 0, }, /* 144 */ - { 20, 5, 12, 38, -32, 20, 0, }, /* 145 */ - { 20, 5, 12, 21, -116, 20, 0, }, /* 146 */ - { 20, 5, 12, 51, -32, 20, 0, }, /* 147 */ - { 20, 5, 12, 26, -775, 20, 0, }, /* 148 */ - { 20, 5, 12, 47, -32, 20, 0, }, /* 149 */ - { 20, 5, 12, 55, -32, 20, 0, }, /* 150 */ - { 20, 5, 12, 30, 1, 20, 0, }, /* 151 */ - { 20, 5, 12, 30, -32, 20, 0, }, /* 152 */ - { 20, 5, 12, 43, -32, 20, 0, }, /* 153 */ - { 20, 5, 12, 96, -32, 20, 0, }, /* 154 */ - { 20, 5, 12, 0, -64, 20, 0, }, /* 155 */ - { 20, 5, 12, 0, -63, 20, 0, }, /* 156 */ - { 20, 9, 12, 0, 8, 20, 0, }, /* 157 */ - { 20, 5, 12, 34, -30, 20, 0, }, /* 158 */ - { 20, 5, 12, 38, -25, 20, 0, }, /* 159 */ - { 20, 9, 12, 0, 0, 20, 0, }, /* 160 */ - { 20, 5, 12, 43, -15, 20, 0, }, /* 161 */ - { 20, 5, 12, 47, -22, 20, 0, }, /* 162 */ - { 20, 5, 12, 0, -8, 20, 0, }, /* 163 */ - { 11, 9, 12, 0, 1, 11, 0, }, /* 164 */ - { 11, 5, 12, 0, -1, 11, 0, }, /* 165 */ - { 20, 5, 12, 51, -54, 20, 0, }, /* 166 */ - { 20, 5, 12, 55, -48, 20, 0, }, /* 167 */ - { 20, 5, 12, 0, 7, 20, 0, }, /* 168 */ - { 20, 5, 12, 0, -116, 20, 0, }, /* 169 */ - { 20, 9, 12, 38, -60, 20, 0, }, /* 170 */ - { 20, 5, 12, 59, -64, 20, 0, }, /* 171 */ - { 20, 25, 12, 0, 0, 20, 0, }, /* 172 */ - { 20, 9, 12, 0, -7, 20, 0, }, /* 173 */ - { 20, 9, 12, 0, -130, 20, 0, }, /* 174 */ - { 13, 9, 12, 0, 80, 13, 0, }, /* 175 */ - { 13, 9, 12, 0, 32, 13, 0, }, /* 176 */ - { 13, 9, 12, 63, 32, 13, 0, }, /* 177 */ - { 13, 9, 12, 67, 32, 13, 0, }, /* 178 */ - { 13, 9, 12, 71, 32, 13, 0, }, /* 179 */ - { 13, 9, 12, 75, 32, 13, 0, }, /* 180 */ - { 13, 9, 12, 79, 32, 13, 0, }, /* 181 */ - { 13, 9, 12, 84, 32, 13, 0, }, /* 182 */ - { 13, 5, 12, 0, -32, 13, 0, }, /* 183 */ - { 13, 5, 12, 63, -32, 13, 0, }, /* 184 */ - { 13, 5, 12, 67, -32, 13, 0, }, /* 185 */ - { 13, 5, 12, 71, -32, 13, 0, }, /* 186 */ - { 13, 5, 12, 75, -32, 13, 0, }, /* 187 */ - { 13, 5, 12, 79, -32, 13, 0, }, /* 188 */ - { 13, 5, 12, 84, -32, 13, 0, }, /* 189 */ - { 13, 5, 12, 0, -80, 13, 0, }, /* 190 */ - { 13, 9, 12, 0, 1, 13, 0, }, /* 191 */ - { 13, 5, 12, 0, -1, 13, 0, }, /* 192 */ - { 13, 9, 12, 88, 1, 13, 0, }, /* 193 */ - { 13, 5, 12, 88, -1, 13, 0, }, /* 194 */ - { 13, 26, 12, 0, 0, 13, 0, }, /* 195 */ - { 13, 12, 3, 0, 0, -34, 0, }, /* 196 */ - { 13, 12, 3, 0, 0, -28, 0, }, /* 197 */ - { 28, 12, 3, 0, 0, -31, 0, }, /* 198 */ - { 13, 11, 3, 0, 0, 13, 0, }, /* 199 */ - { 13, 9, 12, 0, 15, 13, 0, }, /* 200 */ - { 13, 5, 12, 0, -15, 13, 0, }, /* 201 */ - { 2, 9, 12, 0, 48, 2, 0, }, /* 202 */ - { 2, 6, 12, 0, 0, 2, 0, }, /* 203 */ - { 2, 21, 12, 0, 0, 2, 0, }, /* 204 */ - { 2, 5, 12, 0, 0, 2, 0, }, /* 205 */ - { 2, 5, 12, 0, -48, 2, 0, }, /* 206 */ - { 10, 21, 12, 0, 0, -13, 0, }, /* 207 */ - { 2, 17, 12, 0, 0, 2, 0, }, /* 208 */ - { 2, 26, 12, 0, 0, 2, 0, }, /* 209 */ - { 2, 23, 12, 0, 0, 2, 0, }, /* 210 */ - { 26, 12, 3, 0, 0, 26, 0, }, /* 211 */ - { 26, 17, 12, 0, 0, 26, 0, }, /* 212 */ - { 26, 21, 12, 0, 0, 26, 0, }, /* 213 */ - { 26, 7, 12, 0, 0, 26, 0, }, /* 214 */ - { 1, 1, 4, 0, 0, 1, 0, }, /* 215 */ - { 10, 1, 4, 0, 0, 10, 0, }, /* 216 */ - { 1, 25, 12, 0, 0, 1, 0, }, /* 217 */ - { 1, 21, 12, 0, 0, 1, 0, }, /* 218 */ - { 1, 23, 12, 0, 0, 1, 0, }, /* 219 */ - { 10, 21, 12, 0, 0, -96, 0, }, /* 220 */ - { 1, 26, 12, 0, 0, 1, 0, }, /* 221 */ - { 1, 12, 3, 0, 0, 1, 0, }, /* 222 */ - { 1, 1, 2, 0, 0, -64, 0, }, /* 223 */ - { 1, 7, 12, 0, 0, 1, 0, }, /* 224 */ - { 10, 6, 12, 0, 0, -136, 0, }, /* 225 */ - { 28, 12, 3, 0, 0, -7, 0, }, /* 226 */ - { 1, 13, 12, 0, 0, -10, 0, }, /* 227 */ - { 1, 21, 12, 0, 0, -4, 0, }, /* 228 */ - { 1, 6, 12, 0, 0, 1, 0, }, /* 229 */ - { 1, 13, 12, 0, 0, 1, 0, }, /* 230 */ - { 50, 21, 12, 0, 0, 50, 0, }, /* 231 */ - { 50, 1, 4, 0, 0, 50, 0, }, /* 232 */ - { 50, 7, 12, 0, 0, 50, 0, }, /* 233 */ - { 50, 12, 3, 0, 0, 50, 0, }, /* 234 */ - { 56, 7, 12, 0, 0, 56, 0, }, /* 235 */ - { 56, 12, 3, 0, 0, 56, 0, }, /* 236 */ - { 64, 13, 12, 0, 0, 64, 0, }, /* 237 */ - { 64, 7, 12, 0, 0, 64, 0, }, /* 238 */ - { 64, 12, 3, 0, 0, 64, 0, }, /* 239 */ - { 64, 6, 12, 0, 0, 64, 0, }, /* 240 */ - { 64, 26, 12, 0, 0, 64, 0, }, /* 241 */ - { 64, 21, 12, 0, 0, 64, 0, }, /* 242 */ - { 64, 23, 12, 0, 0, 64, 0, }, /* 243 */ - { 90, 7, 12, 0, 0, 90, 0, }, /* 244 */ - { 90, 12, 3, 0, 0, 90, 0, }, /* 245 */ - { 90, 6, 12, 0, 0, 90, 0, }, /* 246 */ - { 90, 21, 12, 0, 0, 90, 0, }, /* 247 */ - { 95, 7, 12, 0, 0, 95, 0, }, /* 248 */ - { 95, 12, 3, 0, 0, 95, 0, }, /* 249 */ - { 95, 21, 12, 0, 0, 95, 0, }, /* 250 */ - { 15, 12, 3, 0, 0, 15, 0, }, /* 251 */ - { 15, 10, 5, 0, 0, 15, 0, }, /* 252 */ - { 15, 7, 12, 0, 0, 15, 0, }, /* 253 */ - { 28, 12, 3, 0, 0, -183, 0, }, /* 254 */ - { 28, 12, 3, 0, 0, -157, 0, }, /* 255 */ - { 10, 21, 12, 0, 0, -211, 0, }, /* 256 */ - { 10, 21, 12, 0, 0, -230, 0, }, /* 257 */ - { 15, 13, 12, 0, 0, -111, 0, }, /* 258 */ - { 15, 21, 12, 0, 0, 15, 0, }, /* 259 */ - { 15, 6, 12, 0, 0, 15, 0, }, /* 260 */ - { 3, 7, 12, 0, 0, 3, 0, }, /* 261 */ - { 3, 12, 3, 0, 0, 3, 0, }, /* 262 */ - { 3, 10, 5, 0, 0, 3, 0, }, /* 263 */ - { 3, 10, 3, 0, 0, 3, 0, }, /* 264 */ - { 3, 13, 12, 0, 0, -68, 0, }, /* 265 */ - { 3, 23, 12, 0, 0, 3, 0, }, /* 266 */ - { 3, 15, 12, 0, 0, 3, 0, }, /* 267 */ - { 3, 26, 12, 0, 0, 3, 0, }, /* 268 */ - { 3, 21, 12, 0, 0, 3, 0, }, /* 269 */ - { 22, 12, 3, 0, 0, 22, 0, }, /* 270 */ - { 22, 10, 5, 0, 0, 22, 0, }, /* 271 */ - { 22, 7, 12, 0, 0, 22, 0, }, /* 272 */ - { 22, 13, 12, 0, 0, -55, 0, }, /* 273 */ - { 22, 21, 12, 0, 0, 22, 0, }, /* 274 */ - { 21, 12, 3, 0, 0, 21, 0, }, /* 275 */ - { 21, 10, 5, 0, 0, 21, 0, }, /* 276 */ - { 21, 7, 12, 0, 0, 21, 0, }, /* 277 */ - { 21, 13, 12, 0, 0, -52, 0, }, /* 278 */ - { 21, 21, 12, 0, 0, 21, 0, }, /* 279 */ - { 21, 23, 12, 0, 0, 21, 0, }, /* 280 */ - { 44, 12, 3, 0, 0, 44, 0, }, /* 281 */ - { 44, 10, 5, 0, 0, 44, 0, }, /* 282 */ - { 44, 7, 12, 0, 0, 44, 0, }, /* 283 */ - { 44, 10, 3, 0, 0, 44, 0, }, /* 284 */ - { 44, 13, 12, 0, 0, 44, 0, }, /* 285 */ - { 44, 26, 12, 0, 0, 44, 0, }, /* 286 */ - { 44, 15, 12, 0, 0, 44, 0, }, /* 287 */ - { 54, 12, 3, 0, 0, 54, 0, }, /* 288 */ - { 54, 7, 12, 0, 0, 54, 0, }, /* 289 */ - { 54, 10, 3, 0, 0, 54, 0, }, /* 290 */ - { 54, 10, 5, 0, 0, 54, 0, }, /* 291 */ - { 54, 13, 12, 0, 0, -49, 0, }, /* 292 */ - { 54, 15, 12, 0, 0, -49, 0, }, /* 293 */ - { 54, 26, 12, 0, 0, -49, 0, }, /* 294 */ - { 54, 26, 12, 0, 0, 54, 0, }, /* 295 */ - { 54, 23, 12, 0, 0, 54, 0, }, /* 296 */ - { 55, 12, 3, 0, 0, 55, 0, }, /* 297 */ - { 55, 10, 5, 0, 0, 55, 0, }, /* 298 */ - { 55, 7, 12, 0, 0, 55, 0, }, /* 299 */ - { 55, 13, 12, 0, 0, 55, 0, }, /* 300 */ - { 55, 15, 12, 0, 0, 55, 0, }, /* 301 */ - { 55, 26, 12, 0, 0, 55, 0, }, /* 302 */ - { 29, 7, 12, 0, 0, 29, 0, }, /* 303 */ - { 29, 12, 3, 0, 0, 29, 0, }, /* 304 */ - { 29, 10, 5, 0, 0, 29, 0, }, /* 305 */ - { 29, 21, 12, 0, 0, 29, 0, }, /* 306 */ - { 29, 10, 3, 0, 0, 29, 0, }, /* 307 */ - { 29, 13, 12, 0, 0, 29, 0, }, /* 308 */ - { 37, 12, 3, 0, 0, 37, 0, }, /* 309 */ - { 37, 10, 5, 0, 0, 37, 0, }, /* 310 */ - { 37, 7, 12, 0, 0, 37, 0, }, /* 311 */ - { 37, 10, 3, 0, 0, 37, 0, }, /* 312 */ - { 37, 7, 4, 0, 0, 37, 0, }, /* 313 */ - { 37, 26, 12, 0, 0, 37, 0, }, /* 314 */ - { 37, 15, 12, 0, 0, 37, 0, }, /* 315 */ - { 37, 13, 12, 0, 0, 37, 0, }, /* 316 */ - { 48, 10, 5, 0, 0, 48, 0, }, /* 317 */ - { 48, 7, 12, 0, 0, 48, 0, }, /* 318 */ - { 48, 12, 3, 0, 0, 48, 0, }, /* 319 */ - { 48, 10, 3, 0, 0, 48, 0, }, /* 320 */ - { 48, 13, 12, 0, 0, 48, 0, }, /* 321 */ - { 48, 21, 12, 0, 0, 48, 0, }, /* 322 */ - { 57, 7, 12, 0, 0, 57, 0, }, /* 323 */ - { 57, 12, 3, 0, 0, 57, 0, }, /* 324 */ - { 57, 7, 5, 0, 0, 57, 0, }, /* 325 */ - { 57, 6, 12, 0, 0, 57, 0, }, /* 326 */ - { 57, 21, 12, 0, 0, 57, 0, }, /* 327 */ - { 57, 13, 12, 0, 0, 57, 0, }, /* 328 */ - { 33, 7, 12, 0, 0, 33, 0, }, /* 329 */ - { 33, 12, 3, 0, 0, 33, 0, }, /* 330 */ - { 33, 7, 5, 0, 0, 33, 0, }, /* 331 */ - { 33, 6, 12, 0, 0, 33, 0, }, /* 332 */ - { 33, 13, 12, 0, 0, 33, 0, }, /* 333 */ - { 58, 7, 12, 0, 0, 58, 0, }, /* 334 */ - { 58, 26, 12, 0, 0, 58, 0, }, /* 335 */ - { 58, 21, 12, 0, 0, 58, 0, }, /* 336 */ - { 58, 12, 3, 0, 0, 58, 0, }, /* 337 */ - { 58, 13, 12, 0, 0, 58, 0, }, /* 338 */ - { 58, 15, 12, 0, 0, 58, 0, }, /* 339 */ - { 58, 22, 12, 0, 0, 58, 0, }, /* 340 */ - { 58, 18, 12, 0, 0, 58, 0, }, /* 341 */ - { 58, 10, 5, 0, 0, 58, 0, }, /* 342 */ - { 39, 7, 12, 0, 0, 39, 0, }, /* 343 */ - { 39, 10, 12, 0, 0, 39, 0, }, /* 344 */ - { 39, 12, 3, 0, 0, 39, 0, }, /* 345 */ - { 39, 10, 5, 0, 0, 39, 0, }, /* 346 */ - { 39, 13, 12, 0, 0, -72, 0, }, /* 347 */ - { 39, 21, 12, 0, 0, 39, 0, }, /* 348 */ - { 39, 13, 12, 0, 0, 39, 0, }, /* 349 */ - { 39, 26, 12, 0, 0, 39, 0, }, /* 350 */ - { 17, 9, 12, 0, 7264, 17, 0, }, /* 351 */ - { 17, 5, 12, 0, 3008, 17, 0, }, /* 352 */ - { 10, 21, 12, 0, 0, -46, 0, }, /* 353 */ - { 17, 6, 12, 0, 0, 17, 0, }, /* 354 */ - { 24, 7, 6, 0, 0, 24, 0, }, /* 355 */ - { 24, 7, 7, 0, 0, 24, 0, }, /* 356 */ - { 24, 7, 8, 0, 0, 24, 0, }, /* 357 */ - { 16, 7, 12, 0, 0, 16, 0, }, /* 358 */ - { 16, 12, 3, 0, 0, 16, 0, }, /* 359 */ - { 16, 21, 12, 0, 0, 16, 0, }, /* 360 */ - { 16, 15, 12, 0, 0, 16, 0, }, /* 361 */ - { 16, 26, 12, 0, 0, 16, 0, }, /* 362 */ - { 9, 9, 12, 0, 38864, 9, 0, }, /* 363 */ - { 9, 9, 12, 0, 8, 9, 0, }, /* 364 */ - { 9, 5, 12, 0, -8, 9, 0, }, /* 365 */ - { 8, 17, 12, 0, 0, 8, 0, }, /* 366 */ - { 8, 7, 12, 0, 0, 8, 0, }, /* 367 */ - { 8, 21, 12, 0, 0, 8, 0, }, /* 368 */ - { 41, 29, 12, 0, 0, 41, 0, }, /* 369 */ - { 41, 7, 12, 0, 0, 41, 0, }, /* 370 */ - { 41, 22, 12, 0, 0, 41, 0, }, /* 371 */ - { 41, 18, 12, 0, 0, 41, 0, }, /* 372 */ - { 46, 7, 12, 0, 0, 46, 0, }, /* 373 */ - { 46, 14, 12, 0, 0, 46, 0, }, /* 374 */ - { 51, 7, 12, 0, 0, 51, 0, }, /* 375 */ - { 51, 12, 3, 0, 0, 51, 0, }, /* 376 */ - { 25, 7, 12, 0, 0, 25, 0, }, /* 377 */ - { 25, 12, 3, 0, 0, 25, 0, }, /* 378 */ - { 10, 21, 12, 0, 0, -106, 0, }, /* 379 */ - { 7, 7, 12, 0, 0, 7, 0, }, /* 380 */ - { 7, 12, 3, 0, 0, 7, 0, }, /* 381 */ - { 52, 7, 12, 0, 0, 52, 0, }, /* 382 */ - { 52, 12, 3, 0, 0, 52, 0, }, /* 383 */ - { 32, 7, 12, 0, 0, 32, 0, }, /* 384 */ - { 32, 12, 3, 0, 0, 32, 0, }, /* 385 */ - { 32, 10, 5, 0, 0, 32, 0, }, /* 386 */ - { 32, 21, 12, 0, 0, 32, 0, }, /* 387 */ - { 32, 6, 12, 0, 0, 32, 0, }, /* 388 */ - { 32, 23, 12, 0, 0, 32, 0, }, /* 389 */ - { 32, 13, 12, 0, 0, 32, 0, }, /* 390 */ - { 32, 15, 12, 0, 0, 32, 0, }, /* 391 */ - { 38, 21, 12, 0, 0, 38, 0, }, /* 392 */ - { 10, 21, 12, 0, 0, -61, 0, }, /* 393 */ - { 38, 17, 12, 0, 0, 38, 0, }, /* 394 */ - { 38, 12, 3, 0, 0, 38, 0, }, /* 395 */ - { 38, 1, 2, 0, 0, 38, 0, }, /* 396 */ - { 38, 13, 12, 0, 0, 38, 0, }, /* 397 */ - { 38, 7, 12, 0, 0, 38, 0, }, /* 398 */ - { 38, 6, 12, 0, 0, 38, 0, }, /* 399 */ - { 35, 7, 12, 0, 0, 35, 0, }, /* 400 */ - { 35, 12, 3, 0, 0, 35, 0, }, /* 401 */ - { 35, 10, 5, 0, 0, 35, 0, }, /* 402 */ - { 35, 26, 12, 0, 0, 35, 0, }, /* 403 */ - { 35, 21, 12, 0, 0, 35, 0, }, /* 404 */ - { 35, 13, 12, 0, 0, 35, 0, }, /* 405 */ - { 53, 7, 12, 0, 0, 53, 0, }, /* 406 */ - { 40, 7, 12, 0, 0, 40, 0, }, /* 407 */ - { 40, 13, 12, 0, 0, 40, 0, }, /* 408 */ - { 40, 15, 12, 0, 0, 40, 0, }, /* 409 */ - { 40, 26, 12, 0, 0, 40, 0, }, /* 410 */ - { 32, 26, 12, 0, 0, 32, 0, }, /* 411 */ - { 6, 7, 12, 0, 0, 6, 0, }, /* 412 */ - { 6, 12, 3, 0, 0, 6, 0, }, /* 413 */ - { 6, 10, 5, 0, 0, 6, 0, }, /* 414 */ - { 6, 21, 12, 0, 0, 6, 0, }, /* 415 */ - { 91, 7, 12, 0, 0, 91, 0, }, /* 416 */ - { 91, 10, 5, 0, 0, 91, 0, }, /* 417 */ - { 91, 12, 3, 0, 0, 91, 0, }, /* 418 */ - { 91, 10, 12, 0, 0, 91, 0, }, /* 419 */ - { 91, 13, 12, 0, 0, 91, 0, }, /* 420 */ - { 91, 21, 12, 0, 0, 91, 0, }, /* 421 */ - { 91, 6, 12, 0, 0, 91, 0, }, /* 422 */ - { 28, 11, 3, 0, 0, 28, 0, }, /* 423 */ - { 62, 12, 3, 0, 0, 62, 0, }, /* 424 */ - { 62, 10, 5, 0, 0, 62, 0, }, /* 425 */ - { 62, 7, 12, 0, 0, 62, 0, }, /* 426 */ - { 62, 13, 12, 0, 0, 62, 0, }, /* 427 */ - { 62, 21, 12, 0, 0, 62, 0, }, /* 428 */ - { 62, 26, 12, 0, 0, 62, 0, }, /* 429 */ - { 76, 12, 3, 0, 0, 76, 0, }, /* 430 */ - { 76, 10, 5, 0, 0, 76, 0, }, /* 431 */ - { 76, 7, 12, 0, 0, 76, 0, }, /* 432 */ - { 76, 13, 12, 0, 0, 76, 0, }, /* 433 */ - { 93, 7, 12, 0, 0, 93, 0, }, /* 434 */ - { 93, 12, 3, 0, 0, 93, 0, }, /* 435 */ - { 93, 10, 5, 0, 0, 93, 0, }, /* 436 */ - { 93, 21, 12, 0, 0, 93, 0, }, /* 437 */ - { 70, 7, 12, 0, 0, 70, 0, }, /* 438 */ - { 70, 10, 5, 0, 0, 70, 0, }, /* 439 */ - { 70, 12, 3, 0, 0, 70, 0, }, /* 440 */ - { 70, 21, 12, 0, 0, 70, 0, }, /* 441 */ - { 70, 13, 12, 0, 0, 70, 0, }, /* 442 */ - { 73, 13, 12, 0, 0, 73, 0, }, /* 443 */ - { 73, 7, 12, 0, 0, 73, 0, }, /* 444 */ - { 73, 6, 12, 0, 0, 73, 0, }, /* 445 */ - { 73, 21, 12, 0, 0, 73, 0, }, /* 446 */ - { 13, 5, 12, 63, -6222, 13, 0, }, /* 447 */ - { 13, 5, 12, 67, -6221, 13, 0, }, /* 448 */ - { 13, 5, 12, 71, -6212, 13, 0, }, /* 449 */ - { 13, 5, 12, 75, -6210, 13, 0, }, /* 450 */ - { 13, 5, 12, 79, -6210, 13, 0, }, /* 451 */ - { 13, 5, 12, 79, -6211, 13, 0, }, /* 452 */ - { 13, 5, 12, 84, -6204, 13, 0, }, /* 453 */ - { 13, 5, 12, 88, -6180, 13, 0, }, /* 454 */ - { 13, 5, 12, 108, 35267, 13, 0, }, /* 455 */ - { 17, 9, 12, 0, -3008, 17, 0, }, /* 456 */ - { 76, 21, 12, 0, 0, 76, 0, }, /* 457 */ - { 28, 12, 3, 0, 0, -101, 0, }, /* 458 */ - { 28, 12, 3, 0, 0, 15, 0, }, /* 459 */ - { 10, 21, 12, 0, 0, -37, 0, }, /* 460 */ - { 28, 12, 3, 0, 0, -16, 0, }, /* 461 */ - { 28, 12, 3, 0, 0, -40, 0, }, /* 462 */ - { 28, 12, 3, 0, 0, -129, 0, }, /* 463 */ - { 10, 10, 5, 0, 0, -16, 0, }, /* 464 */ - { 10, 7, 12, 0, 0, 15, 0, }, /* 465 */ - { 10, 7, 12, 0, 0, -16, 0, }, /* 466 */ - { 10, 10, 5, 0, 0, -37, 0, }, /* 467 */ - { 28, 12, 3, 0, 0, -80, 0, }, /* 468 */ - { 10, 10, 5, 0, 0, 3, 0, }, /* 469 */ - { 28, 12, 3, 0, 0, -37, 0, }, /* 470 */ - { 13, 5, 12, 0, 0, 13, 0, }, /* 471 */ - { 13, 6, 12, 0, 0, 13, 0, }, /* 472 */ - { 34, 5, 12, 0, 35332, 34, 0, }, /* 473 */ - { 34, 5, 12, 0, 3814, 34, 0, }, /* 474 */ - { 34, 9, 12, 92, 1, 34, 0, }, /* 475 */ - { 34, 5, 12, 92, -1, 34, 0, }, /* 476 */ - { 34, 5, 12, 92, -58, 34, 0, }, /* 477 */ - { 34, 9, 12, 0, -7615, 34, 0, }, /* 478 */ - { 20, 5, 12, 0, 8, 20, 0, }, /* 479 */ - { 20, 9, 12, 0, -8, 20, 0, }, /* 480 */ - { 20, 5, 12, 0, 74, 20, 0, }, /* 481 */ - { 20, 5, 12, 0, 86, 20, 0, }, /* 482 */ - { 20, 5, 12, 0, 100, 20, 0, }, /* 483 */ - { 20, 5, 12, 0, 128, 20, 0, }, /* 484 */ - { 20, 5, 12, 0, 112, 20, 0, }, /* 485 */ - { 20, 5, 12, 0, 126, 20, 0, }, /* 486 */ - { 20, 8, 12, 0, -8, 20, 0, }, /* 487 */ - { 20, 5, 12, 0, 9, 20, 0, }, /* 488 */ - { 20, 9, 12, 0, -74, 20, 0, }, /* 489 */ - { 20, 8, 12, 0, -9, 20, 0, }, /* 490 */ - { 20, 5, 12, 21, -7173, 20, 0, }, /* 491 */ - { 20, 9, 12, 0, -86, 20, 0, }, /* 492 */ - { 20, 9, 12, 0, -100, 20, 0, }, /* 493 */ - { 20, 9, 12, 0, -112, 20, 0, }, /* 494 */ - { 20, 9, 12, 0, -128, 20, 0, }, /* 495 */ - { 20, 9, 12, 0, -126, 20, 0, }, /* 496 */ - { 28, 1, 3, 0, 0, 28, 0, }, /* 497 */ - { 28, 1, 13, 0, 0, 28, 0, }, /* 498 */ - { 10, 27, 2, 0, 0, 10, 0, }, /* 499 */ - { 10, 28, 2, 0, 0, 10, 0, }, /* 500 */ - { 10, 21, 14, 0, 0, 10, 0, }, /* 501 */ - { 0, 2, 2, 0, 0, 0, 0, }, /* 502 */ - { 28, 12, 3, 0, 0, -84, 0, }, /* 503 */ - { 10, 9, 12, 0, 0, 10, 0, }, /* 504 */ - { 10, 5, 12, 0, 0, 10, 0, }, /* 505 */ - { 20, 9, 12, 96, -7517, 20, 0, }, /* 506 */ - { 34, 9, 12, 100, -8383, 34, 0, }, /* 507 */ - { 34, 9, 12, 104, -8262, 34, 0, }, /* 508 */ - { 34, 9, 12, 0, 28, 34, 0, }, /* 509 */ - { 10, 7, 12, 0, 0, 10, 0, }, /* 510 */ - { 10, 5, 14, 0, 0, 10, 0, }, /* 511 */ - { 34, 5, 12, 0, -28, 34, 0, }, /* 512 */ - { 34, 14, 12, 0, 16, 34, 0, }, /* 513 */ - { 34, 14, 12, 0, -16, 34, 0, }, /* 514 */ - { 34, 14, 12, 0, 0, 34, 0, }, /* 515 */ - { 10, 25, 14, 0, 0, 10, 0, }, /* 516 */ - { 10, 26, 12, 0, 26, 10, 0, }, /* 517 */ - { 10, 26, 14, 0, 26, 10, 0, }, /* 518 */ - { 10, 26, 12, 0, -26, 10, 0, }, /* 519 */ - { 5, 26, 12, 0, 0, 5, 0, }, /* 520 */ - { 18, 9, 12, 0, 48, 18, 0, }, /* 521 */ - { 18, 5, 12, 0, -48, 18, 0, }, /* 522 */ - { 34, 9, 12, 0, -10743, 34, 0, }, /* 523 */ - { 34, 9, 12, 0, -3814, 34, 0, }, /* 524 */ - { 34, 9, 12, 0, -10727, 34, 0, }, /* 525 */ - { 34, 5, 12, 0, -10795, 34, 0, }, /* 526 */ - { 34, 5, 12, 0, -10792, 34, 0, }, /* 527 */ - { 34, 9, 12, 0, -10780, 34, 0, }, /* 528 */ - { 34, 9, 12, 0, -10749, 34, 0, }, /* 529 */ - { 34, 9, 12, 0, -10783, 34, 0, }, /* 530 */ - { 34, 9, 12, 0, -10782, 34, 0, }, /* 531 */ - { 34, 9, 12, 0, -10815, 34, 0, }, /* 532 */ - { 11, 5, 12, 0, 0, 11, 0, }, /* 533 */ - { 11, 26, 12, 0, 0, 11, 0, }, /* 534 */ - { 11, 12, 3, 0, 0, 11, 0, }, /* 535 */ - { 11, 21, 12, 0, 0, 11, 0, }, /* 536 */ - { 11, 15, 12, 0, 0, 11, 0, }, /* 537 */ - { 17, 5, 12, 0, -7264, 17, 0, }, /* 538 */ - { 59, 7, 12, 0, 0, 59, 0, }, /* 539 */ - { 59, 6, 12, 0, 0, 59, 0, }, /* 540 */ - { 59, 21, 12, 0, 0, 59, 0, }, /* 541 */ - { 59, 12, 3, 0, 0, 59, 0, }, /* 542 */ - { 13, 12, 3, 0, 0, 13, 0, }, /* 543 */ - { 10, 21, 12, 0, 0, -28, 0, }, /* 544 */ - { 23, 26, 12, 0, 0, 23, 0, }, /* 545 */ - { 10, 21, 12, 0, 0, -122, 0, }, /* 546 */ - { 10, 21, 12, 0, 0, -116, 0, }, /* 547 */ - { 23, 6, 12, 0, 0, 23, 0, }, /* 548 */ - { 10, 7, 12, 0, 0, 23, 0, }, /* 549 */ - { 23, 14, 12, 0, 0, 23, 0, }, /* 550 */ - { 10, 22, 12, 0, 0, -122, 0, }, /* 551 */ - { 10, 18, 12, 0, 0, -122, 0, }, /* 552 */ - { 10, 26, 12, 0, 0, -116, 0, }, /* 553 */ - { 10, 17, 12, 0, 0, -116, 0, }, /* 554 */ - { 10, 22, 12, 0, 0, -116, 0, }, /* 555 */ - { 10, 18, 12, 0, 0, -116, 0, }, /* 556 */ - { 28, 12, 3, 0, 0, -19, 0, }, /* 557 */ - { 24, 10, 3, 0, 0, 24, 0, }, /* 558 */ - { 10, 17, 14, 0, 0, -116, 0, }, /* 559 */ - { 10, 6, 12, 0, 0, -58, 0, }, /* 560 */ - { 10, 7, 12, 0, 0, -88, 0, }, /* 561 */ - { 10, 21, 14, 0, 0, -88, 0, }, /* 562 */ - { 10, 26, 12, 0, 0, 23, 0, }, /* 563 */ - { 27, 7, 12, 0, 0, 27, 0, }, /* 564 */ - { 28, 12, 3, 0, 0, -58, 0, }, /* 565 */ - { 10, 24, 12, 0, 0, -58, 0, }, /* 566 */ - { 27, 6, 12, 0, 0, 27, 0, }, /* 567 */ - { 10, 17, 12, 0, 0, -58, 0, }, /* 568 */ - { 30, 7, 12, 0, 0, 30, 0, }, /* 569 */ - { 30, 6, 12, 0, 0, 30, 0, }, /* 570 */ - { 4, 7, 12, 0, 0, 4, 0, }, /* 571 */ - { 24, 7, 12, 0, 0, 24, 0, }, /* 572 */ - { 10, 15, 12, 0, 0, 23, 0, }, /* 573 */ - { 24, 26, 12, 0, 0, 24, 0, }, /* 574 */ - { 10, 26, 14, 0, 0, 23, 0, }, /* 575 */ - { 30, 26, 12, 0, 0, 30, 0, }, /* 576 */ - { 23, 7, 12, 0, 0, 23, 0, }, /* 577 */ - { 61, 7, 12, 0, 0, 61, 0, }, /* 578 */ - { 61, 6, 12, 0, 0, 61, 0, }, /* 579 */ - { 61, 26, 12, 0, 0, 61, 0, }, /* 580 */ - { 86, 7, 12, 0, 0, 86, 0, }, /* 581 */ - { 86, 6, 12, 0, 0, 86, 0, }, /* 582 */ - { 86, 21, 12, 0, 0, 86, 0, }, /* 583 */ - { 77, 7, 12, 0, 0, 77, 0, }, /* 584 */ - { 77, 6, 12, 0, 0, 77, 0, }, /* 585 */ - { 77, 21, 12, 0, 0, 77, 0, }, /* 586 */ - { 77, 13, 12, 0, 0, 77, 0, }, /* 587 */ - { 13, 9, 12, 108, 1, 13, 0, }, /* 588 */ - { 13, 5, 12, 108, -35267, 13, 0, }, /* 589 */ - { 13, 7, 12, 0, 0, 13, 0, }, /* 590 */ - { 13, 21, 12, 0, 0, 13, 0, }, /* 591 */ - { 79, 7, 12, 0, 0, 79, 0, }, /* 592 */ - { 79, 14, 12, 0, 0, 79, 0, }, /* 593 */ - { 79, 12, 3, 0, 0, 79, 0, }, /* 594 */ - { 79, 21, 12, 0, 0, 79, 0, }, /* 595 */ - { 34, 9, 12, 0, -35332, 34, 0, }, /* 596 */ - { 34, 9, 12, 0, -42280, 34, 0, }, /* 597 */ - { 34, 9, 12, 0, -42308, 34, 0, }, /* 598 */ - { 34, 9, 12, 0, -42319, 34, 0, }, /* 599 */ - { 34, 9, 12, 0, -42315, 34, 0, }, /* 600 */ - { 34, 9, 12, 0, -42305, 34, 0, }, /* 601 */ - { 34, 9, 12, 0, -42258, 34, 0, }, /* 602 */ - { 34, 9, 12, 0, -42282, 34, 0, }, /* 603 */ - { 34, 9, 12, 0, -42261, 34, 0, }, /* 604 */ - { 34, 9, 12, 0, 928, 34, 0, }, /* 605 */ - { 49, 7, 12, 0, 0, 49, 0, }, /* 606 */ - { 49, 12, 3, 0, 0, 49, 0, }, /* 607 */ - { 49, 10, 5, 0, 0, 49, 0, }, /* 608 */ - { 49, 26, 12, 0, 0, 49, 0, }, /* 609 */ - { 10, 15, 12, 0, 0, -197, 0, }, /* 610 */ - { 10, 15, 12, 0, 0, -170, 0, }, /* 611 */ - { 10, 26, 12, 0, 0, -145, 0, }, /* 612 */ - { 10, 23, 12, 0, 0, -145, 0, }, /* 613 */ - { 65, 7, 12, 0, 0, 65, 0, }, /* 614 */ - { 65, 21, 12, 0, 0, 65, 0, }, /* 615 */ - { 75, 10, 5, 0, 0, 75, 0, }, /* 616 */ - { 75, 7, 12, 0, 0, 75, 0, }, /* 617 */ - { 75, 12, 3, 0, 0, 75, 0, }, /* 618 */ - { 75, 21, 12, 0, 0, 75, 0, }, /* 619 */ - { 75, 13, 12, 0, 0, 75, 0, }, /* 620 */ - { 15, 12, 3, 0, 0, -16, 0, }, /* 621 */ - { 15, 7, 12, 0, 0, -43, 0, }, /* 622 */ - { 69, 13, 12, 0, 0, 69, 0, }, /* 623 */ - { 69, 7, 12, 0, 0, 69, 0, }, /* 624 */ - { 69, 12, 3, 0, 0, 69, 0, }, /* 625 */ - { 10, 21, 12, 0, 0, -92, 0, }, /* 626 */ - { 69, 21, 12, 0, 0, 69, 0, }, /* 627 */ - { 74, 7, 12, 0, 0, 74, 0, }, /* 628 */ - { 74, 12, 3, 0, 0, 74, 0, }, /* 629 */ - { 74, 10, 5, 0, 0, 74, 0, }, /* 630 */ - { 74, 21, 12, 0, 0, 74, 0, }, /* 631 */ - { 84, 12, 3, 0, 0, 84, 0, }, /* 632 */ - { 84, 10, 5, 0, 0, 84, 0, }, /* 633 */ - { 84, 7, 12, 0, 0, 84, 0, }, /* 634 */ - { 84, 21, 12, 0, 0, 84, 0, }, /* 635 */ - { 10, 6, 12, 0, 0, -22, 0, }, /* 636 */ - { 84, 13, 12, 0, 0, 84, 0, }, /* 637 */ - { 39, 6, 12, 0, 0, 39, 0, }, /* 638 */ - { 68, 7, 12, 0, 0, 68, 0, }, /* 639 */ - { 68, 12, 3, 0, 0, 68, 0, }, /* 640 */ - { 68, 10, 5, 0, 0, 68, 0, }, /* 641 */ - { 68, 13, 12, 0, 0, 68, 0, }, /* 642 */ - { 68, 21, 12, 0, 0, 68, 0, }, /* 643 */ - { 92, 7, 12, 0, 0, 92, 0, }, /* 644 */ - { 92, 12, 3, 0, 0, 92, 0, }, /* 645 */ - { 92, 6, 12, 0, 0, 92, 0, }, /* 646 */ - { 92, 21, 12, 0, 0, 92, 0, }, /* 647 */ - { 87, 7, 12, 0, 0, 87, 0, }, /* 648 */ - { 87, 10, 5, 0, 0, 87, 0, }, /* 649 */ - { 87, 12, 3, 0, 0, 87, 0, }, /* 650 */ - { 87, 21, 12, 0, 0, 87, 0, }, /* 651 */ - { 87, 6, 12, 0, 0, 87, 0, }, /* 652 */ - { 34, 5, 12, 0, -928, 34, 0, }, /* 653 */ - { 9, 5, 12, 0, -38864, 9, 0, }, /* 654 */ - { 87, 13, 12, 0, 0, 87, 0, }, /* 655 */ - { 24, 7, 9, 0, 0, 24, 0, }, /* 656 */ - { 24, 7, 10, 0, 0, 24, 0, }, /* 657 */ - { 0, 4, 2, 0, 0, 0, 0, }, /* 658 */ - { 0, 3, 12, 0, 0, 0, 0, }, /* 659 */ - { 26, 25, 12, 0, 0, 26, 0, }, /* 660 */ - { 1, 24, 12, 0, 0, 1, 0, }, /* 661 */ - { 1, 7, 12, 0, 0, -10, 0, }, /* 662 */ - { 1, 26, 12, 0, 0, -10, 0, }, /* 663 */ - { 10, 6, 3, 0, 0, -58, 0, }, /* 664 */ - { 36, 7, 12, 0, 0, 36, 0, }, /* 665 */ - { 10, 21, 12, 0, 0, -25, 0, }, /* 666 */ - { 10, 15, 12, 0, 0, -76, 0, }, /* 667 */ - { 10, 26, 12, 0, 0, -25, 0, }, /* 668 */ - { 20, 14, 12, 0, 0, 20, 0, }, /* 669 */ - { 20, 15, 12, 0, 0, 20, 0, }, /* 670 */ - { 20, 26, 12, 0, 0, 20, 0, }, /* 671 */ - { 71, 7, 12, 0, 0, 71, 0, }, /* 672 */ - { 67, 7, 12, 0, 0, 67, 0, }, /* 673 */ - { 28, 12, 3, 0, 0, -1, 0, }, /* 674 */ - { 10, 15, 12, 0, 0, -1, 0, }, /* 675 */ - { 42, 7, 12, 0, 0, 42, 0, }, /* 676 */ - { 42, 15, 12, 0, 0, 42, 0, }, /* 677 */ - { 19, 7, 12, 0, 0, 19, 0, }, /* 678 */ - { 19, 14, 12, 0, 0, 19, 0, }, /* 679 */ - { 118, 7, 12, 0, 0, 118, 0, }, /* 680 */ - { 118, 12, 3, 0, 0, 118, 0, }, /* 681 */ - { 60, 7, 12, 0, 0, 60, 0, }, /* 682 */ - { 60, 21, 12, 0, 0, 60, 0, }, /* 683 */ - { 43, 7, 12, 0, 0, 43, 0, }, /* 684 */ - { 43, 21, 12, 0, 0, 43, 0, }, /* 685 */ - { 43, 14, 12, 0, 0, 43, 0, }, /* 686 */ - { 14, 9, 12, 0, 40, 14, 0, }, /* 687 */ - { 14, 5, 12, 0, -40, 14, 0, }, /* 688 */ - { 47, 7, 12, 0, 0, 47, 0, }, /* 689 */ - { 45, 7, 12, 0, 0, 45, 0, }, /* 690 */ - { 45, 13, 12, 0, 0, 45, 0, }, /* 691 */ - { 136, 9, 12, 0, 40, 136, 0, }, /* 692 */ - { 136, 5, 12, 0, -40, 136, 0, }, /* 693 */ - { 106, 7, 12, 0, 0, 106, 0, }, /* 694 */ - { 104, 7, 12, 0, 0, 104, 0, }, /* 695 */ - { 104, 21, 12, 0, 0, 104, 0, }, /* 696 */ - { 110, 7, 12, 0, 0, 110, 0, }, /* 697 */ - { 12, 7, 12, 0, 0, 12, 0, }, /* 698 */ - { 81, 7, 12, 0, 0, 81, 0, }, /* 699 */ - { 81, 21, 12, 0, 0, 81, 0, }, /* 700 */ - { 81, 15, 12, 0, 0, 81, 0, }, /* 701 */ - { 120, 7, 12, 0, 0, 120, 0, }, /* 702 */ - { 120, 26, 12, 0, 0, 120, 0, }, /* 703 */ - { 120, 15, 12, 0, 0, 120, 0, }, /* 704 */ - { 116, 7, 12, 0, 0, 116, 0, }, /* 705 */ - { 116, 15, 12, 0, 0, 116, 0, }, /* 706 */ - { 128, 7, 12, 0, 0, 128, 0, }, /* 707 */ - { 128, 15, 12, 0, 0, 128, 0, }, /* 708 */ - { 66, 7, 12, 0, 0, 66, 0, }, /* 709 */ - { 66, 15, 12, 0, 0, 66, 0, }, /* 710 */ - { 66, 21, 12, 0, 0, 66, 0, }, /* 711 */ - { 72, 7, 12, 0, 0, 72, 0, }, /* 712 */ - { 72, 21, 12, 0, 0, 72, 0, }, /* 713 */ - { 98, 7, 12, 0, 0, 98, 0, }, /* 714 */ - { 97, 7, 12, 0, 0, 97, 0, }, /* 715 */ - { 97, 15, 12, 0, 0, 97, 0, }, /* 716 */ - { 31, 7, 12, 0, 0, 31, 0, }, /* 717 */ - { 31, 12, 3, 0, 0, 31, 0, }, /* 718 */ - { 31, 15, 12, 0, 0, 31, 0, }, /* 719 */ - { 31, 21, 12, 0, 0, 31, 0, }, /* 720 */ - { 88, 7, 12, 0, 0, 88, 0, }, /* 721 */ - { 88, 15, 12, 0, 0, 88, 0, }, /* 722 */ - { 88, 21, 12, 0, 0, 88, 0, }, /* 723 */ - { 117, 7, 12, 0, 0, 117, 0, }, /* 724 */ - { 117, 15, 12, 0, 0, 117, 0, }, /* 725 */ - { 112, 7, 12, 0, 0, 112, 0, }, /* 726 */ - { 112, 26, 12, 0, 0, 112, 0, }, /* 727 */ - { 112, 12, 3, 0, 0, 112, 0, }, /* 728 */ - { 112, 15, 12, 0, 0, 112, 0, }, /* 729 */ - { 112, 21, 12, 0, 0, 112, 0, }, /* 730 */ - { 78, 7, 12, 0, 0, 78, 0, }, /* 731 */ - { 78, 21, 12, 0, 0, 78, 0, }, /* 732 */ - { 83, 7, 12, 0, 0, 83, 0, }, /* 733 */ - { 83, 15, 12, 0, 0, 83, 0, }, /* 734 */ - { 82, 7, 12, 0, 0, 82, 0, }, /* 735 */ - { 82, 15, 12, 0, 0, 82, 0, }, /* 736 */ - { 121, 7, 12, 0, 0, 121, 0, }, /* 737 */ - { 121, 21, 12, 0, 0, 121, 0, }, /* 738 */ - { 121, 15, 12, 0, 0, 121, 0, }, /* 739 */ - { 89, 7, 12, 0, 0, 89, 0, }, /* 740 */ - { 130, 9, 12, 0, 64, 130, 0, }, /* 741 */ - { 130, 5, 12, 0, -64, 130, 0, }, /* 742 */ - { 130, 15, 12, 0, 0, 130, 0, }, /* 743 */ - { 144, 7, 12, 0, 0, 144, 0, }, /* 744 */ - { 144, 12, 3, 0, 0, 144, 0, }, /* 745 */ - { 144, 13, 12, 0, 0, 144, 0, }, /* 746 */ - { 1, 15, 12, 0, 0, 1, 0, }, /* 747 */ - { 147, 7, 12, 0, 0, 147, 0, }, /* 748 */ - { 147, 15, 12, 0, 0, 147, 0, }, /* 749 */ - { 148, 7, 12, 0, 0, 148, 0, }, /* 750 */ - { 148, 12, 3, 0, 0, 148, 0, }, /* 751 */ - { 148, 15, 12, 0, 0, 148, 0, }, /* 752 */ - { 148, 21, 12, 0, 0, 148, 0, }, /* 753 */ - { 94, 10, 5, 0, 0, 94, 0, }, /* 754 */ - { 94, 12, 3, 0, 0, 94, 0, }, /* 755 */ - { 94, 7, 12, 0, 0, 94, 0, }, /* 756 */ - { 94, 21, 12, 0, 0, 94, 0, }, /* 757 */ - { 94, 15, 12, 0, 0, 94, 0, }, /* 758 */ - { 94, 13, 12, 0, 0, 94, 0, }, /* 759 */ - { 85, 12, 3, 0, 0, 85, 0, }, /* 760 */ - { 85, 10, 5, 0, 0, 85, 0, }, /* 761 */ - { 85, 7, 12, 0, 0, 85, 0, }, /* 762 */ - { 85, 21, 12, 0, 0, 85, 0, }, /* 763 */ - { 85, 1, 4, 0, 0, 85, 0, }, /* 764 */ - { 101, 7, 12, 0, 0, 101, 0, }, /* 765 */ - { 101, 13, 12, 0, 0, 101, 0, }, /* 766 */ - { 96, 12, 3, 0, 0, 96, 0, }, /* 767 */ - { 96, 7, 12, 0, 0, 96, 0, }, /* 768 */ - { 96, 10, 5, 0, 0, 96, 0, }, /* 769 */ - { 96, 13, 12, 0, 0, 96, 0, }, /* 770 */ - { 96, 21, 12, 0, 0, 96, 0, }, /* 771 */ - { 111, 7, 12, 0, 0, 111, 0, }, /* 772 */ - { 111, 12, 3, 0, 0, 111, 0, }, /* 773 */ - { 111, 21, 12, 0, 0, 111, 0, }, /* 774 */ - { 100, 12, 3, 0, 0, 100, 0, }, /* 775 */ - { 100, 10, 5, 0, 0, 100, 0, }, /* 776 */ - { 100, 7, 12, 0, 0, 100, 0, }, /* 777 */ - { 100, 7, 4, 0, 0, 100, 0, }, /* 778 */ - { 100, 21, 12, 0, 0, 100, 0, }, /* 779 */ - { 100, 13, 12, 0, 0, 100, 0, }, /* 780 */ - { 48, 15, 12, 0, 0, 48, 0, }, /* 781 */ - { 108, 7, 12, 0, 0, 108, 0, }, /* 782 */ - { 108, 10, 5, 0, 0, 108, 0, }, /* 783 */ - { 108, 12, 3, 0, 0, 108, 0, }, /* 784 */ - { 108, 21, 12, 0, 0, 108, 0, }, /* 785 */ - { 129, 7, 12, 0, 0, 129, 0, }, /* 786 */ - { 129, 21, 12, 0, 0, 129, 0, }, /* 787 */ - { 109, 7, 12, 0, 0, 109, 0, }, /* 788 */ - { 109, 12, 3, 0, 0, 109, 0, }, /* 789 */ - { 109, 10, 5, 0, 0, 109, 0, }, /* 790 */ - { 109, 13, 12, 0, 0, 109, 0, }, /* 791 */ - { 107, 12, 3, 0, 0, 107, 0, }, /* 792 */ - { 107, 12, 3, 0, 0, -49, 0, }, /* 793 */ - { 107, 10, 5, 0, 0, 107, 0, }, /* 794 */ - { 107, 10, 5, 0, 0, -49, 0, }, /* 795 */ - { 107, 7, 12, 0, 0, 107, 0, }, /* 796 */ - { 28, 12, 3, 0, 0, -49, 0, }, /* 797 */ - { 107, 10, 3, 0, 0, 107, 0, }, /* 798 */ - { 135, 7, 12, 0, 0, 135, 0, }, /* 799 */ - { 135, 10, 5, 0, 0, 135, 0, }, /* 800 */ - { 135, 12, 3, 0, 0, 135, 0, }, /* 801 */ - { 135, 21, 12, 0, 0, 135, 0, }, /* 802 */ - { 135, 13, 12, 0, 0, 135, 0, }, /* 803 */ - { 124, 7, 12, 0, 0, 124, 0, }, /* 804 */ - { 124, 10, 3, 0, 0, 124, 0, }, /* 805 */ - { 124, 10, 5, 0, 0, 124, 0, }, /* 806 */ - { 124, 12, 3, 0, 0, 124, 0, }, /* 807 */ - { 124, 21, 12, 0, 0, 124, 0, }, /* 808 */ - { 124, 13, 12, 0, 0, 124, 0, }, /* 809 */ - { 123, 7, 12, 0, 0, 123, 0, }, /* 810 */ - { 123, 10, 3, 0, 0, 123, 0, }, /* 811 */ - { 123, 10, 5, 0, 0, 123, 0, }, /* 812 */ - { 123, 12, 3, 0, 0, 123, 0, }, /* 813 */ - { 123, 21, 12, 0, 0, 123, 0, }, /* 814 */ - { 114, 7, 12, 0, 0, 114, 0, }, /* 815 */ - { 114, 10, 5, 0, 0, 114, 0, }, /* 816 */ - { 114, 12, 3, 0, 0, 114, 0, }, /* 817 */ - { 114, 21, 12, 0, 0, 114, 0, }, /* 818 */ - { 114, 13, 12, 0, 0, 114, 0, }, /* 819 */ - { 102, 7, 12, 0, 0, 102, 0, }, /* 820 */ - { 102, 12, 3, 0, 0, 102, 0, }, /* 821 */ - { 102, 10, 5, 0, 0, 102, 0, }, /* 822 */ - { 102, 13, 12, 0, 0, 102, 0, }, /* 823 */ - { 126, 7, 12, 0, 0, 126, 0, }, /* 824 */ - { 126, 12, 3, 0, 0, 126, 0, }, /* 825 */ - { 126, 10, 5, 0, 0, 126, 0, }, /* 826 */ - { 126, 13, 12, 0, 0, 126, 0, }, /* 827 */ - { 126, 15, 12, 0, 0, 126, 0, }, /* 828 */ - { 126, 21, 12, 0, 0, 126, 0, }, /* 829 */ - { 126, 26, 12, 0, 0, 126, 0, }, /* 830 */ - { 142, 7, 12, 0, 0, 142, 0, }, /* 831 */ - { 142, 10, 5, 0, 0, 142, 0, }, /* 832 */ - { 142, 12, 3, 0, 0, 142, 0, }, /* 833 */ - { 142, 21, 12, 0, 0, 142, 0, }, /* 834 */ - { 125, 9, 12, 0, 32, 125, 0, }, /* 835 */ - { 125, 5, 12, 0, -32, 125, 0, }, /* 836 */ - { 125, 13, 12, 0, 0, 125, 0, }, /* 837 */ - { 125, 15, 12, 0, 0, 125, 0, }, /* 838 */ - { 125, 7, 12, 0, 0, 125, 0, }, /* 839 */ - { 141, 7, 12, 0, 0, 141, 0, }, /* 840 */ - { 141, 12, 3, 0, 0, 141, 0, }, /* 841 */ - { 141, 10, 5, 0, 0, 141, 0, }, /* 842 */ - { 141, 7, 4, 0, 0, 141, 0, }, /* 843 */ - { 141, 21, 12, 0, 0, 141, 0, }, /* 844 */ - { 140, 7, 12, 0, 0, 140, 0, }, /* 845 */ - { 140, 12, 3, 0, 0, 140, 0, }, /* 846 */ - { 140, 10, 5, 0, 0, 140, 0, }, /* 847 */ - { 140, 7, 4, 0, 0, 140, 0, }, /* 848 */ - { 140, 21, 12, 0, 0, 140, 0, }, /* 849 */ - { 122, 7, 12, 0, 0, 122, 0, }, /* 850 */ - { 133, 7, 12, 0, 0, 133, 0, }, /* 851 */ - { 133, 10, 5, 0, 0, 133, 0, }, /* 852 */ - { 133, 12, 3, 0, 0, 133, 0, }, /* 853 */ - { 133, 21, 12, 0, 0, 133, 0, }, /* 854 */ - { 133, 13, 12, 0, 0, 133, 0, }, /* 855 */ - { 133, 15, 12, 0, 0, 133, 0, }, /* 856 */ - { 134, 21, 12, 0, 0, 134, 0, }, /* 857 */ - { 134, 7, 12, 0, 0, 134, 0, }, /* 858 */ - { 134, 12, 3, 0, 0, 134, 0, }, /* 859 */ - { 134, 10, 5, 0, 0, 134, 0, }, /* 860 */ - { 138, 7, 12, 0, 0, 138, 0, }, /* 861 */ - { 138, 12, 3, 0, 0, 138, 0, }, /* 862 */ - { 138, 7, 4, 0, 0, 138, 0, }, /* 863 */ - { 138, 13, 12, 0, 0, 138, 0, }, /* 864 */ - { 143, 7, 12, 0, 0, 143, 0, }, /* 865 */ - { 143, 10, 5, 0, 0, 143, 0, }, /* 866 */ - { 143, 12, 3, 0, 0, 143, 0, }, /* 867 */ - { 143, 13, 12, 0, 0, 143, 0, }, /* 868 */ - { 145, 7, 12, 0, 0, 145, 0, }, /* 869 */ - { 145, 12, 3, 0, 0, 145, 0, }, /* 870 */ - { 145, 10, 5, 0, 0, 145, 0, }, /* 871 */ - { 145, 21, 12, 0, 0, 145, 0, }, /* 872 */ - { 63, 7, 12, 0, 0, 63, 0, }, /* 873 */ - { 63, 14, 12, 0, 0, 63, 0, }, /* 874 */ - { 63, 21, 12, 0, 0, 63, 0, }, /* 875 */ - { 80, 7, 12, 0, 0, 80, 0, }, /* 876 */ - { 127, 7, 12, 0, 0, 127, 0, }, /* 877 */ - { 115, 7, 12, 0, 0, 115, 0, }, /* 878 */ - { 115, 13, 12, 0, 0, 115, 0, }, /* 879 */ - { 115, 21, 12, 0, 0, 115, 0, }, /* 880 */ - { 103, 7, 12, 0, 0, 103, 0, }, /* 881 */ - { 103, 12, 3, 0, 0, 103, 0, }, /* 882 */ - { 103, 21, 12, 0, 0, 103, 0, }, /* 883 */ - { 119, 7, 12, 0, 0, 119, 0, }, /* 884 */ - { 119, 12, 3, 0, 0, 119, 0, }, /* 885 */ - { 119, 21, 12, 0, 0, 119, 0, }, /* 886 */ - { 119, 26, 12, 0, 0, 119, 0, }, /* 887 */ - { 119, 6, 12, 0, 0, 119, 0, }, /* 888 */ - { 119, 13, 12, 0, 0, 119, 0, }, /* 889 */ - { 119, 15, 12, 0, 0, 119, 0, }, /* 890 */ - { 146, 9, 12, 0, 32, 146, 0, }, /* 891 */ - { 146, 5, 12, 0, -32, 146, 0, }, /* 892 */ - { 146, 15, 12, 0, 0, 146, 0, }, /* 893 */ - { 146, 21, 12, 0, 0, 146, 0, }, /* 894 */ - { 99, 7, 12, 0, 0, 99, 0, }, /* 895 */ - { 99, 10, 5, 0, 0, 99, 0, }, /* 896 */ - { 99, 12, 3, 0, 0, 99, 0, }, /* 897 */ - { 99, 6, 12, 0, 0, 99, 0, }, /* 898 */ - { 137, 6, 12, 0, 0, 137, 0, }, /* 899 */ - { 139, 6, 12, 0, 0, 139, 0, }, /* 900 */ - { 137, 7, 12, 0, 0, 137, 0, }, /* 901 */ - { 139, 7, 12, 0, 0, 139, 0, }, /* 902 */ - { 105, 7, 12, 0, 0, 105, 0, }, /* 903 */ - { 105, 26, 12, 0, 0, 105, 0, }, /* 904 */ - { 105, 12, 3, 0, 0, 105, 0, }, /* 905 */ - { 105, 21, 12, 0, 0, 105, 0, }, /* 906 */ - { 10, 1, 2, 0, 0, 105, 0, }, /* 907 */ - { 10, 10, 3, 0, 0, 10, 0, }, /* 908 */ - { 10, 10, 5, 0, 0, 10, 0, }, /* 909 */ - { 20, 12, 3, 0, 0, 20, 0, }, /* 910 */ - { 131, 26, 12, 0, 0, 131, 0, }, /* 911 */ - { 131, 12, 3, 0, 0, 131, 0, }, /* 912 */ - { 131, 21, 12, 0, 0, 131, 0, }, /* 913 */ - { 18, 12, 3, 0, 0, 18, 0, }, /* 914 */ - { 113, 7, 12, 0, 0, 113, 0, }, /* 915 */ - { 113, 15, 12, 0, 0, 113, 0, }, /* 916 */ - { 113, 12, 3, 0, 0, 113, 0, }, /* 917 */ - { 132, 9, 12, 0, 34, 132, 0, }, /* 918 */ - { 132, 5, 12, 0, -34, 132, 0, }, /* 919 */ - { 132, 12, 3, 0, 0, 132, 0, }, /* 920 */ - { 132, 13, 12, 0, 0, 132, 0, }, /* 921 */ - { 132, 21, 12, 0, 0, 132, 0, }, /* 922 */ - { 0, 2, 14, 0, 0, 0, 0, }, /* 923 */ - { 10, 26, 11, 0, 0, 10, 0, }, /* 924 */ - { 27, 26, 12, 0, 0, 27, 0, }, /* 925 */ - { 10, 24, 3, 0, 0, 10, 0, }, /* 926 */ - { 10, 1, 3, 0, 0, 10, 0, }, /* 927 */ + { 34, 5, 12, 0, 42307, 34, 0, }, /* 102 */ + { 34, 5, 12, 0, 42282, 34, 0, }, /* 103 */ + { 34, 5, 12, 0, -69, 34, 0, }, /* 104 */ + { 34, 5, 12, 0, -217, 34, 0, }, /* 105 */ + { 34, 5, 12, 0, -71, 34, 0, }, /* 106 */ + { 34, 5, 12, 0, -219, 34, 0, }, /* 107 */ + { 34, 5, 12, 0, 42261, 34, 0, }, /* 108 */ + { 34, 5, 12, 0, 42258, 34, 0, }, /* 109 */ + { 34, 6, 12, 0, 0, 34, 0, }, /* 110 */ + { 10, 6, 12, 0, 0, 10, 0, }, /* 111 */ + { 4, 24, 12, 0, 0, 4, 0, }, /* 112 */ + { 28, 12, 3, 0, 0, 28, 0, }, /* 113 */ + { 28, 12, 3, 0, 0, 20, 0, }, /* 114 */ + { 28, 12, 3, 21, 116, 20, 0, }, /* 115 */ + { 28, 12, 3, 0, 0, 34, 0, }, /* 116 */ + { 20, 9, 12, 0, 1, 20, 0, }, /* 117 */ + { 20, 5, 12, 0, -1, 20, 0, }, /* 118 */ + { 20, 24, 12, 0, 0, 20, 0, }, /* 119 */ + { 0, 2, 12, 0, 0, 0, 0, }, /* 120 */ + { 20, 6, 12, 0, 0, 20, 0, }, /* 121 */ + { 20, 5, 12, 0, 130, 20, 0, }, /* 122 */ + { 20, 9, 12, 0, 116, 20, 0, }, /* 123 */ + { 20, 9, 12, 0, 38, 20, 0, }, /* 124 */ + { 20, 9, 12, 0, 37, 20, 0, }, /* 125 */ + { 20, 9, 12, 0, 64, 20, 0, }, /* 126 */ + { 20, 9, 12, 0, 63, 20, 0, }, /* 127 */ + { 20, 5, 12, 0, 0, 20, 0, }, /* 128 */ + { 20, 9, 12, 0, 32, 20, 0, }, /* 129 */ + { 20, 9, 12, 34, 32, 20, 0, }, /* 130 */ + { 20, 9, 12, 59, 32, 20, 0, }, /* 131 */ + { 20, 9, 12, 38, 32, 20, 0, }, /* 132 */ + { 20, 9, 12, 21, 32, 20, 0, }, /* 133 */ + { 20, 9, 12, 51, 32, 20, 0, }, /* 134 */ + { 20, 9, 12, 26, 32, 20, 0, }, /* 135 */ + { 20, 9, 12, 47, 32, 20, 0, }, /* 136 */ + { 20, 9, 12, 55, 32, 20, 0, }, /* 137 */ + { 20, 9, 12, 30, 32, 20, 0, }, /* 138 */ + { 20, 9, 12, 43, 32, 20, 0, }, /* 139 */ + { 20, 9, 12, 96, 32, 20, 0, }, /* 140 */ + { 20, 5, 12, 0, -38, 20, 0, }, /* 141 */ + { 20, 5, 12, 0, -37, 20, 0, }, /* 142 */ + { 20, 5, 12, 0, -32, 20, 0, }, /* 143 */ + { 20, 5, 12, 34, -32, 20, 0, }, /* 144 */ + { 20, 5, 12, 59, -32, 20, 0, }, /* 145 */ + { 20, 5, 12, 38, -32, 20, 0, }, /* 146 */ + { 20, 5, 12, 21, -116, 20, 0, }, /* 147 */ + { 20, 5, 12, 51, -32, 20, 0, }, /* 148 */ + { 20, 5, 12, 26, -775, 20, 0, }, /* 149 */ + { 20, 5, 12, 47, -32, 20, 0, }, /* 150 */ + { 20, 5, 12, 55, -32, 20, 0, }, /* 151 */ + { 20, 5, 12, 30, 1, 20, 0, }, /* 152 */ + { 20, 5, 12, 30, -32, 20, 0, }, /* 153 */ + { 20, 5, 12, 43, -32, 20, 0, }, /* 154 */ + { 20, 5, 12, 96, -32, 20, 0, }, /* 155 */ + { 20, 5, 12, 0, -64, 20, 0, }, /* 156 */ + { 20, 5, 12, 0, -63, 20, 0, }, /* 157 */ + { 20, 9, 12, 0, 8, 20, 0, }, /* 158 */ + { 20, 5, 12, 34, -30, 20, 0, }, /* 159 */ + { 20, 5, 12, 38, -25, 20, 0, }, /* 160 */ + { 20, 9, 12, 0, 0, 20, 0, }, /* 161 */ + { 20, 5, 12, 43, -15, 20, 0, }, /* 162 */ + { 20, 5, 12, 47, -22, 20, 0, }, /* 163 */ + { 20, 5, 12, 0, -8, 20, 0, }, /* 164 */ + { 11, 9, 12, 0, 1, 11, 0, }, /* 165 */ + { 11, 5, 12, 0, -1, 11, 0, }, /* 166 */ + { 20, 5, 12, 51, -54, 20, 0, }, /* 167 */ + { 20, 5, 12, 55, -48, 20, 0, }, /* 168 */ + { 20, 5, 12, 0, 7, 20, 0, }, /* 169 */ + { 20, 5, 12, 0, -116, 20, 0, }, /* 170 */ + { 20, 9, 12, 38, -60, 20, 0, }, /* 171 */ + { 20, 5, 12, 59, -64, 20, 0, }, /* 172 */ + { 20, 25, 12, 0, 0, 20, 0, }, /* 173 */ + { 20, 9, 12, 0, -7, 20, 0, }, /* 174 */ + { 20, 9, 12, 0, -130, 20, 0, }, /* 175 */ + { 13, 9, 12, 0, 80, 13, 0, }, /* 176 */ + { 13, 9, 12, 0, 32, 13, 0, }, /* 177 */ + { 13, 9, 12, 63, 32, 13, 0, }, /* 178 */ + { 13, 9, 12, 67, 32, 13, 0, }, /* 179 */ + { 13, 9, 12, 71, 32, 13, 0, }, /* 180 */ + { 13, 9, 12, 75, 32, 13, 0, }, /* 181 */ + { 13, 9, 12, 79, 32, 13, 0, }, /* 182 */ + { 13, 9, 12, 84, 32, 13, 0, }, /* 183 */ + { 13, 5, 12, 0, -32, 13, 0, }, /* 184 */ + { 13, 5, 12, 63, -32, 13, 0, }, /* 185 */ + { 13, 5, 12, 67, -32, 13, 0, }, /* 186 */ + { 13, 5, 12, 71, -32, 13, 0, }, /* 187 */ + { 13, 5, 12, 75, -32, 13, 0, }, /* 188 */ + { 13, 5, 12, 79, -32, 13, 0, }, /* 189 */ + { 13, 5, 12, 84, -32, 13, 0, }, /* 190 */ + { 13, 5, 12, 0, -80, 13, 0, }, /* 191 */ + { 13, 9, 12, 0, 1, 13, 0, }, /* 192 */ + { 13, 5, 12, 0, -1, 13, 0, }, /* 193 */ + { 13, 9, 12, 88, 1, 13, 0, }, /* 194 */ + { 13, 5, 12, 88, -1, 13, 0, }, /* 195 */ + { 13, 26, 12, 0, 0, 13, 0, }, /* 196 */ + { 13, 12, 3, 0, 0, -34, 0, }, /* 197 */ + { 13, 12, 3, 0, 0, -28, 0, }, /* 198 */ + { 28, 12, 3, 0, 0, -31, 0, }, /* 199 */ + { 13, 11, 3, 0, 0, 13, 0, }, /* 200 */ + { 13, 9, 12, 0, 15, 13, 0, }, /* 201 */ + { 13, 5, 12, 0, -15, 13, 0, }, /* 202 */ + { 2, 9, 12, 0, 48, 2, 0, }, /* 203 */ + { 2, 6, 12, 0, 0, 2, 0, }, /* 204 */ + { 2, 21, 12, 0, 0, 2, 0, }, /* 205 */ + { 2, 5, 12, 0, 0, 2, 0, }, /* 206 */ + { 2, 5, 12, 0, -48, 2, 0, }, /* 207 */ + { 10, 21, 12, 0, 0, -13, 0, }, /* 208 */ + { 2, 17, 12, 0, 0, 2, 0, }, /* 209 */ + { 2, 26, 12, 0, 0, 2, 0, }, /* 210 */ + { 2, 23, 12, 0, 0, 2, 0, }, /* 211 */ + { 26, 12, 3, 0, 0, 26, 0, }, /* 212 */ + { 26, 17, 12, 0, 0, 26, 0, }, /* 213 */ + { 26, 21, 12, 0, 0, 26, 0, }, /* 214 */ + { 26, 7, 12, 0, 0, 26, 0, }, /* 215 */ + { 1, 1, 4, 0, 0, 1, 0, }, /* 216 */ + { 10, 1, 4, 0, 0, 10, 0, }, /* 217 */ + { 1, 25, 12, 0, 0, 1, 0, }, /* 218 */ + { 1, 21, 12, 0, 0, 1, 0, }, /* 219 */ + { 1, 23, 12, 0, 0, 1, 0, }, /* 220 */ + { 10, 21, 12, 0, 0, -105, 0, }, /* 221 */ + { 1, 26, 12, 0, 0, 1, 0, }, /* 222 */ + { 1, 12, 3, 0, 0, 1, 0, }, /* 223 */ + { 1, 1, 2, 0, 0, -73, 0, }, /* 224 */ + { 1, 7, 12, 0, 0, 1, 0, }, /* 225 */ + { 10, 6, 12, 0, 0, -145, 0, }, /* 226 */ + { 28, 12, 3, 0, 0, -7, 0, }, /* 227 */ + { 1, 13, 12, 0, 0, -10, 0, }, /* 228 */ + { 1, 21, 12, 0, 0, -4, 0, }, /* 229 */ + { 1, 6, 12, 0, 0, 1, 0, }, /* 230 */ + { 1, 13, 12, 0, 0, 1, 0, }, /* 231 */ + { 50, 21, 12, 0, 0, 50, 0, }, /* 232 */ + { 50, 1, 4, 0, 0, 50, 0, }, /* 233 */ + { 50, 7, 12, 0, 0, 50, 0, }, /* 234 */ + { 50, 12, 3, 0, 0, 50, 0, }, /* 235 */ + { 56, 7, 12, 0, 0, 56, 0, }, /* 236 */ + { 56, 12, 3, 0, 0, 56, 0, }, /* 237 */ + { 64, 13, 12, 0, 0, 64, 0, }, /* 238 */ + { 64, 7, 12, 0, 0, 64, 0, }, /* 239 */ + { 64, 12, 3, 0, 0, 64, 0, }, /* 240 */ + { 64, 6, 12, 0, 0, 64, 0, }, /* 241 */ + { 64, 26, 12, 0, 0, 64, 0, }, /* 242 */ + { 64, 21, 12, 0, 0, 64, 0, }, /* 243 */ + { 64, 23, 12, 0, 0, 64, 0, }, /* 244 */ + { 90, 7, 12, 0, 0, 90, 0, }, /* 245 */ + { 90, 12, 3, 0, 0, 90, 0, }, /* 246 */ + { 90, 6, 12, 0, 0, 90, 0, }, /* 247 */ + { 90, 21, 12, 0, 0, 90, 0, }, /* 248 */ + { 95, 7, 12, 0, 0, 95, 0, }, /* 249 */ + { 95, 12, 3, 0, 0, 95, 0, }, /* 250 */ + { 95, 21, 12, 0, 0, 95, 0, }, /* 251 */ + { 15, 12, 3, 0, 0, 15, 0, }, /* 252 */ + { 15, 10, 5, 0, 0, 15, 0, }, /* 253 */ + { 15, 7, 12, 0, 0, 15, 0, }, /* 254 */ + { 28, 12, 3, 0, 0, -188, 0, }, /* 255 */ + { 28, 12, 3, 0, 0, -175, 0, }, /* 256 */ + { 10, 21, 12, 0, 0, -231, 0, }, /* 257 */ + { 10, 21, 12, 0, 0, -252, 0, }, /* 258 */ + { 15, 13, 12, 0, 0, -120, 0, }, /* 259 */ + { 15, 21, 12, 0, 0, 15, 0, }, /* 260 */ + { 15, 6, 12, 0, 0, 15, 0, }, /* 261 */ + { 3, 7, 12, 0, 0, 3, 0, }, /* 262 */ + { 3, 12, 3, 0, 0, 3, 0, }, /* 263 */ + { 3, 10, 5, 0, 0, 3, 0, }, /* 264 */ + { 3, 10, 3, 0, 0, 3, 0, }, /* 265 */ + { 3, 13, 12, 0, 0, -77, 0, }, /* 266 */ + { 3, 23, 12, 0, 0, 3, 0, }, /* 267 */ + { 3, 15, 12, 0, 0, 3, 0, }, /* 268 */ + { 3, 26, 12, 0, 0, 3, 0, }, /* 269 */ + { 3, 21, 12, 0, 0, 3, 0, }, /* 270 */ + { 22, 12, 3, 0, 0, 22, 0, }, /* 271 */ + { 22, 10, 5, 0, 0, 22, 0, }, /* 272 */ + { 22, 7, 12, 0, 0, 22, 0, }, /* 273 */ + { 22, 13, 12, 0, 0, -58, 0, }, /* 274 */ + { 22, 21, 12, 0, 0, 22, 0, }, /* 275 */ + { 21, 12, 3, 0, 0, 21, 0, }, /* 276 */ + { 21, 10, 5, 0, 0, 21, 0, }, /* 277 */ + { 21, 7, 12, 0, 0, 21, 0, }, /* 278 */ + { 21, 13, 12, 0, 0, -55, 0, }, /* 279 */ + { 21, 21, 12, 0, 0, 21, 0, }, /* 280 */ + { 21, 23, 12, 0, 0, 21, 0, }, /* 281 */ + { 44, 12, 3, 0, 0, 44, 0, }, /* 282 */ + { 44, 10, 5, 0, 0, 44, 0, }, /* 283 */ + { 44, 7, 12, 0, 0, 44, 0, }, /* 284 */ + { 44, 10, 3, 0, 0, 44, 0, }, /* 285 */ + { 44, 13, 12, 0, 0, 44, 0, }, /* 286 */ + { 44, 26, 12, 0, 0, 44, 0, }, /* 287 */ + { 44, 15, 12, 0, 0, 44, 0, }, /* 288 */ + { 54, 12, 3, 0, 0, 54, 0, }, /* 289 */ + { 54, 7, 12, 0, 0, 54, 0, }, /* 290 */ + { 54, 10, 3, 0, 0, 54, 0, }, /* 291 */ + { 54, 10, 5, 0, 0, 54, 0, }, /* 292 */ + { 54, 13, 12, 0, 0, -52, 0, }, /* 293 */ + { 54, 15, 12, 0, 0, -52, 0, }, /* 294 */ + { 54, 26, 12, 0, 0, -52, 0, }, /* 295 */ + { 54, 26, 12, 0, 0, 54, 0, }, /* 296 */ + { 54, 23, 12, 0, 0, 54, 0, }, /* 297 */ + { 55, 12, 3, 0, 0, 55, 0, }, /* 298 */ + { 55, 10, 5, 0, 0, 55, 0, }, /* 299 */ + { 55, 7, 12, 0, 0, 55, 0, }, /* 300 */ + { 55, 13, 12, 0, 0, 55, 0, }, /* 301 */ + { 55, 21, 12, 0, 0, 55, 0, }, /* 302 */ + { 55, 15, 12, 0, 0, 55, 0, }, /* 303 */ + { 55, 26, 12, 0, 0, 55, 0, }, /* 304 */ + { 29, 7, 12, 0, 0, 29, 0, }, /* 305 */ + { 29, 12, 3, 0, 0, 29, 0, }, /* 306 */ + { 29, 10, 5, 0, 0, 29, 0, }, /* 307 */ + { 29, 21, 12, 0, 0, 29, 0, }, /* 308 */ + { 29, 10, 3, 0, 0, 29, 0, }, /* 309 */ + { 29, 13, 12, 0, 0, -64, 0, }, /* 310 */ + { 37, 12, 3, 0, 0, 37, 0, }, /* 311 */ + { 37, 10, 5, 0, 0, 37, 0, }, /* 312 */ + { 37, 7, 12, 0, 0, 37, 0, }, /* 313 */ + { 37, 10, 3, 0, 0, 37, 0, }, /* 314 */ + { 37, 7, 4, 0, 0, 37, 0, }, /* 315 */ + { 37, 26, 12, 0, 0, 37, 0, }, /* 316 */ + { 37, 15, 12, 0, 0, 37, 0, }, /* 317 */ + { 37, 13, 12, 0, 0, 37, 0, }, /* 318 */ + { 48, 10, 5, 0, 0, 48, 0, }, /* 319 */ + { 48, 7, 12, 0, 0, 48, 0, }, /* 320 */ + { 48, 12, 3, 0, 0, 48, 0, }, /* 321 */ + { 48, 10, 3, 0, 0, 48, 0, }, /* 322 */ + { 48, 13, 12, 0, 0, 48, 0, }, /* 323 */ + { 48, 21, 12, 0, 0, 48, 0, }, /* 324 */ + { 57, 7, 12, 0, 0, 57, 0, }, /* 325 */ + { 57, 12, 3, 0, 0, 57, 0, }, /* 326 */ + { 57, 7, 5, 0, 0, 57, 0, }, /* 327 */ + { 57, 6, 12, 0, 0, 57, 0, }, /* 328 */ + { 57, 21, 12, 0, 0, 57, 0, }, /* 329 */ + { 57, 13, 12, 0, 0, 57, 0, }, /* 330 */ + { 33, 7, 12, 0, 0, 33, 0, }, /* 331 */ + { 33, 12, 3, 0, 0, 33, 0, }, /* 332 */ + { 33, 7, 5, 0, 0, 33, 0, }, /* 333 */ + { 33, 6, 12, 0, 0, 33, 0, }, /* 334 */ + { 33, 13, 12, 0, 0, 33, 0, }, /* 335 */ + { 58, 7, 12, 0, 0, 58, 0, }, /* 336 */ + { 58, 26, 12, 0, 0, 58, 0, }, /* 337 */ + { 58, 21, 12, 0, 0, 58, 0, }, /* 338 */ + { 58, 12, 3, 0, 0, 58, 0, }, /* 339 */ + { 58, 13, 12, 0, 0, 58, 0, }, /* 340 */ + { 58, 15, 12, 0, 0, 58, 0, }, /* 341 */ + { 58, 22, 12, 0, 0, 58, 0, }, /* 342 */ + { 58, 18, 12, 0, 0, 58, 0, }, /* 343 */ + { 58, 10, 5, 0, 0, 58, 0, }, /* 344 */ + { 39, 7, 12, 0, 0, 39, 0, }, /* 345 */ + { 39, 10, 12, 0, 0, 39, 0, }, /* 346 */ + { 39, 12, 3, 0, 0, 39, 0, }, /* 347 */ + { 39, 10, 5, 0, 0, 39, 0, }, /* 348 */ + { 39, 13, 12, 0, 0, -81, 0, }, /* 349 */ + { 39, 21, 12, 0, 0, 39, 0, }, /* 350 */ + { 39, 13, 12, 0, 0, 39, 0, }, /* 351 */ + { 39, 26, 12, 0, 0, 39, 0, }, /* 352 */ + { 17, 9, 12, 0, 7264, 17, 0, }, /* 353 */ + { 17, 5, 12, 0, 3008, 17, 0, }, /* 354 */ + { 10, 21, 12, 0, 0, -49, 0, }, /* 355 */ + { 17, 6, 12, 0, 0, 17, 0, }, /* 356 */ + { 24, 7, 6, 0, 0, 24, 0, }, /* 357 */ + { 24, 7, 7, 0, 0, 24, 0, }, /* 358 */ + { 24, 7, 8, 0, 0, 24, 0, }, /* 359 */ + { 16, 7, 12, 0, 0, 16, 0, }, /* 360 */ + { 16, 12, 3, 0, 0, 16, 0, }, /* 361 */ + { 16, 21, 12, 0, 0, 16, 0, }, /* 362 */ + { 16, 15, 12, 0, 0, 16, 0, }, /* 363 */ + { 16, 26, 12, 0, 0, 16, 0, }, /* 364 */ + { 9, 9, 12, 0, 38864, 9, 0, }, /* 365 */ + { 9, 9, 12, 0, 8, 9, 0, }, /* 366 */ + { 9, 5, 12, 0, -8, 9, 0, }, /* 367 */ + { 8, 17, 12, 0, 0, 8, 0, }, /* 368 */ + { 8, 7, 12, 0, 0, 8, 0, }, /* 369 */ + { 8, 26, 12, 0, 0, 8, 0, }, /* 370 */ + { 8, 21, 12, 0, 0, 8, 0, }, /* 371 */ + { 41, 29, 12, 0, 0, 41, 0, }, /* 372 */ + { 41, 7, 12, 0, 0, 41, 0, }, /* 373 */ + { 41, 22, 12, 0, 0, 41, 0, }, /* 374 */ + { 41, 18, 12, 0, 0, 41, 0, }, /* 375 */ + { 46, 7, 12, 0, 0, 46, 0, }, /* 376 */ + { 46, 14, 12, 0, 0, 46, 0, }, /* 377 */ + { 51, 7, 12, 0, 0, 51, 0, }, /* 378 */ + { 51, 12, 3, 0, 0, 51, 0, }, /* 379 */ + { 25, 7, 12, 0, 0, 25, 0, }, /* 380 */ + { 25, 12, 3, 0, 0, 25, 0, }, /* 381 */ + { 10, 21, 12, 0, 0, -115, 0, }, /* 382 */ + { 7, 7, 12, 0, 0, 7, 0, }, /* 383 */ + { 7, 12, 3, 0, 0, 7, 0, }, /* 384 */ + { 52, 7, 12, 0, 0, 52, 0, }, /* 385 */ + { 52, 12, 3, 0, 0, 52, 0, }, /* 386 */ + { 32, 7, 12, 0, 0, 32, 0, }, /* 387 */ + { 32, 12, 3, 0, 0, 32, 0, }, /* 388 */ + { 32, 10, 5, 0, 0, 32, 0, }, /* 389 */ + { 32, 21, 12, 0, 0, 32, 0, }, /* 390 */ + { 32, 6, 12, 0, 0, 32, 0, }, /* 391 */ + { 32, 23, 12, 0, 0, 32, 0, }, /* 392 */ + { 32, 13, 12, 0, 0, 32, 0, }, /* 393 */ + { 32, 15, 12, 0, 0, 32, 0, }, /* 394 */ + { 38, 21, 12, 0, 0, 38, 0, }, /* 395 */ + { 10, 21, 12, 0, 0, -70, 0, }, /* 396 */ + { 38, 17, 12, 0, 0, 38, 0, }, /* 397 */ + { 38, 12, 3, 0, 0, 38, 0, }, /* 398 */ + { 38, 1, 2, 0, 0, 38, 0, }, /* 399 */ + { 38, 13, 12, 0, 0, 38, 0, }, /* 400 */ + { 38, 7, 12, 0, 0, 38, 0, }, /* 401 */ + { 38, 6, 12, 0, 0, 38, 0, }, /* 402 */ + { 35, 7, 12, 0, 0, 35, 0, }, /* 403 */ + { 35, 12, 3, 0, 0, 35, 0, }, /* 404 */ + { 35, 10, 5, 0, 0, 35, 0, }, /* 405 */ + { 35, 26, 12, 0, 0, 35, 0, }, /* 406 */ + { 35, 21, 12, 0, 0, 35, 0, }, /* 407 */ + { 35, 13, 12, 0, 0, 35, 0, }, /* 408 */ + { 53, 7, 12, 0, 0, 53, 0, }, /* 409 */ + { 40, 7, 12, 0, 0, 40, 0, }, /* 410 */ + { 40, 13, 12, 0, 0, 40, 0, }, /* 411 */ + { 40, 15, 12, 0, 0, 40, 0, }, /* 412 */ + { 40, 26, 12, 0, 0, 40, 0, }, /* 413 */ + { 32, 26, 12, 0, 0, 32, 0, }, /* 414 */ + { 6, 7, 12, 0, 0, 6, 0, }, /* 415 */ + { 6, 12, 3, 0, 0, 6, 0, }, /* 416 */ + { 6, 10, 5, 0, 0, 6, 0, }, /* 417 */ + { 6, 21, 12, 0, 0, 6, 0, }, /* 418 */ + { 91, 7, 12, 0, 0, 91, 0, }, /* 419 */ + { 91, 10, 5, 0, 0, 91, 0, }, /* 420 */ + { 91, 12, 3, 0, 0, 91, 0, }, /* 421 */ + { 91, 10, 12, 0, 0, 91, 0, }, /* 422 */ + { 91, 13, 12, 0, 0, 91, 0, }, /* 423 */ + { 91, 21, 12, 0, 0, 91, 0, }, /* 424 */ + { 91, 6, 12, 0, 0, 91, 0, }, /* 425 */ + { 28, 11, 3, 0, 0, 28, 0, }, /* 426 */ + { 62, 12, 3, 0, 0, 62, 0, }, /* 427 */ + { 62, 10, 5, 0, 0, 62, 0, }, /* 428 */ + { 62, 7, 12, 0, 0, 62, 0, }, /* 429 */ + { 62, 10, 3, 0, 0, 62, 0, }, /* 430 */ + { 62, 13, 12, 0, 0, 62, 0, }, /* 431 */ + { 62, 21, 12, 0, 0, 62, 0, }, /* 432 */ + { 62, 26, 12, 0, 0, 62, 0, }, /* 433 */ + { 76, 12, 3, 0, 0, 76, 0, }, /* 434 */ + { 76, 10, 5, 0, 0, 76, 0, }, /* 435 */ + { 76, 7, 12, 0, 0, 76, 0, }, /* 436 */ + { 76, 13, 12, 0, 0, 76, 0, }, /* 437 */ + { 93, 7, 12, 0, 0, 93, 0, }, /* 438 */ + { 93, 12, 3, 0, 0, 93, 0, }, /* 439 */ + { 93, 10, 5, 0, 0, 93, 0, }, /* 440 */ + { 93, 21, 12, 0, 0, 93, 0, }, /* 441 */ + { 70, 7, 12, 0, 0, 70, 0, }, /* 442 */ + { 70, 10, 5, 0, 0, 70, 0, }, /* 443 */ + { 70, 12, 3, 0, 0, 70, 0, }, /* 444 */ + { 70, 21, 12, 0, 0, 70, 0, }, /* 445 */ + { 70, 13, 12, 0, 0, 70, 0, }, /* 446 */ + { 73, 13, 12, 0, 0, 73, 0, }, /* 447 */ + { 73, 7, 12, 0, 0, 73, 0, }, /* 448 */ + { 73, 6, 12, 0, 0, 73, 0, }, /* 449 */ + { 73, 21, 12, 0, 0, 73, 0, }, /* 450 */ + { 13, 5, 12, 63, -6222, 13, 0, }, /* 451 */ + { 13, 5, 12, 67, -6221, 13, 0, }, /* 452 */ + { 13, 5, 12, 71, -6212, 13, 0, }, /* 453 */ + { 13, 5, 12, 75, -6210, 13, 0, }, /* 454 */ + { 13, 5, 12, 79, -6210, 13, 0, }, /* 455 */ + { 13, 5, 12, 79, -6211, 13, 0, }, /* 456 */ + { 13, 5, 12, 84, -6204, 13, 0, }, /* 457 */ + { 13, 5, 12, 88, -6180, 13, 0, }, /* 458 */ + { 13, 5, 12, 108, 35267, 13, 0, }, /* 459 */ + { 17, 9, 12, 0, -3008, 17, 0, }, /* 460 */ + { 76, 21, 12, 0, 0, 76, 0, }, /* 461 */ + { 28, 12, 3, 0, 0, -110, 0, }, /* 462 */ + { 28, 12, 3, 0, 0, 15, 0, }, /* 463 */ + { 10, 21, 12, 0, 0, -37, 0, }, /* 464 */ + { 28, 12, 3, 0, 0, -16, 0, }, /* 465 */ + { 28, 12, 3, 0, 0, -43, 0, }, /* 466 */ + { 28, 12, 3, 0, 0, -138, 0, }, /* 467 */ + { 10, 10, 5, 0, 0, -16, 0, }, /* 468 */ + { 10, 7, 12, 0, 0, -40, 0, }, /* 469 */ + { 10, 7, 12, 0, 0, -16, 0, }, /* 470 */ + { 10, 7, 12, 0, 0, 15, 0, }, /* 471 */ + { 10, 7, 12, 0, 0, -154, 0, }, /* 472 */ + { 10, 7, 12, 0, 0, -37, 0, }, /* 473 */ + { 28, 12, 3, 0, 0, -89, 0, }, /* 474 */ + { 10, 10, 5, 0, 0, 3, 0, }, /* 475 */ + { 28, 12, 3, 0, 0, -37, 0, }, /* 476 */ + { 10, 7, 12, 0, 0, 150, 0, }, /* 477 */ + { 13, 5, 12, 0, 0, 13, 0, }, /* 478 */ + { 13, 6, 12, 0, 0, 13, 0, }, /* 479 */ + { 34, 5, 12, 0, 35332, 34, 0, }, /* 480 */ + { 34, 5, 12, 0, 3814, 34, 0, }, /* 481 */ + { 34, 5, 12, 0, 35384, 34, 0, }, /* 482 */ + { 34, 9, 12, 92, 1, 34, 0, }, /* 483 */ + { 34, 5, 12, 92, -1, 34, 0, }, /* 484 */ + { 34, 5, 12, 92, -58, 34, 0, }, /* 485 */ + { 34, 9, 12, 0, -7615, 34, 0, }, /* 486 */ + { 20, 5, 12, 0, 8, 20, 0, }, /* 487 */ + { 20, 9, 12, 0, -8, 20, 0, }, /* 488 */ + { 20, 5, 12, 0, 74, 20, 0, }, /* 489 */ + { 20, 5, 12, 0, 86, 20, 0, }, /* 490 */ + { 20, 5, 12, 0, 100, 20, 0, }, /* 491 */ + { 20, 5, 12, 0, 128, 20, 0, }, /* 492 */ + { 20, 5, 12, 0, 112, 20, 0, }, /* 493 */ + { 20, 5, 12, 0, 126, 20, 0, }, /* 494 */ + { 20, 8, 12, 0, -8, 20, 0, }, /* 495 */ + { 20, 5, 12, 0, 9, 20, 0, }, /* 496 */ + { 20, 9, 12, 0, -74, 20, 0, }, /* 497 */ + { 20, 8, 12, 0, -9, 20, 0, }, /* 498 */ + { 20, 5, 12, 21, -7173, 20, 0, }, /* 499 */ + { 20, 9, 12, 0, -86, 20, 0, }, /* 500 */ + { 20, 9, 12, 0, -100, 20, 0, }, /* 501 */ + { 20, 9, 12, 0, -112, 20, 0, }, /* 502 */ + { 20, 9, 12, 0, -128, 20, 0, }, /* 503 */ + { 20, 9, 12, 0, -126, 20, 0, }, /* 504 */ + { 28, 1, 3, 0, 0, 28, 0, }, /* 505 */ + { 28, 1, 13, 0, 0, 28, 0, }, /* 506 */ + { 10, 27, 2, 0, 0, 10, 0, }, /* 507 */ + { 10, 28, 2, 0, 0, 10, 0, }, /* 508 */ + { 10, 29, 12, 0, 0, -67, 0, }, /* 509 */ + { 10, 21, 14, 0, 0, 10, 0, }, /* 510 */ + { 0, 2, 2, 0, 0, 0, 0, }, /* 511 */ + { 28, 12, 3, 0, 0, -93, 0, }, /* 512 */ + { 10, 9, 12, 0, 0, 10, 0, }, /* 513 */ + { 10, 5, 12, 0, 0, 10, 0, }, /* 514 */ + { 20, 9, 12, 96, -7517, 20, 0, }, /* 515 */ + { 34, 9, 12, 100, -8383, 34, 0, }, /* 516 */ + { 34, 9, 12, 104, -8262, 34, 0, }, /* 517 */ + { 34, 9, 12, 0, 28, 34, 0, }, /* 518 */ + { 10, 7, 12, 0, 0, 10, 0, }, /* 519 */ + { 10, 5, 14, 0, 0, 10, 0, }, /* 520 */ + { 34, 5, 12, 0, -28, 34, 0, }, /* 521 */ + { 34, 14, 12, 0, 16, 34, 0, }, /* 522 */ + { 34, 14, 12, 0, -16, 34, 0, }, /* 523 */ + { 34, 14, 12, 0, 0, 34, 0, }, /* 524 */ + { 10, 25, 14, 0, 0, 10, 0, }, /* 525 */ + { 10, 26, 12, 0, 26, 10, 0, }, /* 526 */ + { 10, 26, 14, 0, 26, 10, 0, }, /* 527 */ + { 10, 26, 12, 0, -26, 10, 0, }, /* 528 */ + { 5, 26, 12, 0, 0, 5, 0, }, /* 529 */ + { 18, 9, 12, 0, 48, 18, 0, }, /* 530 */ + { 18, 5, 12, 0, -48, 18, 0, }, /* 531 */ + { 34, 9, 12, 0, -10743, 34, 0, }, /* 532 */ + { 34, 9, 12, 0, -3814, 34, 0, }, /* 533 */ + { 34, 9, 12, 0, -10727, 34, 0, }, /* 534 */ + { 34, 5, 12, 0, -10795, 34, 0, }, /* 535 */ + { 34, 5, 12, 0, -10792, 34, 0, }, /* 536 */ + { 34, 9, 12, 0, -10780, 34, 0, }, /* 537 */ + { 34, 9, 12, 0, -10749, 34, 0, }, /* 538 */ + { 34, 9, 12, 0, -10783, 34, 0, }, /* 539 */ + { 34, 9, 12, 0, -10782, 34, 0, }, /* 540 */ + { 34, 9, 12, 0, -10815, 34, 0, }, /* 541 */ + { 11, 5, 12, 0, 0, 11, 0, }, /* 542 */ + { 11, 26, 12, 0, 0, 11, 0, }, /* 543 */ + { 11, 12, 3, 0, 0, 11, 0, }, /* 544 */ + { 11, 21, 12, 0, 0, 11, 0, }, /* 545 */ + { 11, 15, 12, 0, 0, 11, 0, }, /* 546 */ + { 17, 5, 12, 0, -7264, 17, 0, }, /* 547 */ + { 59, 7, 12, 0, 0, 59, 0, }, /* 548 */ + { 59, 6, 12, 0, 0, 59, 0, }, /* 549 */ + { 59, 21, 12, 0, 0, 59, 0, }, /* 550 */ + { 59, 12, 3, 0, 0, 59, 0, }, /* 551 */ + { 13, 12, 3, 0, 0, 13, 0, }, /* 552 */ + { 10, 21, 12, 0, 0, -28, 0, }, /* 553 */ + { 23, 26, 12, 0, 0, 23, 0, }, /* 554 */ + { 10, 21, 12, 0, 0, -131, 0, }, /* 555 */ + { 10, 21, 12, 0, 0, -125, 0, }, /* 556 */ + { 23, 6, 12, 0, 0, 23, 0, }, /* 557 */ + { 10, 7, 12, 0, 0, 23, 0, }, /* 558 */ + { 23, 14, 12, 0, 0, 23, 0, }, /* 559 */ + { 10, 22, 12, 0, 0, -131, 0, }, /* 560 */ + { 10, 18, 12, 0, 0, -131, 0, }, /* 561 */ + { 10, 26, 12, 0, 0, -125, 0, }, /* 562 */ + { 10, 17, 12, 0, 0, -125, 0, }, /* 563 */ + { 10, 22, 12, 0, 0, -125, 0, }, /* 564 */ + { 10, 18, 12, 0, 0, -125, 0, }, /* 565 */ + { 28, 12, 3, 0, 0, -19, 0, }, /* 566 */ + { 24, 10, 3, 0, 0, 24, 0, }, /* 567 */ + { 10, 17, 14, 0, 0, -125, 0, }, /* 568 */ + { 10, 6, 12, 0, 0, -61, 0, }, /* 569 */ + { 10, 7, 12, 0, 0, -97, 0, }, /* 570 */ + { 10, 21, 14, 0, 0, -97, 0, }, /* 571 */ + { 10, 26, 12, 0, 0, 23, 0, }, /* 572 */ + { 27, 7, 12, 0, 0, 27, 0, }, /* 573 */ + { 28, 12, 3, 0, 0, -61, 0, }, /* 574 */ + { 10, 24, 12, 0, 0, -61, 0, }, /* 575 */ + { 27, 6, 12, 0, 0, 27, 0, }, /* 576 */ + { 10, 17, 12, 0, 0, -61, 0, }, /* 577 */ + { 30, 7, 12, 0, 0, 30, 0, }, /* 578 */ + { 30, 6, 12, 0, 0, 30, 0, }, /* 579 */ + { 4, 7, 12, 0, 0, 4, 0, }, /* 580 */ + { 24, 7, 12, 0, 0, 24, 0, }, /* 581 */ + { 10, 15, 12, 0, 0, 23, 0, }, /* 582 */ + { 24, 26, 12, 0, 0, 24, 0, }, /* 583 */ + { 10, 26, 14, 0, 0, 23, 0, }, /* 584 */ + { 30, 26, 12, 0, 0, 30, 0, }, /* 585 */ + { 23, 7, 12, 0, 0, 23, 0, }, /* 586 */ + { 61, 7, 12, 0, 0, 61, 0, }, /* 587 */ + { 61, 6, 12, 0, 0, 61, 0, }, /* 588 */ + { 61, 26, 12, 0, 0, 61, 0, }, /* 589 */ + { 86, 7, 12, 0, 0, 86, 0, }, /* 590 */ + { 86, 6, 12, 0, 0, 86, 0, }, /* 591 */ + { 86, 21, 12, 0, 0, 86, 0, }, /* 592 */ + { 77, 7, 12, 0, 0, 77, 0, }, /* 593 */ + { 77, 6, 12, 0, 0, 77, 0, }, /* 594 */ + { 77, 21, 12, 0, 0, 77, 0, }, /* 595 */ + { 77, 13, 12, 0, 0, 77, 0, }, /* 596 */ + { 13, 9, 12, 108, 1, 13, 0, }, /* 597 */ + { 13, 5, 12, 108, -35267, 13, 0, }, /* 598 */ + { 13, 7, 12, 0, 0, 13, 0, }, /* 599 */ + { 13, 21, 12, 0, 0, 13, 0, }, /* 600 */ + { 79, 7, 12, 0, 0, 79, 0, }, /* 601 */ + { 79, 14, 12, 0, 0, 79, 0, }, /* 602 */ + { 79, 12, 3, 0, 0, 79, 0, }, /* 603 */ + { 79, 21, 12, 0, 0, 79, 0, }, /* 604 */ + { 34, 9, 12, 0, -35332, 34, 0, }, /* 605 */ + { 34, 9, 12, 0, -42280, 34, 0, }, /* 606 */ + { 34, 5, 12, 0, 48, 34, 0, }, /* 607 */ + { 34, 9, 12, 0, -42308, 34, 0, }, /* 608 */ + { 34, 9, 12, 0, -42319, 34, 0, }, /* 609 */ + { 34, 9, 12, 0, -42315, 34, 0, }, /* 610 */ + { 34, 9, 12, 0, -42305, 34, 0, }, /* 611 */ + { 34, 9, 12, 0, -42258, 34, 0, }, /* 612 */ + { 34, 9, 12, 0, -42282, 34, 0, }, /* 613 */ + { 34, 9, 12, 0, -42261, 34, 0, }, /* 614 */ + { 34, 9, 12, 0, 928, 34, 0, }, /* 615 */ + { 34, 9, 12, 0, -48, 34, 0, }, /* 616 */ + { 34, 9, 12, 0, -42307, 34, 0, }, /* 617 */ + { 34, 9, 12, 0, -35384, 34, 0, }, /* 618 */ + { 49, 7, 12, 0, 0, 49, 0, }, /* 619 */ + { 49, 12, 3, 0, 0, 49, 0, }, /* 620 */ + { 49, 10, 5, 0, 0, 49, 0, }, /* 621 */ + { 49, 26, 12, 0, 0, 49, 0, }, /* 622 */ + { 10, 15, 12, 0, 0, -216, 0, }, /* 623 */ + { 10, 15, 12, 0, 0, -202, 0, }, /* 624 */ + { 10, 26, 12, 0, 0, -163, 0, }, /* 625 */ + { 10, 23, 12, 0, 0, -163, 0, }, /* 626 */ + { 65, 7, 12, 0, 0, 65, 0, }, /* 627 */ + { 65, 21, 12, 0, 0, 65, 0, }, /* 628 */ + { 75, 10, 5, 0, 0, 75, 0, }, /* 629 */ + { 75, 7, 12, 0, 0, 75, 0, }, /* 630 */ + { 75, 12, 3, 0, 0, 75, 0, }, /* 631 */ + { 75, 21, 12, 0, 0, 75, 0, }, /* 632 */ + { 75, 13, 12, 0, 0, 75, 0, }, /* 633 */ + { 15, 12, 3, 0, 0, -16, 0, }, /* 634 */ + { 15, 7, 12, 0, 0, -46, 0, }, /* 635 */ + { 69, 13, 12, 0, 0, 69, 0, }, /* 636 */ + { 69, 7, 12, 0, 0, 69, 0, }, /* 637 */ + { 69, 12, 3, 0, 0, 69, 0, }, /* 638 */ + { 10, 21, 12, 0, 0, -101, 0, }, /* 639 */ + { 69, 21, 12, 0, 0, 69, 0, }, /* 640 */ + { 74, 7, 12, 0, 0, 74, 0, }, /* 641 */ + { 74, 12, 3, 0, 0, 74, 0, }, /* 642 */ + { 74, 10, 5, 0, 0, 74, 0, }, /* 643 */ + { 74, 21, 12, 0, 0, 74, 0, }, /* 644 */ + { 84, 12, 3, 0, 0, 84, 0, }, /* 645 */ + { 84, 10, 5, 0, 0, 84, 0, }, /* 646 */ + { 84, 7, 12, 0, 0, 84, 0, }, /* 647 */ + { 84, 21, 12, 0, 0, 84, 0, }, /* 648 */ + { 10, 6, 12, 0, 0, -22, 0, }, /* 649 */ + { 84, 13, 12, 0, 0, 84, 0, }, /* 650 */ + { 39, 6, 12, 0, 0, 39, 0, }, /* 651 */ + { 68, 7, 12, 0, 0, 68, 0, }, /* 652 */ + { 68, 12, 3, 0, 0, 68, 0, }, /* 653 */ + { 68, 10, 5, 0, 0, 68, 0, }, /* 654 */ + { 68, 13, 12, 0, 0, 68, 0, }, /* 655 */ + { 68, 21, 12, 0, 0, 68, 0, }, /* 656 */ + { 92, 7, 12, 0, 0, 92, 0, }, /* 657 */ + { 92, 12, 3, 0, 0, 92, 0, }, /* 658 */ + { 92, 6, 12, 0, 0, 92, 0, }, /* 659 */ + { 92, 21, 12, 0, 0, 92, 0, }, /* 660 */ + { 87, 7, 12, 0, 0, 87, 0, }, /* 661 */ + { 87, 10, 5, 0, 0, 87, 0, }, /* 662 */ + { 87, 12, 3, 0, 0, 87, 0, }, /* 663 */ + { 87, 21, 12, 0, 0, 87, 0, }, /* 664 */ + { 87, 6, 12, 0, 0, 87, 0, }, /* 665 */ + { 34, 5, 12, 0, -928, 34, 0, }, /* 666 */ + { 9, 5, 12, 0, -38864, 9, 0, }, /* 667 */ + { 87, 13, 12, 0, 0, 87, 0, }, /* 668 */ + { 24, 7, 9, 0, 0, 24, 0, }, /* 669 */ + { 24, 7, 10, 0, 0, 24, 0, }, /* 670 */ + { 0, 4, 12, 0, 0, 0, 0, }, /* 671 */ + { 0, 3, 12, 0, 0, 0, 0, }, /* 672 */ + { 26, 25, 12, 0, 0, 26, 0, }, /* 673 */ + { 1, 24, 12, 0, 0, 1, 0, }, /* 674 */ + { 1, 7, 12, 0, 0, -10, 0, }, /* 675 */ + { 1, 26, 12, 0, 0, -10, 0, }, /* 676 */ + { 10, 6, 3, 0, 0, -61, 0, }, /* 677 */ + { 36, 7, 12, 0, 0, 36, 0, }, /* 678 */ + { 10, 21, 12, 0, 0, -25, 0, }, /* 679 */ + { 10, 15, 12, 0, 0, -85, 0, }, /* 680 */ + { 10, 26, 12, 0, 0, -25, 0, }, /* 681 */ + { 20, 14, 12, 0, 0, 20, 0, }, /* 682 */ + { 20, 15, 12, 0, 0, 20, 0, }, /* 683 */ + { 20, 26, 12, 0, 0, 20, 0, }, /* 684 */ + { 71, 7, 12, 0, 0, 71, 0, }, /* 685 */ + { 67, 7, 12, 0, 0, 67, 0, }, /* 686 */ + { 28, 12, 3, 0, 0, -1, 0, }, /* 687 */ + { 10, 15, 12, 0, 0, -1, 0, }, /* 688 */ + { 42, 7, 12, 0, 0, 42, 0, }, /* 689 */ + { 42, 15, 12, 0, 0, 42, 0, }, /* 690 */ + { 19, 7, 12, 0, 0, 19, 0, }, /* 691 */ + { 19, 14, 12, 0, 0, 19, 0, }, /* 692 */ + { 118, 7, 12, 0, 0, 118, 0, }, /* 693 */ + { 118, 12, 3, 0, 0, 118, 0, }, /* 694 */ + { 60, 7, 12, 0, 0, 60, 0, }, /* 695 */ + { 60, 21, 12, 0, 0, 60, 0, }, /* 696 */ + { 43, 7, 12, 0, 0, 43, 0, }, /* 697 */ + { 43, 21, 12, 0, 0, 43, 0, }, /* 698 */ + { 43, 14, 12, 0, 0, 43, 0, }, /* 699 */ + { 14, 9, 12, 0, 40, 14, 0, }, /* 700 */ + { 14, 5, 12, 0, -40, 14, 0, }, /* 701 */ + { 47, 7, 12, 0, 0, 47, 0, }, /* 702 */ + { 45, 7, 12, 0, 0, 45, 0, }, /* 703 */ + { 45, 13, 12, 0, 0, 45, 0, }, /* 704 */ + { 136, 9, 12, 0, 40, 136, 0, }, /* 705 */ + { 136, 5, 12, 0, -40, 136, 0, }, /* 706 */ + { 106, 7, 12, 0, 0, 106, 0, }, /* 707 */ + { 104, 7, 12, 0, 0, 104, 0, }, /* 708 */ + { 104, 21, 12, 0, 0, 104, 0, }, /* 709 */ + { 110, 7, 12, 0, 0, 110, 0, }, /* 710 */ + { 12, 7, 12, 0, 0, 12, 0, }, /* 711 */ + { 81, 7, 12, 0, 0, 81, 0, }, /* 712 */ + { 81, 21, 12, 0, 0, 81, 0, }, /* 713 */ + { 81, 15, 12, 0, 0, 81, 0, }, /* 714 */ + { 120, 7, 12, 0, 0, 120, 0, }, /* 715 */ + { 120, 26, 12, 0, 0, 120, 0, }, /* 716 */ + { 120, 15, 12, 0, 0, 120, 0, }, /* 717 */ + { 116, 7, 12, 0, 0, 116, 0, }, /* 718 */ + { 116, 15, 12, 0, 0, 116, 0, }, /* 719 */ + { 128, 7, 12, 0, 0, 128, 0, }, /* 720 */ + { 128, 15, 12, 0, 0, 128, 0, }, /* 721 */ + { 66, 7, 12, 0, 0, 66, 0, }, /* 722 */ + { 66, 15, 12, 0, 0, 66, 0, }, /* 723 */ + { 66, 21, 12, 0, 0, 66, 0, }, /* 724 */ + { 72, 7, 12, 0, 0, 72, 0, }, /* 725 */ + { 72, 21, 12, 0, 0, 72, 0, }, /* 726 */ + { 98, 7, 12, 0, 0, 98, 0, }, /* 727 */ + { 97, 7, 12, 0, 0, 97, 0, }, /* 728 */ + { 97, 15, 12, 0, 0, 97, 0, }, /* 729 */ + { 31, 7, 12, 0, 0, 31, 0, }, /* 730 */ + { 31, 12, 3, 0, 0, 31, 0, }, /* 731 */ + { 31, 15, 12, 0, 0, 31, 0, }, /* 732 */ + { 31, 21, 12, 0, 0, 31, 0, }, /* 733 */ + { 88, 7, 12, 0, 0, 88, 0, }, /* 734 */ + { 88, 15, 12, 0, 0, 88, 0, }, /* 735 */ + { 88, 21, 12, 0, 0, 88, 0, }, /* 736 */ + { 117, 7, 12, 0, 0, 117, 0, }, /* 737 */ + { 117, 15, 12, 0, 0, 117, 0, }, /* 738 */ + { 112, 7, 12, 0, 0, 112, 0, }, /* 739 */ + { 112, 26, 12, 0, 0, 112, 0, }, /* 740 */ + { 112, 12, 3, 0, 0, 112, 0, }, /* 741 */ + { 112, 15, 12, 0, 0, 112, 0, }, /* 742 */ + { 112, 21, 12, 0, 0, 112, 0, }, /* 743 */ + { 78, 7, 12, 0, 0, 78, 0, }, /* 744 */ + { 78, 21, 12, 0, 0, 78, 0, }, /* 745 */ + { 83, 7, 12, 0, 0, 83, 0, }, /* 746 */ + { 83, 15, 12, 0, 0, 83, 0, }, /* 747 */ + { 82, 7, 12, 0, 0, 82, 0, }, /* 748 */ + { 82, 15, 12, 0, 0, 82, 0, }, /* 749 */ + { 121, 7, 12, 0, 0, 121, 0, }, /* 750 */ + { 121, 21, 12, 0, 0, 121, 0, }, /* 751 */ + { 121, 15, 12, 0, 0, 121, 0, }, /* 752 */ + { 89, 7, 12, 0, 0, 89, 0, }, /* 753 */ + { 130, 9, 12, 0, 64, 130, 0, }, /* 754 */ + { 130, 5, 12, 0, -64, 130, 0, }, /* 755 */ + { 130, 15, 12, 0, 0, 130, 0, }, /* 756 */ + { 144, 7, 12, 0, 0, 144, 0, }, /* 757 */ + { 144, 12, 3, 0, 0, 144, 0, }, /* 758 */ + { 144, 13, 12, 0, 0, 144, 0, }, /* 759 */ + { 1, 15, 12, 0, 0, 1, 0, }, /* 760 */ + { 147, 7, 12, 0, 0, 147, 0, }, /* 761 */ + { 147, 15, 12, 0, 0, 147, 0, }, /* 762 */ + { 148, 7, 12, 0, 0, 148, 0, }, /* 763 */ + { 148, 12, 3, 0, 0, 148, 0, }, /* 764 */ + { 148, 15, 12, 0, 0, 148, 0, }, /* 765 */ + { 148, 21, 12, 0, 0, 148, 0, }, /* 766 */ + { 149, 7, 12, 0, 0, 149, 0, }, /* 767 */ + { 94, 10, 5, 0, 0, 94, 0, }, /* 768 */ + { 94, 12, 3, 0, 0, 94, 0, }, /* 769 */ + { 94, 7, 12, 0, 0, 94, 0, }, /* 770 */ + { 94, 21, 12, 0, 0, 94, 0, }, /* 771 */ + { 94, 15, 12, 0, 0, 94, 0, }, /* 772 */ + { 94, 13, 12, 0, 0, 94, 0, }, /* 773 */ + { 85, 12, 3, 0, 0, 85, 0, }, /* 774 */ + { 85, 10, 5, 0, 0, 85, 0, }, /* 775 */ + { 85, 7, 12, 0, 0, 85, 0, }, /* 776 */ + { 85, 21, 12, 0, 0, 85, 0, }, /* 777 */ + { 85, 1, 4, 0, 0, 85, 0, }, /* 778 */ + { 101, 7, 12, 0, 0, 101, 0, }, /* 779 */ + { 101, 13, 12, 0, 0, 101, 0, }, /* 780 */ + { 96, 12, 3, 0, 0, 96, 0, }, /* 781 */ + { 96, 7, 12, 0, 0, 96, 0, }, /* 782 */ + { 96, 10, 5, 0, 0, 96, 0, }, /* 783 */ + { 96, 13, 12, 0, 0, 96, 0, }, /* 784 */ + { 96, 21, 12, 0, 0, 96, 0, }, /* 785 */ + { 111, 7, 12, 0, 0, 111, 0, }, /* 786 */ + { 111, 12, 3, 0, 0, 111, 0, }, /* 787 */ + { 111, 21, 12, 0, 0, 111, 0, }, /* 788 */ + { 100, 12, 3, 0, 0, 100, 0, }, /* 789 */ + { 100, 10, 5, 0, 0, 100, 0, }, /* 790 */ + { 100, 7, 12, 0, 0, 100, 0, }, /* 791 */ + { 100, 7, 4, 0, 0, 100, 0, }, /* 792 */ + { 100, 21, 12, 0, 0, 100, 0, }, /* 793 */ + { 100, 13, 12, 0, 0, 100, 0, }, /* 794 */ + { 48, 15, 12, 0, 0, 48, 0, }, /* 795 */ + { 108, 7, 12, 0, 0, 108, 0, }, /* 796 */ + { 108, 10, 5, 0, 0, 108, 0, }, /* 797 */ + { 108, 12, 3, 0, 0, 108, 0, }, /* 798 */ + { 108, 21, 12, 0, 0, 108, 0, }, /* 799 */ + { 129, 7, 12, 0, 0, 129, 0, }, /* 800 */ + { 129, 21, 12, 0, 0, 129, 0, }, /* 801 */ + { 109, 7, 12, 0, 0, 109, 0, }, /* 802 */ + { 109, 12, 3, 0, 0, 109, 0, }, /* 803 */ + { 109, 10, 5, 0, 0, 109, 0, }, /* 804 */ + { 109, 13, 12, 0, 0, 109, 0, }, /* 805 */ + { 107, 12, 3, 0, 0, 107, 0, }, /* 806 */ + { 107, 12, 3, 0, 0, -52, 0, }, /* 807 */ + { 107, 10, 5, 0, 0, 107, 0, }, /* 808 */ + { 107, 10, 5, 0, 0, -52, 0, }, /* 809 */ + { 107, 7, 12, 0, 0, 107, 0, }, /* 810 */ + { 28, 12, 3, 0, 0, -52, 0, }, /* 811 */ + { 107, 10, 3, 0, 0, 107, 0, }, /* 812 */ + { 135, 7, 12, 0, 0, 135, 0, }, /* 813 */ + { 135, 10, 5, 0, 0, 135, 0, }, /* 814 */ + { 135, 12, 3, 0, 0, 135, 0, }, /* 815 */ + { 135, 21, 12, 0, 0, 135, 0, }, /* 816 */ + { 135, 13, 12, 0, 0, 135, 0, }, /* 817 */ + { 124, 7, 12, 0, 0, 124, 0, }, /* 818 */ + { 124, 10, 3, 0, 0, 124, 0, }, /* 819 */ + { 124, 10, 5, 0, 0, 124, 0, }, /* 820 */ + { 124, 12, 3, 0, 0, 124, 0, }, /* 821 */ + { 124, 21, 12, 0, 0, 124, 0, }, /* 822 */ + { 124, 13, 12, 0, 0, 124, 0, }, /* 823 */ + { 123, 7, 12, 0, 0, 123, 0, }, /* 824 */ + { 123, 10, 3, 0, 0, 123, 0, }, /* 825 */ + { 123, 10, 5, 0, 0, 123, 0, }, /* 826 */ + { 123, 12, 3, 0, 0, 123, 0, }, /* 827 */ + { 123, 21, 12, 0, 0, 123, 0, }, /* 828 */ + { 114, 7, 12, 0, 0, 114, 0, }, /* 829 */ + { 114, 10, 5, 0, 0, 114, 0, }, /* 830 */ + { 114, 12, 3, 0, 0, 114, 0, }, /* 831 */ + { 114, 21, 12, 0, 0, 114, 0, }, /* 832 */ + { 114, 13, 12, 0, 0, 114, 0, }, /* 833 */ + { 102, 7, 12, 0, 0, 102, 0, }, /* 834 */ + { 102, 12, 3, 0, 0, 102, 0, }, /* 835 */ + { 102, 10, 5, 0, 0, 102, 0, }, /* 836 */ + { 102, 13, 12, 0, 0, 102, 0, }, /* 837 */ + { 126, 7, 12, 0, 0, 126, 0, }, /* 838 */ + { 126, 12, 3, 0, 0, 126, 0, }, /* 839 */ + { 126, 10, 5, 0, 0, 126, 0, }, /* 840 */ + { 126, 13, 12, 0, 0, 126, 0, }, /* 841 */ + { 126, 15, 12, 0, 0, 126, 0, }, /* 842 */ + { 126, 21, 12, 0, 0, 126, 0, }, /* 843 */ + { 126, 26, 12, 0, 0, 126, 0, }, /* 844 */ + { 142, 7, 12, 0, 0, 142, 0, }, /* 845 */ + { 142, 10, 5, 0, 0, 142, 0, }, /* 846 */ + { 142, 12, 3, 0, 0, 142, 0, }, /* 847 */ + { 142, 21, 12, 0, 0, 142, 0, }, /* 848 */ + { 125, 9, 12, 0, 32, 125, 0, }, /* 849 */ + { 125, 5, 12, 0, -32, 125, 0, }, /* 850 */ + { 125, 13, 12, 0, 0, 125, 0, }, /* 851 */ + { 125, 15, 12, 0, 0, 125, 0, }, /* 852 */ + { 125, 7, 12, 0, 0, 125, 0, }, /* 853 */ + { 150, 7, 12, 0, 0, 150, 0, }, /* 854 */ + { 150, 10, 5, 0, 0, 150, 0, }, /* 855 */ + { 150, 12, 3, 0, 0, 150, 0, }, /* 856 */ + { 150, 21, 12, 0, 0, 150, 0, }, /* 857 */ + { 141, 7, 12, 0, 0, 141, 0, }, /* 858 */ + { 141, 12, 3, 0, 0, 141, 0, }, /* 859 */ + { 141, 10, 5, 0, 0, 141, 0, }, /* 860 */ + { 141, 7, 4, 0, 0, 141, 0, }, /* 861 */ + { 141, 21, 12, 0, 0, 141, 0, }, /* 862 */ + { 140, 7, 12, 0, 0, 140, 0, }, /* 863 */ + { 140, 12, 3, 0, 0, 140, 0, }, /* 864 */ + { 140, 10, 5, 0, 0, 140, 0, }, /* 865 */ + { 140, 7, 4, 0, 0, 140, 0, }, /* 866 */ + { 140, 21, 12, 0, 0, 140, 0, }, /* 867 */ + { 122, 7, 12, 0, 0, 122, 0, }, /* 868 */ + { 133, 7, 12, 0, 0, 133, 0, }, /* 869 */ + { 133, 10, 5, 0, 0, 133, 0, }, /* 870 */ + { 133, 12, 3, 0, 0, 133, 0, }, /* 871 */ + { 133, 21, 12, 0, 0, 133, 0, }, /* 872 */ + { 133, 13, 12, 0, 0, 133, 0, }, /* 873 */ + { 133, 15, 12, 0, 0, 133, 0, }, /* 874 */ + { 134, 21, 12, 0, 0, 134, 0, }, /* 875 */ + { 134, 7, 12, 0, 0, 134, 0, }, /* 876 */ + { 134, 12, 3, 0, 0, 134, 0, }, /* 877 */ + { 134, 10, 5, 0, 0, 134, 0, }, /* 878 */ + { 138, 7, 12, 0, 0, 138, 0, }, /* 879 */ + { 138, 12, 3, 0, 0, 138, 0, }, /* 880 */ + { 138, 7, 4, 0, 0, 138, 0, }, /* 881 */ + { 138, 13, 12, 0, 0, 138, 0, }, /* 882 */ + { 143, 7, 12, 0, 0, 143, 0, }, /* 883 */ + { 143, 10, 5, 0, 0, 143, 0, }, /* 884 */ + { 143, 12, 3, 0, 0, 143, 0, }, /* 885 */ + { 143, 13, 12, 0, 0, 143, 0, }, /* 886 */ + { 145, 7, 12, 0, 0, 145, 0, }, /* 887 */ + { 145, 12, 3, 0, 0, 145, 0, }, /* 888 */ + { 145, 10, 5, 0, 0, 145, 0, }, /* 889 */ + { 145, 21, 12, 0, 0, 145, 0, }, /* 890 */ + { 54, 15, 12, 0, 0, 54, 0, }, /* 891 */ + { 54, 21, 12, 0, 0, 54, 0, }, /* 892 */ + { 63, 7, 12, 0, 0, 63, 0, }, /* 893 */ + { 63, 14, 12, 0, 0, 63, 0, }, /* 894 */ + { 63, 21, 12, 0, 0, 63, 0, }, /* 895 */ + { 80, 7, 12, 0, 0, 80, 0, }, /* 896 */ + { 80, 1, 2, 0, 0, 80, 0, }, /* 897 */ + { 127, 7, 12, 0, 0, 127, 0, }, /* 898 */ + { 115, 7, 12, 0, 0, 115, 0, }, /* 899 */ + { 115, 13, 12, 0, 0, 115, 0, }, /* 900 */ + { 115, 21, 12, 0, 0, 115, 0, }, /* 901 */ + { 103, 7, 12, 0, 0, 103, 0, }, /* 902 */ + { 103, 12, 3, 0, 0, 103, 0, }, /* 903 */ + { 103, 21, 12, 0, 0, 103, 0, }, /* 904 */ + { 119, 7, 12, 0, 0, 119, 0, }, /* 905 */ + { 119, 12, 3, 0, 0, 119, 0, }, /* 906 */ + { 119, 21, 12, 0, 0, 119, 0, }, /* 907 */ + { 119, 26, 12, 0, 0, 119, 0, }, /* 908 */ + { 119, 6, 12, 0, 0, 119, 0, }, /* 909 */ + { 119, 13, 12, 0, 0, 119, 0, }, /* 910 */ + { 119, 15, 12, 0, 0, 119, 0, }, /* 911 */ + { 146, 9, 12, 0, 32, 146, 0, }, /* 912 */ + { 146, 5, 12, 0, -32, 146, 0, }, /* 913 */ + { 146, 15, 12, 0, 0, 146, 0, }, /* 914 */ + { 146, 21, 12, 0, 0, 146, 0, }, /* 915 */ + { 99, 7, 12, 0, 0, 99, 0, }, /* 916 */ + { 99, 12, 3, 0, 0, 99, 0, }, /* 917 */ + { 99, 10, 5, 0, 0, 99, 0, }, /* 918 */ + { 99, 6, 12, 0, 0, 99, 0, }, /* 919 */ + { 137, 6, 12, 0, 0, 137, 0, }, /* 920 */ + { 139, 6, 12, 0, 0, 139, 0, }, /* 921 */ + { 137, 7, 12, 0, 0, 137, 0, }, /* 922 */ + { 139, 7, 12, 0, 0, 139, 0, }, /* 923 */ + { 105, 7, 12, 0, 0, 105, 0, }, /* 924 */ + { 105, 26, 12, 0, 0, 105, 0, }, /* 925 */ + { 105, 12, 3, 0, 0, 105, 0, }, /* 926 */ + { 105, 21, 12, 0, 0, 105, 0, }, /* 927 */ + { 10, 1, 2, 0, 0, 105, 0, }, /* 928 */ + { 10, 10, 3, 0, 0, 10, 0, }, /* 929 */ + { 10, 10, 5, 0, 0, 10, 0, }, /* 930 */ + { 20, 12, 3, 0, 0, 20, 0, }, /* 931 */ + { 131, 26, 12, 0, 0, 131, 0, }, /* 932 */ + { 131, 12, 3, 0, 0, 131, 0, }, /* 933 */ + { 131, 21, 12, 0, 0, 131, 0, }, /* 934 */ + { 18, 12, 3, 0, 0, 18, 0, }, /* 935 */ + { 151, 7, 12, 0, 0, 151, 0, }, /* 936 */ + { 151, 12, 3, 0, 0, 151, 0, }, /* 937 */ + { 151, 6, 12, 0, 0, 151, 0, }, /* 938 */ + { 151, 13, 12, 0, 0, 151, 0, }, /* 939 */ + { 151, 26, 12, 0, 0, 151, 0, }, /* 940 */ + { 152, 7, 12, 0, 0, 152, 0, }, /* 941 */ + { 152, 12, 3, 0, 0, 152, 0, }, /* 942 */ + { 152, 13, 12, 0, 0, 152, 0, }, /* 943 */ + { 152, 23, 12, 0, 0, 152, 0, }, /* 944 */ + { 113, 7, 12, 0, 0, 113, 0, }, /* 945 */ + { 113, 15, 12, 0, 0, 113, 0, }, /* 946 */ + { 113, 12, 3, 0, 0, 113, 0, }, /* 947 */ + { 132, 9, 12, 0, 34, 132, 0, }, /* 948 */ + { 132, 5, 12, 0, -34, 132, 0, }, /* 949 */ + { 132, 12, 3, 0, 0, 132, 0, }, /* 950 */ + { 132, 6, 12, 0, 0, 132, 0, }, /* 951 */ + { 132, 13, 12, 0, 0, 132, 0, }, /* 952 */ + { 132, 21, 12, 0, 0, 132, 0, }, /* 953 */ + { 0, 2, 14, 0, 0, 0, 0, }, /* 954 */ + { 10, 26, 11, 0, 0, 10, 0, }, /* 955 */ + { 27, 26, 12, 0, 0, 27, 0, }, /* 956 */ + { 10, 24, 3, 0, 0, 10, 0, }, /* 957 */ + { 10, 1, 3, 0, 0, 10, 0, }, /* 958 */ }; const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ @@ -1150,37 +1185,37 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F000 */ 126,126, 98, 98,127,128,129,130,131,131,132,133,134,135,136,137, /* U+F800 */ 138,139,140,141,142,143,144,145,146,147,148,142,149,149,150,142, /* U+10000 */ -151,152,153,154,155,156,157,158,159,160,161,142,162,142,163,142, /* U+10800 */ -164,165,166,167,168,169,170,142,171,172,142,173,174,175,176,142, /* U+11000 */ -177,178,142,142,179,180,142,142,181,182,183,184,142,185,142,142, /* U+11800 */ -186,186,186,186,186,186,186,187,188,186,189,142,142,142,142,142, /* U+12000 */ +151,152,153,154,155,156,157,158,159,160,161,142,162,142,163,164, /* U+10800 */ +165,166,167,168,169,170,171,142,172,173,142,174,175,176,177,142, /* U+11000 */ +178,179,142,180,181,182,142,142,183,184,185,186,142,187,142,188, /* U+11800 */ +189,189,189,189,189,189,189,190,191,189,192,142,142,142,142,142, /* U+12000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+12800 */ -190,190,190,190,190,190,190,190,191,142,142,142,142,142,142,142, /* U+13000 */ +193,193,193,193,193,193,193,193,194,142,142,142,142,142,142,142, /* U+13000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+13800 */ -142,142,142,142,142,142,142,142,192,192,192,192,193,142,142,142, /* U+14000 */ +142,142,142,142,142,142,142,142,195,195,195,195,196,142,142,142, /* U+14000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+14800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+16000 */ -194,194,194,194,195,196,197,198,142,142,142,142,199,200,201,202, /* U+16800 */ -203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, /* U+17000 */ -203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, /* U+17800 */ -203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,204, /* U+18000 */ -203,203,203,203,203,205,142,142,142,142,142,142,142,142,142,142, /* U+18800 */ +197,197,197,197,198,199,200,201,142,142,142,142,202,203,204,205, /* U+16800 */ +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17000 */ +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17800 */ +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,207, /* U+18000 */ +206,206,206,206,206,208,142,142,142,142,142,142,142,142,142,142, /* U+18800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A800 */ -206,207,208,209,209,210,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */ -142,142,142,142,142,142,142,142,211,212,142,142,142,142,142,142, /* U+1B800 */ +209,210,211,212,212,213,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */ +142,142,142,142,142,142,142,142,214,215,142,142,142,142,142,142, /* U+1B800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C800 */ - 71,213,214,215,216,217,218,142,219,220,221,222,223,224,225,226, /* U+1D000 */ -227,227,227,227,228,229,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */ -230,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */ -231,232,233,142,142,142,142,142,234,235,142,142,236,237,142,142, /* U+1E800 */ -238,239,240,241,242,243,244,245,244,244,246,244,247,248,249,250, /* U+1F000 */ -251,252,253,254,255,243,243,243,243,243,243,243,243,243,243,256, /* U+1F800 */ + 71,216,217,218,219,220,221,142,222,223,224,225,226,227,228,229, /* U+1D000 */ +230,230,230,230,231,232,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */ +233,142,234,142,142,235,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */ +236,237,238,142,142,142,142,142,239,240,241,142,242,243,142,142, /* U+1E800 */ +244,245,246,247,248,249,250,251,250,250,252,250,253,254,255,256, /* U+1F000 */ +257,258,259,260,261,262,249,249,249,249,249,249,249,249,249,263, /* U+1F800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+21000 */ @@ -1201,18 +1236,18 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+28800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29800 */ - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,257, 98, 98, /* U+2A000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,264, 98, 98, /* U+2A000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2A800 */ - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,258, 98, /* U+2B000 */ -259, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,265, 98, /* U+2B000 */ +266, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2C000 */ - 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,260, 98, 98, /* U+2C800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,267, 98, 98, /* U+2C800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D000 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D800 */ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2E000 */ - 98, 98, 98, 98, 98, 98, 98,261,142,142,142,142,142,142,142,142, /* U+2E800 */ + 98, 98, 98, 98, 98, 98, 98,268,142,142,142,142,142,142,142,142, /* U+2E800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+2F000 */ - 98, 98, 98, 98,262,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */ + 98, 98, 98, 98,269,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+31000 */ @@ -1565,8 +1600,8 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DE800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF800 */ -263,264,265,266,264,264,264,264,264,264,264,264,264,264,264,264, /* U+E0000 */ -264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264, /* U+E0800 */ +270,271,272,273,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0000 */ +271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1000 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1800 */ 142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E2000 */ @@ -1628,7 +1663,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE000 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FF000 */ -126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,267, /* U+FF800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+FF800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100000 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+101000 */ @@ -1660,10 +1695,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E000 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E800 */ 126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10F000 */ -126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,267, /* U+10F800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+10F800 */ }; -const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ +const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */ /* block 0 */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1715,534 +1750,534 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 35, 97, 98, 35, 35, 99, 35, 35, 35, 35, 35, 35, 35,100, 35, 35, /* block 5 */ -101, 35, 35,101, 35, 35, 35,102,101,103,104,104,105, 35, 35, 35, - 35, 35,106, 35, 22, 35, 35, 35, 35, 35, 35, 35, 35,107,108, 35, +101, 35,102,101, 35, 35, 35,103,101,104,105,105,106, 35, 35, 35, + 35, 35,107, 35, 22, 35, 35, 35, 35, 35, 35, 35, 35,108,109, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, -109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110, -110,110, 15, 15, 15, 15,110,110,110,110,110,110,110,110,110,110, -110,110, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -109,109,109,109,109, 15, 15, 15, 15, 15,111,111,110, 15,110, 15, +110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111, +111,111, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111,111, +111,111, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +110,110,110,110,110, 15, 15, 15, 15, 15,112,112,111, 15,111, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, /* block 6 */ -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,113,112,112,114,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,115,115,115,115,115,115,115,115,115,115,115,115,115, -116,117,116,117,110,118,116,117,119,119,120,121,121,121, 5,122, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,114,113,113,115,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,116,116,116,116,116,116,116,116,116,116,116,116,116, +117,118,117,118,111,119,117,118,120,120,121,122,122,122, 5,123, /* block 7 */ -119,119,119,119,118, 15,123, 5,124,124,124,119,125,119,126,126, -127,128,129,128,128,130,128,128,131,132,133,128,134,128,128,128, -135,136,119,137,128,128,138,128,128,139,128,128,140,141,141,141, -127,142,143,142,142,144,142,142,145,146,147,142,148,142,142,142, -149,150,151,152,142,142,153,142,142,154,142,142,155,156,156,157, -158,159,160,160,160,161,162,163,116,117,116,117,116,117,116,117, -116,117,164,165,164,165,164,165,164,165,164,165,164,165,164,165, -166,167,168,169,170,171,172,116,117,173,116,117,127,174,174,174, +120,120,120,120,119, 15,124, 5,125,125,125,120,126,120,127,127, +128,129,130,129,129,131,129,129,132,133,134,129,135,129,129,129, +136,137,120,138,129,129,139,129,129,140,129,129,141,142,142,142, +128,143,144,143,143,145,143,143,146,147,148,143,149,143,143,143, +150,151,152,153,143,143,154,143,143,155,143,143,156,157,157,158, +159,160,161,161,161,162,163,164,117,118,117,118,117,118,117,118, +117,118,165,166,165,166,165,166,165,166,165,166,165,166,165,166, +167,168,169,170,171,172,173,117,118,174,117,118,128,175,175,175, /* block 8 */ -175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, -176,176,177,176,178,176,176,176,176,176,176,176,176,176,179,176, -176,180,181,176,176,176,176,176,176,176,182,176,176,176,176,176, -183,183,184,183,185,183,183,183,183,183,183,183,183,183,186,183, -183,187,188,183,183,183,183,183,183,183,189,183,183,183,183,183, -190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, -191,192,193,194,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176, +177,177,178,177,179,177,177,177,177,177,177,177,177,177,180,177, +177,181,182,177,177,177,177,177,177,177,183,177,177,177,177,177, +184,184,185,184,186,184,184,184,184,184,184,184,184,184,187,184, +184,188,189,184,184,184,184,184,184,184,190,184,184,184,184,184, +191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191, +192,193,194,195,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, /* block 9 */ -191,192,195,196,197,198,198,197,199,199,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -200,191,192,191,192,191,192,191,192,191,192,191,192,191,192,201, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +192,193,196,197,198,199,199,198,200,200,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +201,192,193,192,193,192,193,192,193,192,193,192,193,192,193,202, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, /* block 10 */ -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -119,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, -202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, -202,202,202,202,202,202,202,119,119,203,204,204,204,204,204,204, -205,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, -206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +120,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, +203,203,203,203,203,203,203,120,120,204,205,205,205,205,205,205, +206,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, +207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207, /* block 11 */ -206,206,206,206,206,206,206,205,205,207,208,119,119,209,209,210, -119,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, -211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211, -211,211,211,211,211,211,211,211,211,211,211,211,211,211,212,211, -213,211,211,213,211,211,213,211,119,119,119,119,119,119,119,119, -214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214, -214,214,214,214,214,214,214,214,214,214,214,119,119,119,119,214, -214,214,214,213,213,119,119,119,119,119,119,119,119,119,119,119, +207,207,207,207,207,207,207,206,206,208,209,120,120,210,210,211, +120,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212, +212,212,212,212,212,212,212,212,212,212,212,212,212,212,213,212, +214,212,212,214,212,212,214,212,120,120,120,120,120,120,120,120, +215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215, +215,215,215,215,215,215,215,215,215,215,215,120,120,120,120,215, +215,215,215,214,214,120,120,120,120,120,120,120,120,120,120,120, /* block 12 */ -215,215,215,215,215,216,217,217,217,218,218,219,220,218,221,221, -222,222,222,222,222,222,222,222,222,222,222,220,223,119,218,220, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -225,224,224,224,224,224,224,224,224,224,224,226,226,226,226,226, -226,226,226,226,226,226,222,222,222,222,222,222,222,222,222,222, -227,227,227,227,227,227,227,227,227,227,218,218,218,218,224,224, -226,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +216,216,216,216,216,217,218,218,218,219,219,220,221,219,222,222, +223,223,223,223,223,223,223,223,223,223,223,221,224,120,219,221, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +226,225,225,225,225,225,225,225,225,225,225,227,227,227,227,227, +227,227,227,227,227,227,223,223,223,223,223,223,223,223,223,223, +228,228,228,228,228,228,228,228,228,228,219,219,219,219,225,225, +227,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, /* block 13 */ -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,228,224,222,222,222,222,222,222,222,216,221,222, -222,222,222,222,222,229,229,222,222,221,222,222,222,222,224,224, -230,230,230,230,230,230,230,230,230,230,224,224,224,221,221,224, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,229,225,223,223,223,223,223,223,223,217,222,223, +223,223,223,223,223,230,230,223,223,222,223,223,223,223,225,225, +231,231,231,231,231,231,231,231,231,231,225,225,225,222,222,225, /* block 14 */ -231,231,231,231,231,231,231,231,231,231,231,231,231,231,119,232, -233,234,233,233,233,233,233,233,233,233,233,233,233,233,233,233, -233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233, +232,232,232,232,232,232,232,232,232,232,232,232,232,232,120,233, +234,235,234,234,234,234,234,234,234,234,234,234,234,234,234,234, 234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234, -234,234,234,234,234,234,234,234,234,234,234,119,119,233,233,233, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, +235,235,235,235,235,235,235,235,235,235,235,120,120,234,234,234, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, /* block 15 */ -235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, -235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235, -235,235,235,235,235,235,236,236,236,236,236,236,236,236,236,236, -236,235,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -237,237,237,237,237,237,237,237,237,237,238,238,238,238,238,238, -238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238, -238,238,238,238,238,238,238,238,238,238,238,239,239,239,239,239, -239,239,239,239,240,240,241,242,242,242,240,119,119,239,243,243, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236, +236,236,236,236,236,236,237,237,237,237,237,237,237,237,237,237, +237,236,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239, +239,239,239,239,239,239,239,239,239,239,239,240,240,240,240,240, +240,240,240,240,241,241,242,243,243,243,241,120,120,240,244,244, /* block 16 */ -244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244, -244,244,244,244,244,244,245,245,245,245,246,245,245,245,245,245, -245,245,245,245,246,245,245,245,246,245,245,245,245,245,119,119, -247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,119, -248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248, -248,248,248,248,248,248,248,248,248,249,249,249,119,119,250,119, -233,233,233,233,233,233,233,233,233,233,233,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245, +245,245,245,245,245,245,246,246,246,246,247,246,246,246,246,246, +246,246,246,246,247,246,246,246,247,246,246,246,246,246,120,120, +248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,120, +249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249, +249,249,249,249,249,249,249,249,249,250,250,250,120,120,251,120, +234,234,234,234,234,234,234,234,234,234,234,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 17 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,119,224,224,224,224,224,224,224,224,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,222,222,222,222,222,222,222,222,222,222,222,222,222, -222,222,216,222,222,222,222,222,222,222,222,222,222,222,222,222, -222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,120,225,225,225,225,225,225,225,225,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,217,223,223,223,223,223,223,223,223,223,223,223,223,223, +223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223, /* block 18 */ -251,251,251,252,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, -253,253,253,253,253,253,253,253,253,253,251,252,251,253,252,252, -252,251,251,251,251,251,251,251,251,252,252,252,252,251,252,252, -253,254,255,251,251,251,251,251,253,253,253,253,253,253,253,253, -253,253,251,251,256,257,258,258,258,258,258,258,258,258,258,258, -259,260,253,253,253,253,253,253,253,253,253,253,253,253,253,253, +252,252,252,253,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254, +254,254,254,254,254,254,254,254,254,254,252,253,252,254,253,253, +253,252,252,252,252,252,252,252,252,253,253,253,253,252,253,253, +254,255,256,113,113,252,252,252,254,254,254,254,254,254,254,254, +254,254,252,252,257,258,259,259,259,259,259,259,259,259,259,259, +260,261,254,254,254,254,254,254,254,254,254,254,254,254,254,254, /* block 19 */ -261,262,263,263,119,261,261,261,261,261,261,261,261,119,119,261, -261,119,119,261,261,261,261,261,261,261,261,261,261,261,261,261, -261,261,261,261,261,261,261,261,261,119,261,261,261,261,261,261, -261,119,261,119,119,119,261,261,261,261,119,119,262,261,264,263, -263,262,262,262,262,119,119,263,263,119,119,263,263,262,261,119, -119,119,119,119,119,119,119,264,119,119,119,119,261,261,119,261, -261,261,262,262,119,119,265,265,265,265,265,265,265,265,265,265, -261,261,266,266,267,267,267,267,267,267,268,266,261,269,262,119, +262,263,264,264,120,262,262,262,262,262,262,262,262,120,120,262, +262,120,120,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,120,262,262,262,262,262,262, +262,120,262,120,120,120,262,262,262,262,120,120,263,262,265,264, +264,263,263,263,263,120,120,264,264,120,120,264,264,263,262,120, +120,120,120,120,120,120,120,265,120,120,120,120,262,262,120,262, +262,262,263,263,120,120,266,266,266,266,266,266,266,266,266,266, +262,262,267,267,268,268,268,268,268,268,269,267,262,270,263,120, /* block 20 */ -119,270,270,271,119,272,272,272,272,272,272,119,119,119,119,272, -272,119,119,272,272,272,272,272,272,272,272,272,272,272,272,272, -272,272,272,272,272,272,272,272,272,119,272,272,272,272,272,272, -272,119,272,272,119,272,272,119,272,272,119,119,270,119,271,271, -271,270,270,119,119,119,119,270,270,119,119,270,270,270,119,119, -119,270,119,119,119,119,119,119,119,272,272,272,272,119,272,119, -119,119,119,119,119,119,273,273,273,273,273,273,273,273,273,273, -270,270,272,272,272,270,274,119,119,119,119,119,119,119,119,119, +120,271,271,272,120,273,273,273,273,273,273,120,120,120,120,273, +273,120,120,273,273,273,273,273,273,273,273,273,273,273,273,273, +273,273,273,273,273,273,273,273,273,120,273,273,273,273,273,273, +273,120,273,273,120,273,273,120,273,273,120,120,271,120,272,272, +272,271,271,120,120,120,120,271,271,120,120,271,271,271,120,120, +120,271,120,120,120,120,120,120,120,273,273,273,273,120,273,120, +120,120,120,120,120,120,274,274,274,274,274,274,274,274,274,274, +271,271,273,273,273,271,275,120,120,120,120,120,120,120,120,120, /* block 21 */ -119,275,275,276,119,277,277,277,277,277,277,277,277,277,119,277, -277,277,119,277,277,277,277,277,277,277,277,277,277,277,277,277, -277,277,277,277,277,277,277,277,277,119,277,277,277,277,277,277, -277,119,277,277,119,277,277,277,277,277,119,119,275,277,276,276, -276,275,275,275,275,275,119,275,275,276,119,276,276,275,119,119, -277,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -277,277,275,275,119,119,278,278,278,278,278,278,278,278,278,278, -279,280,119,119,119,119,119,119,119,277,275,275,275,275,275,275, +120,276,276,277,120,278,278,278,278,278,278,278,278,278,120,278, +278,278,120,278,278,278,278,278,278,278,278,278,278,278,278,278, +278,278,278,278,278,278,278,278,278,120,278,278,278,278,278,278, +278,120,278,278,120,278,278,278,278,278,120,120,276,278,277,277, +277,276,276,276,276,276,120,276,276,277,120,277,277,276,120,120, +278,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +278,278,276,276,120,120,279,279,279,279,279,279,279,279,279,279, +280,281,120,120,120,120,120,120,120,278,276,276,276,276,276,276, /* block 22 */ -119,281,282,282,119,283,283,283,283,283,283,283,283,119,119,283, -283,119,119,283,283,283,283,283,283,283,283,283,283,283,283,283, -283,283,283,283,283,283,283,283,283,119,283,283,283,283,283,283, -283,119,283,283,119,283,283,283,283,283,119,119,281,283,284,281, -282,281,281,281,281,119,119,282,282,119,119,282,282,281,119,119, -119,119,119,119,119,119,281,284,119,119,119,119,283,283,119,283, -283,283,281,281,119,119,285,285,285,285,285,285,285,285,285,285, -286,283,287,287,287,287,287,287,119,119,119,119,119,119,119,119, +120,282,283,283,120,284,284,284,284,284,284,284,284,120,120,284, +284,120,120,284,284,284,284,284,284,284,284,284,284,284,284,284, +284,284,284,284,284,284,284,284,284,120,284,284,284,284,284,284, +284,120,284,284,120,284,284,284,284,284,120,120,282,284,285,282, +283,282,282,282,282,120,120,283,283,120,120,283,283,282,120,120, +120,120,120,120,120,120,282,285,120,120,120,120,284,284,120,284, +284,284,282,282,120,120,286,286,286,286,286,286,286,286,286,286, +287,284,288,288,288,288,288,288,120,120,120,120,120,120,120,120, /* block 23 */ -119,119,288,289,119,289,289,289,289,289,289,119,119,119,289,289, -289,119,289,289,289,289,119,119,119,289,289,119,289,119,289,289, -119,119,119,289,289,119,119,119,289,289,289,119,119,119,289,289, -289,289,289,289,289,289,289,289,289,289,119,119,119,119,290,291, -288,291,291,119,119,119,291,291,291,119,291,291,291,288,119,119, -289,119,119,119,119,119,119,290,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,292,292,292,292,292,292,292,292,292,292, -293,293,293,294,295,295,295,295,295,296,295,119,119,119,119,119, +120,120,289,290,120,290,290,290,290,290,290,120,120,120,290,290, +290,120,290,290,290,290,120,120,120,290,290,120,290,120,290,290, +120,120,120,290,290,120,120,120,290,290,290,120,120,120,290,290, +290,290,290,290,290,290,290,290,290,290,120,120,120,120,291,292, +289,292,292,120,120,120,292,292,292,120,292,292,292,289,120,120, +290,120,120,120,120,120,120,291,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,293,293,293,293,293,293,293,293,293,293, +294,294,294,295,296,296,296,296,296,297,296,120,120,120,120,120, /* block 24 */ -297,298,298,298,297,299,299,299,299,299,299,299,299,119,299,299, -299,119,299,299,299,299,299,299,299,299,299,299,299,299,299,299, -299,299,299,299,299,299,299,299,299,119,299,299,299,299,299,299, -299,299,299,299,299,299,299,299,299,299,119,119,119,299,297,297, -297,298,298,298,298,119,297,297,297,119,297,297,297,297,119,119, -119,119,119,119,119,297,297,119,299,299,299,119,119,119,119,119, -299,299,297,297,119,119,300,300,300,300,300,300,300,300,300,300, -119,119,119,119,119,119,119,119,301,301,301,301,301,301,301,302, +298,299,299,299,298,300,300,300,300,300,300,300,300,120,300,300, +300,120,300,300,300,300,300,300,300,300,300,300,300,300,300,300, +300,300,300,300,300,300,300,300,300,120,300,300,300,300,300,300, +300,300,300,300,300,300,300,300,300,300,120,120,120,300,298,298, +298,299,299,299,299,120,298,298,298,120,298,298,298,298,120,120, +120,120,120,120,120,298,298,120,300,300,300,120,120,120,120,120, +300,300,298,298,120,120,301,301,301,301,301,301,301,301,301,301, +120,120,120,120,120,120,120,302,303,303,303,303,303,303,303,304, /* block 25 */ -303,304,305,305,306,303,303,303,303,303,303,303,303,119,303,303, -303,119,303,303,303,303,303,303,303,303,303,303,303,303,303,303, -303,303,303,303,303,303,303,303,303,119,303,303,303,303,303,303, -303,303,303,303,119,303,303,303,303,303,119,119,304,303,305,304, -305,305,307,305,305,119,304,305,305,119,305,305,304,304,119,119, -119,119,119,119,119,307,307,119,119,119,119,119,119,119,303,119, -303,303,304,304,119,119,308,308,308,308,308,308,308,308,308,308, -119,303,303,119,119,119,119,119,119,119,119,119,119,119,119,119, +305,306,307,307,308,305,305,305,305,305,305,305,305,120,305,305, +305,120,305,305,305,305,305,305,305,305,305,305,305,305,305,305, +305,305,305,305,305,305,305,305,305,120,305,305,305,305,305,305, +305,305,305,305,120,305,305,305,305,305,120,120,306,305,307,306, +307,307,309,307,307,120,306,307,307,120,307,307,306,306,120,120, +120,120,120,120,120,309,309,120,120,120,120,120,120,120,305,120, +305,305,306,306,120,120,310,310,310,310,310,310,310,310,310,310, +120,305,305,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 26 */ -309,309,310,310,119,311,311,311,311,311,311,311,311,119,311,311, -311,119,311,311,311,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, -311,311,311,311,311,311,311,311,311,311,311,309,309,311,312,310, -310,309,309,309,309,119,310,310,310,119,310,310,310,309,313,314, -119,119,119,119,311,311,311,312,315,315,315,315,315,315,315,311, -311,311,309,309,119,119,316,316,316,316,316,316,316,316,316,316, -315,315,315,315,315,315,315,315,315,314,311,311,311,311,311,311, +311,311,312,312,120,313,313,313,313,313,313,313,313,120,313,313, +313,120,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313, +313,313,313,313,313,313,313,313,313,313,313,311,311,313,314,312, +312,311,311,311,311,120,312,312,312,120,312,312,312,311,315,316, +120,120,120,120,313,313,313,314,317,317,317,317,317,317,317,313, +313,313,311,311,120,120,318,318,318,318,318,318,318,318,318,318, +317,317,317,317,317,317,317,317,317,316,313,313,313,313,313,313, /* block 27 */ -119,119,317,317,119,318,318,318,318,318,318,318,318,318,318,318, -318,318,318,318,318,318,318,119,119,119,318,318,318,318,318,318, -318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318, -318,318,119,318,318,318,318,318,318,318,318,318,119,318,119,119, -318,318,318,318,318,318,318,119,119,119,319,119,119,119,119,320, -317,317,319,319,319,119,319,119,317,317,317,317,317,317,317,320, -119,119,119,119,119,119,321,321,321,321,321,321,321,321,321,321, -119,119,317,317,322,119,119,119,119,119,119,119,119,119,119,119, +120,120,319,319,120,320,320,320,320,320,320,320,320,320,320,320, +320,320,320,320,320,320,320,120,120,120,320,320,320,320,320,320, +320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320, +320,320,120,320,320,320,320,320,320,320,320,320,120,320,120,120, +320,320,320,320,320,320,320,120,120,120,321,120,120,120,120,322, +319,319,321,321,321,120,321,120,319,319,319,319,319,319,319,322, +120,120,120,120,120,120,323,323,323,323,323,323,323,323,323,323, +120,120,319,319,324,120,120,120,120,120,120,120,120,120,120,120, /* block 28 */ -119,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323, -323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323, -323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323, -323,324,323,325,324,324,324,324,324,324,324,119,119,119,119, 6, -323,323,323,323,323,323,326,324,324,324,324,324,324,324,324,327, -328,328,328,328,328,328,328,328,328,328,327,327,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, +325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, +325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325, +325,326,325,327,326,326,326,326,326,326,326,120,120,120,120, 6, +325,325,325,325,325,325,328,326,326,326,326,326,326,326,326,329, +330,330,330,330,330,330,330,330,330,330,329,329,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 29 */ -119,329,329,119,329,119,119,329,329,119,329,119,119,329,119,119, -119,119,119,119,329,329,329,329,119,329,329,329,329,329,329,329, -119,329,329,329,119,329,119,329,119,119,329,329,119,329,329,329, -329,330,329,331,330,330,330,330,330,330,119,330,330,329,119,119, -329,329,329,329,329,119,332,119,330,330,330,330,330,330,119,119, -333,333,333,333,333,333,333,333,333,333,119,119,329,329,329,329, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,331,331,120,331,120,331,331,331,331,331,120,331,331,331,331, +331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331, +331,331,331,331,120,331,120,331,331,331,331,331,331,331,331,331, +331,332,331,333,332,332,332,332,332,332,332,332,332,331,120,120, +331,331,331,331,331,120,334,120,332,332,332,332,332,332,120,120, +335,335,335,335,335,335,335,335,335,335,120,120,331,331,331,331, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 30 */ -334,335,335,335,336,336,336,336,336,336,336,336,336,336,336,336, -336,336,336,335,336,335,335,335,337,337,335,335,335,335,335,335, -338,338,338,338,338,338,338,338,338,338,339,339,339,339,339,339, -339,339,339,339,335,337,335,337,335,337,340,341,340,341,342,342, -334,334,334,334,334,334,334,334,119,334,334,334,334,334,334,334, -334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334, -334,334,334,334,334,334,334,334,334,334,334,334,334,119,119,119, -119,337,337,337,337,337,337,337,337,337,337,337,337,337,337,342, +336,337,337,337,338,338,338,338,338,338,338,338,338,338,338,338, +338,338,338,337,338,337,337,337,339,339,337,337,337,337,337,337, +340,340,340,340,340,340,340,340,340,340,341,341,341,341,341,341, +341,341,341,341,337,339,337,339,337,339,342,343,342,343,344,344, +336,336,336,336,336,336,336,336,120,336,336,336,336,336,336,336, +336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336, +336,336,336,336,336,336,336,336,336,336,336,336,336,120,120,120, +120,339,339,339,339,339,339,339,339,339,339,339,339,339,339,344, /* block 31 */ -337,337,337,337,337,336,337,337,334,334,334,334,334,337,337,337, -337,337,337,337,337,337,337,337,119,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,119,335,335, -335,335,335,335,335,335,337,335,335,335,335,335,335,119,335,335, -336,336,336,336,336, 20, 20, 20, 20,336,336,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +339,339,339,339,339,338,339,339,336,336,336,336,336,339,339,339, +339,339,339,339,339,339,339,339,120,339,339,339,339,339,339,339, +339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339, +339,339,339,339,339,339,339,339,339,339,339,339,339,120,337,337, +337,337,337,337,337,337,339,337,337,337,337,337,337,120,337,337, +338,338,338,338,338, 20, 20, 20, 20,338,338,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 32 */ -343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343, -343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343, -343,343,343,343,343,343,343,343,343,343,343,344,344,345,345,345, -345,346,345,345,345,345,345,345,344,345,345,346,346,345,345,343, -347,347,347,347,347,347,347,347,347,347,348,348,348,348,348,348, -343,343,343,343,343,343,346,346,345,345,343,343,343,343,345,345, -345,343,344,344,344,343,343,344,344,344,344,344,344,344,343,343, -343,345,345,345,345,343,343,343,343,343,343,343,343,343,343,343, +345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345, +345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345, +345,345,345,345,345,345,345,345,345,345,345,346,346,347,347,347, +347,348,347,347,347,347,347,347,346,347,347,348,348,347,347,345, +349,349,349,349,349,349,349,349,349,349,350,350,350,350,350,350, +345,345,345,345,345,345,348,348,347,347,345,345,345,345,347,347, +347,345,346,346,346,345,345,346,346,346,346,346,346,346,345,345, +345,347,347,347,347,345,345,345,345,345,345,345,345,345,345,345, /* block 33 */ -343,343,345,344,346,345,345,344,344,344,344,344,344,345,343,344, -349,349,349,349,349,349,349,349,349,349,344,344,344,345,350,350, -351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351, -351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351, -351,351,351,351,351,351,119,351,119,119,119,119,119,351,119,119, -352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352, -352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352, -352,352,352,352,352,352,352,352,352,352,352,353,354,352,352,352, +345,345,347,346,348,347,347,346,346,346,346,346,346,347,345,346, +351,351,351,351,351,351,351,351,351,351,346,346,346,347,352,352, +353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353, +353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353, +353,353,353,353,353,353,120,353,120,120,120,120,120,353,120,120, +354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354, +354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354, +354,354,354,354,354,354,354,354,354,354,354,355,356,354,354,354, /* block 34 */ -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, -356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, - -/* block 35 */ -356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, -356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, -356,356,356,356,356,356,356,356,357,357,357,357,357,357,357,357, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, 357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, - -/* block 36 */ -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,119,358,358,358,358,119,119, -358,358,358,358,358,358,358,119,358,119,358,358,358,358,119,119, + +/* block 35 */ 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, 358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,358,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, + +/* block 36 */ +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120, +360,360,360,360,360,360,360,120,360,120,360,360,360,360,120,120, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, /* block 37 */ -358,358,358,358,358,358,358,358,358,119,358,358,358,358,119,119, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,119,358,358,358,358,119,119,358,358,358,358,358,358,358,119, -358,119,358,358,358,358,119,119,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,120, +360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, /* block 38 */ -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,119,358,358,358,358,119,119,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,358,358,358,358,119,119,359,359,359, -360,360,360,360,360,360,360,360,360,361,361,361,361,361,361,361, -361,361,361,361,361,361,361,361,361,361,361,361,361,119,119,119, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,360,360,360,360,120,120,361,361,361, +362,362,362,362,362,362,362,362,362,363,363,363,363,363,363,363, +363,363,363,363,363,363,363,363,363,363,363,363,363,120,120,120, /* block 39 */ -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -362,362,362,362,362,362,362,362,362,362,119,119,119,119,119,119, -363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, -363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, -363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, -363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, -363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, -364,364,364,364,364,364,119,119,365,365,365,365,365,365,119,119, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +364,364,364,364,364,364,364,364,364,364,120,120,120,120,120,120, +365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, +365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, +365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, +365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, +365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365, +366,366,366,366,366,366,120,120,367,367,367,367,367,367,120,120, /* block 40 */ -366,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +368,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, /* block 41 */ -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, /* block 42 */ -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,368,368,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,370,371,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, /* block 43 */ -369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, -370,370,370,370,370,370,370,370,370,370,370,371,372,119,119,119, -373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, -373,373,373,373,373,373,373,373,373,373,373, 5, 5, 5,374,374, -374,373,373,373,373,373,373,373,373,119,119,119,119,119,119,119, +372,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373,374,375,120,120,120, +376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, +376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, +376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, +376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376, +376,376,376,376,376,376,376,376,376,376,376, 5, 5, 5,377,377, +377,376,376,376,376,376,376,376,376,120,120,120,120,120,120,120, /* block 44 */ -375,375,375,375,375,375,375,375,375,375,375,375,375,119,375,375, -375,375,376,376,376,119,119,119,119,119,119,119,119,119,119,119, -377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377, -377,377,378,378,378,379,379,119,119,119,119,119,119,119,119,119, +378,378,378,378,378,378,378,378,378,378,378,378,378,120,378,378, +378,378,379,379,379,120,120,120,120,120,120,120,120,120,120,120, 380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, -380,380,381,381,119,119,119,119,119,119,119,119,119,119,119,119, -382,382,382,382,382,382,382,382,382,382,382,382,382,119,382,382, -382,119,383,383,119,119,119,119,119,119,119,119,119,119,119,119, +380,380,381,381,381,382,382,120,120,120,120,120,120,120,120,120, +383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383, +383,383,384,384,120,120,120,120,120,120,120,120,120,120,120,120, +385,385,385,385,385,385,385,385,385,385,385,385,385,120,385,385, +385,120,386,386,120,120,120,120,120,120,120,120,120,120,120,120, /* block 45 */ -384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, -384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, -384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, -384,384,384,384,385,385,386,385,385,385,385,385,385,385,386,386, -386,386,386,386,386,386,385,386,386,385,385,385,385,385,385,385, -385,385,385,385,387,387,387,388,387,387,387,389,384,385,119,119, -390,390,390,390,390,390,390,390,390,390,119,119,119,119,119,119, -391,391,391,391,391,391,391,391,391,391,119,119,119,119,119,119, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, +387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387, +387,387,387,387,388,388,389,388,388,388,388,388,388,388,389,389, +389,389,389,389,389,389,388,389,389,388,388,388,388,388,388,388, +388,388,388,388,390,390,390,391,390,390,390,392,387,388,120,120, +393,393,393,393,393,393,393,393,393,393,120,120,120,120,120,120, +394,394,394,394,394,394,394,394,394,394,120,120,120,120,120,120, /* block 46 */ -392,392,393,393,392,393,394,392,392,392,392,395,395,395,396,119, -397,397,397,397,397,397,397,397,397,397,119,119,119,119,119,119, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,399,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,119,119,119,119,119,119,119, +395,395,396,396,395,396,397,395,395,395,395,398,398,398,399,120, +400,400,400,400,400,400,400,400,400,400,120,120,120,120,120,120, +401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,402,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,120,120,120,120,120,120,120, /* block 47 */ -398,398,398,398,398,395,395,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, -398,398,398,398,398,398,398,398,398,395,398,119,119,119,119,119, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, -367,367,367,367,367,367,119,119,119,119,119,119,119,119,119,119, +401,401,401,401,401,398,398,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,398,401,120,120,120,120,120, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369, +369,369,369,369,369,369,120,120,120,120,120,120,120,120,120,120, /* block 48 */ -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400, -400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,119, -401,401,401,402,402,402,402,401,401,402,402,402,119,119,119,119, -402,402,401,402,402,402,402,402,402,401,401,401,119,119,119,119, -403,119,119,119,404,404,405,405,405,405,405,405,405,405,405,405, -406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406, -406,406,406,406,406,406,406,406,406,406,406,406,406,406,119,119, -406,406,406,406,406,119,119,119,119,119,119,119,119,119,119,119, +403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403, +403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,120, +404,404,404,405,405,405,405,404,404,405,405,405,120,120,120,120, +405,405,404,405,405,405,405,405,405,404,404,404,120,120,120,120, +406,120,120,120,407,407,408,408,408,408,408,408,408,408,408,408, +409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409, +409,409,409,409,409,409,409,409,409,409,409,409,409,409,120,120, +409,409,409,409,409,120,120,120,120,120,120,120,120,120,120,120, /* block 49 */ -407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407, -407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407, -407,407,407,407,407,407,407,407,407,407,407,407,119,119,119,119, -407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407, -407,407,407,407,407,407,407,407,407,407,119,119,119,119,119,119, -408,408,408,408,408,408,408,408,408,408,409,119,119,119,410,410, -411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411, -411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,410,410,120,120,120,120, +410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410, +410,410,410,410,410,410,410,410,410,410,120,120,120,120,120,120, +411,411,411,411,411,411,411,411,411,411,412,120,120,120,413,413, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, +414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414, /* block 50 */ -412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, -412,412,412,412,412,412,412,413,413,414,414,413,119,119,415,415, -416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, -416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, -416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, -416,416,416,416,416,417,418,417,418,418,418,418,418,418,418,119, -418,419,418,419,419,418,418,418,418,418,418,418,418,417,417,417, -417,417,417,418,418,418,418,418,418,418,418,418,418,119,119,418, +415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415, +415,415,415,415,415,415,415,416,416,417,417,416,120,120,418,418, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419, +419,419,419,419,419,420,421,420,421,421,421,421,421,421,421,120, +421,422,421,422,422,421,421,421,421,421,421,421,421,420,420,420, +420,420,420,421,421,421,421,421,421,421,421,421,421,120,120,421, /* block 51 */ -420,420,420,420,420,420,420,420,420,420,119,119,119,119,119,119, -420,420,420,420,420,420,420,420,420,420,119,119,119,119,119,119, -421,421,421,421,421,421,421,422,421,421,421,421,421,421,119,119, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,423,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120, +423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120, +424,424,424,424,424,424,424,425,424,424,424,424,424,424,120,120, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,426,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 52 */ -424,424,424,424,425,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, -426,426,426,426,424,425,424,424,424,424,424,425,424,425,425,425, -425,425,424,425,425,426,426,426,426,426,426,426,119,119,119,119, -427,427,427,427,427,427,427,427,427,427,428,428,428,428,428,428, -428,429,429,429,429,429,429,429,429,429,429,424,424,424,424,424, -424,424,424,424,429,429,429,429,429,429,429,429,429,119,119,119, +427,427,427,427,428,429,429,429,429,429,429,429,429,429,429,429, +429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429, +429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429, +429,429,429,429,427,430,427,427,427,427,427,428,427,428,428,428, +428,428,427,428,428,429,429,429,429,429,429,429,120,120,120,120, +431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432, +432,433,433,433,433,433,433,433,433,433,433,427,427,427,427,427, +427,427,427,427,433,433,433,433,433,433,433,433,433,120,120,120, /* block 53 */ -430,430,431,432,432,432,432,432,432,432,432,432,432,432,432,432, -432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, -432,431,430,430,430,430,431,431,430,430,431,430,430,430,432,432, -433,433,433,433,433,433,433,433,433,433,432,432,432,432,432,432, -434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434, -434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434, -434,434,434,434,434,434,435,436,435,435,436,436,436,435,436,435, -435,435,436,436,119,119,119,119,119,119,119,119,437,437,437,437, - -/* block 54 */ +434,434,435,436,436,436,436,436,436,436,436,436,436,436,436,436, +436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436, +436,435,434,434,434,434,435,435,434,434,435,434,434,434,436,436, +437,437,437,437,437,437,437,437,437,437,436,436,436,436,436,436, 438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, 438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, -438,438,438,438,439,439,439,439,439,439,439,439,440,440,440,440, -440,440,440,440,439,439,440,440,119,119,119,441,441,441,441,441, -442,442,442,442,442,442,442,442,442,442,119,119,119,438,438,438, -443,443,443,443,443,443,443,443,443,443,444,444,444,444,444,444, -444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444, -444,444,444,444,444,444,444,444,445,445,445,445,445,445,446,446, +438,438,438,438,438,438,439,440,439,439,440,440,440,439,440,439, +439,439,440,440,120,120,120,120,120,120,120,120,441,441,441,441, + +/* block 54 */ +442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442, +442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442, +442,442,442,442,443,443,443,443,443,443,443,443,444,444,444,444, +444,444,444,444,443,443,444,444,120,120,120,445,445,445,445,445, +446,446,446,446,446,446,446,446,446,446,120,120,120,442,442,442, +447,447,447,447,447,447,447,447,447,447,448,448,448,448,448,448, +448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448, +448,448,448,448,448,448,448,448,449,449,449,449,449,449,450,450, /* block 55 */ -447,448,449,450,451,452,453,454,455,119,119,119,119,119,119,119, -456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, -456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, -456,456,456,456,456,456,456,456,456,456,456,119,119,456,456,456, -457,457,457,457,457,457,457,457,119,119,119,119,119,119,119,119, -458,459,458,460,459,461,461,462,461,462,463,459,462,462,459,459, -462,464,459,459,459,459,459,459,459,465,466,465,465,461,465,465, -465,465,467,467,468,466,466,469,470,470,119,119,119,119,119,119, +451,452,453,454,455,456,457,458,459,120,120,120,120,120,120,120, +460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +460,460,460,460,460,460,460,460,460,460,460,120,120,460,460,460, +461,461,461,461,461,461,461,461,120,120,120,120,120,120,120,120, +462,463,462,464,463,465,465,466,465,466,467,463,466,466,463,463, +466,468,463,463,463,463,463,463,463,469,470,471,471,465,471,471, +471,471,472,473,474,470,470,475,476,476,477,120,120,120,120,120, /* block 56 */ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35,127,127,127,127,127,471,109,109,109,109, -109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, -109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, -109,109,109,109,109,109,109,109,109,109,109,109,109,120,120,120, -120,120,109,109,109,109,120,120,120,120,120, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35,472,473, 35, 35, 35,474, 35, 35, + 35, 35, 35, 35, 35, 35,128,128,128,128,128,478,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,121,121,121, +121,121,110,110,110,110,121,121,121,121,121, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35,479,480, 35, 35, 35,481, 35, 35, /* block 57 */ - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,109,109,109,109,109, -109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, -109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,120, -113,113,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,119,112,112,112,112,112, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,482, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110, +110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,121, +114,114,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,120,113,113,113,113,113, /* block 58 */ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, @@ -2251,12 +2286,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, -475,476, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, +483,484, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, /* block 59 */ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, - 32, 33, 32, 33, 32, 33, 35, 35, 35, 35, 35,477, 35, 35,478, 35, + 32, 33, 32, 33, 32, 33, 35, 35, 35, 35, 35,485, 35, 35,486, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, @@ -2265,58 +2300,58 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, /* block 60 */ -479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, -479,479,479,479,479,479,119,119,480,480,480,480,480,480,119,119, -479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, -479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, -479,479,479,479,479,479,119,119,480,480,480,480,480,480,119,119, -127,479,127,479,127,479,127,479,119,480,119,480,119,480,119,480, -479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, -481,481,482,482,482,482,483,483,484,484,485,485,486,486,119,119, +487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488, +487,487,487,487,487,487,120,120,488,488,488,488,488,488,120,120, +487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488, +487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488, +487,487,487,487,487,487,120,120,488,488,488,488,488,488,120,120, +128,487,128,487,128,487,128,487,120,488,120,488,120,488,120,488, +487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488, +489,489,490,490,490,490,491,491,492,492,493,493,494,494,120,120, /* block 61 */ -479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487, -479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487, -479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487, -479,479,127,488,127,119,127,127,480,480,489,489,490,118,491,118, -118,118,127,488,127,119,127,127,492,492,492,492,490,118,118,118, -479,479,127,127,119,119,127,127,480,480,493,493,119,118,118,118, -479,479,127,127,127,168,127,127,480,480,494,494,173,118,118,118, -119,119,127,488,127,119,127,127,495,495,496,496,490,118,118,119, +487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495, +487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495, +487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495, +487,487,128,496,128,120,128,128,488,488,497,497,498,119,499,119, +119,119,128,496,128,120,128,128,500,500,500,500,498,119,119,119, +487,487,128,128,120,120,128,128,488,488,501,501,120,119,119,119, +487,487,128,128,128,169,128,128,488,488,502,502,174,119,119,119, +120,120,128,496,128,120,128,128,503,503,504,504,498,119,119,120, /* block 62 */ - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24,497,498, 24, 24, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24,505,506, 24, 24, 10, 10, 10, 10, 10, 10, 5, 5, 23, 27, 7, 23, 23, 27, 7, 23, - 5, 5, 5, 5, 5, 5, 5, 5,499,500, 24, 24, 24, 24, 24, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 27, 5,501, 5, 5, 16, - 16, 5, 5, 5, 9, 7, 8, 5, 5,501, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5,507,508, 24, 24, 24, 24, 24,509, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 27, 5,510, 5, 5, 16, + 16, 5, 5, 5, 9, 7, 8, 5, 5,510, 5, 5, 5, 5, 5, 5, 5, 5, 9, 5, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, - 24, 24, 24, 24, 24,502, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25,109,119,119, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,109, + 24, 24, 24, 24, 24,511, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25,110,120,120, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,110, /* block 63 */ - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,119, -109,109,109,109,109,109,109,109,109,109,109,109,109,119,119,119, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,120, +110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -112,112,112,112,112,112,112,112,112,112,112,112,112,423,423,423, -423,112,423,423,423,112,112,112,112,112,112,112,112,112,112,112, -503,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +113,113,113,113,113,113,113,113,113,113,113,113,113,426,426,426, +426,113,426,426,426,113,113,113,113,113,113,113,113,113,113,113, +512,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 64 */ - 20, 20,504, 20, 20, 20, 20,504, 20, 20,505,504,504,504,505,505, -504,504,504,505, 20,504, 20, 20, 9,504,504,504,504,504, 20, 20, - 20, 20, 21, 20,504, 20,506, 20,504, 20,507,508,504,504, 20,505, -504,504,509,504,505,510,510,510,510,511, 20, 20,505,505,504,504, - 9, 9, 9, 9, 9,504,505,505,505,505, 20, 9, 20, 20,512, 20, + 20, 20,513, 20, 20, 20, 20,513, 20, 20,514,513,513,513,514,514, +513,513,513,514, 20,513, 20, 20, 9,513,513,513,513,513, 20, 20, + 20, 20, 21, 20,513, 20,515, 20,513, 20,516,517,513,513, 20,514, +513,513,518,513,514,519,519,519,519,520, 20, 20,514,514,513,513, + 9, 9, 9, 9, 9,513,514,514,514,514, 20, 9, 20, 20,521, 20, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, /* block 65 */ -515,515,515, 32, 33,515,515,515,515, 25, 20, 20,119,119,119,119, - 9, 9, 9, 9,516, 21, 21, 21, 21, 21, 9, 9, 20, 20, 20, 20, +524,524,524, 32, 33,524,524,524,524, 25, 20, 20,120,120,120,120, + 9, 9, 9, 9,525, 21, 21, 21, 21, 21, 9, 9, 20, 20, 20, 20, 9, 20, 20, 9, 20, 20, 9, 20, 20, 21, 21, 20, 20, 20, 9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 9, @@ -2357,10 +2392,10 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ /* block 69 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, @@ -2368,10 +2403,10 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20,517,517,517,517,517,517,517,517,517,517, -517,517,518,517,517,517,517,517,517,517,517,517,517,517,517,517, -519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, -519,519,519,519,519,519,519,519,519,519, 25, 25, 25, 25, 25, 25, + 20, 20, 20, 20, 20, 20,526,526,526,526,526,526,526,526,526,526, +526,526,527,526,526,526,526,526,526,526,526,526,526,526,526,526, +528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528, +528,528,528,528,528,528,528,528,528,528, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, /* block 71 */ @@ -2392,7 +2427,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 21, 9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 9, 9, 9,516,516,516,516, 9, + 20, 20, 20, 20, 20, 20, 20, 20, 9, 9, 9,525,525,525,525, 9, /* block 73 */ 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -2401,7 +2436,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,516, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,525, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, /* block 74 */ @@ -2435,20 +2470,20 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* block 77 */ -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, +529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529, /* block 78 */ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9,516,516, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,525,525, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -2472,167 +2507,167 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 9, 9, 9, 9, 9, 20, 20, 9, 9, 9, 9, 9, 9, 20, 20, 20, 21, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, /* block 81 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20,119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119, /* block 82 */ -521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, -521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, -521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,119, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,119, - 32, 33,523,524,525,526,527, 32, 33, 32, 33, 32, 33,528,529,530, -531, 35, 32, 33, 35, 32, 33, 35, 35, 35, 35, 35,109,109,532,532, +530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, +530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, +530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,120, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531, +531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,120, + 32, 33,532,533,534,535,536, 32, 33, 32, 33, 32, 33,537,538,539, +540, 35, 32, 33, 35, 32, 33, 35, 35, 35, 35, 35,110,110,541,541, /* block 83 */ -164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, -164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, -164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, -164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, -164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, -164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, -164,165,164,165,533,534,534,534,534,534,534,164,165,164,165,535, -535,535,164,165,119,119,119,119,119,536,536,536,536,537,536,536, +165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166, +165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166, +165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166, +165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166, +165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166, +165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166, +165,166,165,166,542,543,543,543,543,543,543,165,166,165,166,544, +544,544,165,166,120,120,120,120,120,545,545,545,545,546,545,545, /* block 84 */ -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,119,538,119,119,119,119,119,538,119,119, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, -539,539,539,539,539,539,539,539,119,119,119,119,119,119,119,540, -541,119,119,119,119,119,119,119,119,119,119,119,119,119,119,542, +547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547, +547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547, +547,547,547,547,547,547,120,547,120,120,120,120,120,547,120,120, +548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548, +548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548, +548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548, +548,548,548,548,548,548,548,548,120,120,120,120,120,120,120,549, +550,120,120,120,120,120,120,120,120,120,120,120,120,120,120,551, /* block 85 */ -358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, -358,358,358,358,358,358,358,119,119,119,119,119,119,119,119,119, -358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, -358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, -358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, -358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, -543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, +360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360, +360,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120, +360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, +360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, +360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, +360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, /* block 86 */ 5, 5, 23, 27, 23, 27, 5, 5, 5, 23, 27, 5, 23, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 10, 5, 23, 27, 5, 5, - 23, 27, 7, 8, 7, 8, 7, 8, 7, 8, 5, 5, 5, 5, 5,110, + 23, 27, 7, 8, 7, 8, 7, 8, 7, 8, 5, 5, 5, 5, 5,111, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 5, 5, 5, 5, - 10, 5, 7,544, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 10, 5, 7,553, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 87 */ -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,119,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,119,119,119,119,119,119,119,119,119,119,119,119, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,120,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,120,120,120,120,120,120,120,120,120,120,120,120, /* block 88 */ -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, /* block 89 */ -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, -545,545,545,545,545,545,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554, +554,554,554,554,554,554,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120, /* block 90 */ - 4,546,546,547, 20,548,549,550,551,552,551,552,551,552,551,552, -551,552, 20,553,551,552,551,552,551,552,551,552,554,555,556,556, - 20,550,550,550,550,550,550,550,550,550,557,557,557,557,558,558, -559,560,560,560,560,560, 20,553,550,550,550,548,561,562,563,563, -119,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, + 4,555,555,556, 20,557,558,559,560,561,560,561,560,561,560,561, +560,561, 20,562,560,561,560,561,560,561,560,561,563,564,565,565, + 20,559,559,559,559,559,559,559,559,559,566,566,566,566,567,567, +568,569,569,569,569,569, 20,562,559,559,559,557,570,571,572,572, +120,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, /* block 91 */ -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,119,119,565,565,566,566,567,567,564, -568,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, -569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, -569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, -569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, -569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, -569,569,569,569,569,569,569,569,569,569,569,546,560,570,570,569, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,120,120,574,574,575,575,576,576,573, +577,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +578,578,578,578,578,578,578,578,578,578,578,555,569,579,579,578, /* block 92 */ -119,119,119,119,119,571,571,571,571,571,571,571,571,571,571,571, -571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, -571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, -119,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, +120,120,120,120,120,580,580,580,580,580,580,580,580,580,580,580, +580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, +580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, +120,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, +581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, +581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, +581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, +581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, /* block 93 */ -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,119, -563,563,573,573,573,573,563,563,563,563,563,563,563,563,563,563, -571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, -571,571,571,571,571,571,571,571,571,571,571,119,119,119,119,119, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,119,119,119,119,119,119,119,119,119,119,119,119, -569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120, +572,572,582,582,582,582,572,572,572,572,572,572,572,572,572,572, +580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, +580,580,580,580,580,580,580,580,580,580,580,120,120,120,120,120, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, +572,572,572,572,120,120,120,120,120,120,120,120,120,120,120,120, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, /* block 94 */ -574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, -574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,119, -573,573,573,573,573,573,573,573,573,573,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,563,563, 25, 25, 25, 25, 25, 25, 25, 25, +583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583, +583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,120, +582,582,582,582,582,582,582,582,582,582,572,572,572,572,572,572, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, +572,572,572,572,572,572,572,572, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, -574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, 20, +583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583, +583,583,583,583,583,583,583,583,583,583,583,583,583,583,583, 20, /* block 95 */ -573,573,573,573,573,573,573,573,573,573,563,563,563,563,563,563, -563,563,563,563,563,563,563,575,563,575,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -563,563,563,563,563,563,563,563,563,563,563,563, 20, 20, 20, 20, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,119, +582,582,582,582,582,582,582,582,582,582,572,572,572,572,572,572, +572,572,572,572,572,572,572,584,572,584,572,572,572,572,572,572, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, +572, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +572,572,572,572,572,572,572,572,572,572,572,572, 20, 20, 20, 20, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,572, /* block 96 */ -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,563,563,563,563,563, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, +585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585, +585,585,585,585,585,585,585,585,572,572,572,572,572,572,572,572, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, +572, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,572,572,572,572,572, /* block 97 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -2641,1160 +2676,1190 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, -563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, 20, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, 20, /* block 98 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, /* block 99 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,119,119,119,119,119,119,119,119,119,119, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,120,120,120,120,120,120,120,120,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, /* block 100 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 101 */ -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,579,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,588,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, /* block 102 */ -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, -578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, +587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, /* block 103 */ -578,578,578,578,578,578,578,578,578,578,578,578,578,119,119,119, -580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, -580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, -580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580, -580,580,580,580,580,580,580,119,119,119,119,119,119,119,119,119, -581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, -581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, -581,581,581,581,581,581,581,581,582,582,582,582,582,582,583,583, +587,587,587,587,587,587,587,587,587,587,587,587,587,120,120,120, +589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589, +589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589, +589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589, +589,589,589,589,589,589,589,120,120,120,120,120,120,120,120,120, +590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590, +590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590, +590,590,590,590,590,590,590,590,591,591,591,591,591,591,592,592, /* block 104 */ -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, /* block 105 */ -584,584,584,584,584,584,584,584,584,584,584,584,585,586,586,586, -584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, -587,587,587,587,587,587,587,587,587,587,584,584,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -191,192,191,192,191,192,191,192,191,192,588,589,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,191,192,590,197, -199,199,199,591,543,543,543,543,543,543,543,543,543,543,591,472, +593,593,593,593,593,593,593,593,593,593,593,593,594,595,595,595, +593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593, +596,596,596,596,596,596,596,596,596,596,593,593,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +192,193,192,193,192,193,192,193,192,193,597,598,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,599,198, +200,200,200,600,552,552,552,552,552,552,552,552,552,552,600,479, /* block 106 */ -191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, -191,192,191,192,191,192,191,192,191,192,191,192,472,472,543,543, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,593,593,593,593,593,593,593,593,593,593, -594,594,595,595,595,595,595,595,119,119,119,119,119,119,119,119, +192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193, +192,193,192,193,192,193,192,193,192,193,192,193,479,479,552,552, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,602,602,602,602,602,602,602,602,602,602, +603,603,604,604,604,604,604,604,120,120,120,120,120,120,120,120, /* block 107 */ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15,110,110,110,110,110,110,110,110,110, + 15, 15, 15, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111, 15, 15, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 35, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, -109, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,596, 32, 33, +110, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,605, 32, 33, /* block 108 */ - 32, 33, 32, 33, 32, 33, 32, 33,110, 15, 15, 32, 33,597, 35, 22, - 32, 33, 32, 33, 35, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, - 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,598,599,600,601,598, 35, -602,603,604,605, 32, 33, 32, 33, 32, 33,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119, 22,109,109, 35, 22, 22, 22, 22, 22, + 32, 33, 32, 33, 32, 33, 32, 33,111, 15, 15, 32, 33,606, 35, 22, + 32, 33, 32, 33,607, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, + 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,608,609,610,611,608, 35, +612,613,614,615, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, +120,120, 32, 33,616,617,618,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120, 22,110,110, 35, 22, 22, 22, 22, 22, /* block 109 */ -606,606,607,606,606,606,607,606,606,606,606,607,606,606,606,606, -606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606, -606,606,606,608,608,607,607,608,609,609,609,609,119,119,119,119, -610,610,610,611,611,611,612,612,613,612,119,119,119,119,119,119, -614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614, -614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614, -614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614, -614,614,614,614,615,615,615,615,119,119,119,119,119,119,119,119, +619,619,620,619,619,619,620,619,619,619,619,620,619,619,619,619, +619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, +619,619,619,621,621,620,620,621,622,622,622,622,120,120,120,120, +623,623,623,624,624,624,625,625,626,625,120,120,120,120,120,120, +627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, +627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, +627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627, +627,627,627,627,628,628,628,628,120,120,120,120,120,120,120,120, /* block 110 */ -616,616,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, -617,617,617,617,616,616,616,616,616,616,616,616,616,616,616,616, -616,616,616,616,618,618,119,119,119,119,119,119,119,119,619,619, -620,620,620,620,620,620,620,620,620,620,119,119,119,119,119,119, -251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, -251,621,253,622,253,253,253,253,259,259,259,253,259,253,253,251, +629,629,630,630,630,630,630,630,630,630,630,630,630,630,630,630, +630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630, +630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630, +630,630,630,630,629,629,629,629,629,629,629,629,629,629,629,629, +629,629,629,629,631,631,120,120,120,120,120,120,120,120,632,632, +633,633,633,633,633,633,633,633,633,633,120,120,120,120,120,120, +252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252, +252,634,254,635,254,254,254,254,260,260,260,254,260,254,254,252, /* block 111 */ -623,623,623,623,623,623,623,623,623,623,624,624,624,624,624,624, -624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624, -624,624,624,624,624,624,625,625,625,625,625,625,625,625,626,627, -628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628, -628,628,628,628,628,628,628,629,629,629,629,629,629,629,629,629, -629,629,630,630,119,119,119,119,119,119,119,119,119,119,119,631, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,119,119,119, +636,636,636,636,636,636,636,636,636,636,637,637,637,637,637,637, +637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637, +637,637,637,637,637,637,638,638,638,638,638,638,638,638,639,640, +641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641, +641,641,641,641,641,641,641,642,642,642,642,642,642,642,642,642, +642,642,643,643,120,120,120,120,120,120,120,120,120,120,120,644, +357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, +357,357,357,357,357,357,357,357,357,357,357,357,357,120,120,120, /* block 112 */ -632,632,632,633,634,634,634,634,634,634,634,634,634,634,634,634, -634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634, -634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634, -634,634,634,632,633,633,632,632,632,632,633,633,632,633,633,633, -633,635,635,635,635,635,635,635,635,635,635,635,635,635,119,636, -637,637,637,637,637,637,637,637,637,637,119,119,119,119,635,635, -343,343,343,343,343,345,638,343,343,343,343,343,343,343,343,343, -349,349,349,349,349,349,349,349,349,349,343,343,343,343,343,119, +645,645,645,646,647,647,647,647,647,647,647,647,647,647,647,647, +647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647, +647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647, +647,647,647,645,646,646,645,645,645,645,646,646,645,645,646,646, +646,648,648,648,648,648,648,648,648,648,648,648,648,648,120,649, +650,650,650,650,650,650,650,650,650,650,120,120,120,120,648,648, +345,345,345,345,345,347,651,345,345,345,345,345,345,345,345,345, +351,351,351,351,351,351,351,351,351,351,345,345,345,345,345,120, /* block 113 */ -639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639, -639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639, -639,639,639,639,639,639,639,639,639,640,640,640,640,640,640,641, -641,640,640,641,641,640,640,119,119,119,119,119,119,119,119,119, -639,639,639,640,639,639,639,639,639,639,639,639,640,641,119,119, -642,642,642,642,642,642,642,642,642,642,119,119,643,643,643,643, -343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343, -638,343,343,343,343,343,343,350,350,350,343,344,345,344,343,343, +652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652, +652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652, +652,652,652,652,652,652,652,652,652,653,653,653,653,653,653,654, +654,653,653,654,654,653,653,120,120,120,120,120,120,120,120,120, +652,652,652,653,652,652,652,652,652,652,652,652,653,654,120,120, +655,655,655,655,655,655,655,655,655,655,120,120,656,656,656,656, +345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345, +651,345,345,345,345,345,345,352,352,352,345,346,347,346,345,345, /* block 114 */ -644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644, -644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644, -644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644, -645,644,645,645,645,644,644,645,645,644,644,644,644,644,645,645, -644,645,644,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,644,644,646,647,647, -648,648,648,648,648,648,648,648,648,648,648,649,650,650,649,649, -651,651,648,652,652,649,650,119,119,119,119,119,119,119,119,119, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +658,657,658,658,658,657,657,658,658,657,657,657,657,657,658,658, +657,658,657,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,657,657,659,660,660, +661,661,661,661,661,661,661,661,661,661,661,662,663,663,662,662, +664,664,661,665,665,662,663,120,120,120,120,120,120,120,120,120, /* block 115 */ -119,358,358,358,358,358,358,119,119,358,358,358,358,358,358,119, -119,358,358,358,358,358,358,119,119,119,119,119,119,119,119,119, -358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, +120,360,360,360,360,360,360,120,120,360,360,360,360,360,360,120, +120,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120, +360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 35,653, 35, 35, 35, 35, 35, 35, 35, 15,109,109,109,109, - 35, 35, 35, 35, 35,127,119,119,119,119,119,119,119,119,119,119, -654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, + 35, 35, 35,666, 35, 35, 35, 35, 35, 35, 35, 15,110,110,110,110, + 35, 35, 35, 35, 35,128, 35, 35,120,120,120,120,120,120,120,120, +667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, /* block 116 */ -654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, -654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, -654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, -654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, -648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, -648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648, -648,648,648,649,649,650,649,649,650,649,649,651,649,650,119,119, -655,655,655,655,655,655,655,655,655,655,119,119,119,119,119,119, +667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, +667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, +667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, +667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, +661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661, +661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661, +661,661,661,662,662,663,662,662,663,662,662,664,662,663,120,120, +668,668,668,668,668,668,668,668,668,668,120,120,120,120,120,120, /* block 117 */ -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, /* block 118 */ -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, /* block 119 */ -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, /* block 120 */ -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, /* block 121 */ -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, /* block 122 */ -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, /* block 123 */ -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, /* block 124 */ -657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657, -657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, -657,657,657,657,119,119,119,119,119,119,119,119,119,119,119,119, -356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, -356,356,356,356,356,356,356,119,119,119,119,357,357,357,357,357, -357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, -357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357, -357,357,357,357,357,357,357,357,357,357,357,357,119,119,119,119, +670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670, +670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670, +670,670,670,670,120,120,120,120,120,120,120,120,120,120,120,120, +358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,120,120,120,120,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, +359,359,359,359,359,359,359,359,359,359,359,359,120,120,120,120, /* block 125 */ -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, -658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, +671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, /* block 126 */ -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, /* block 127 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, /* block 128 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 129 */ - 35, 35, 35, 35, 35, 35, 35,119,119,119,119,119,119,119,119,119, -119,119,119,205,205,205,205,205,119,119,119,119,119,214,211,214, -214,214,214,214,214,214,214,214,214,660,214,214,214,214,214,214, -214,214,214,214,214,214,214,119,214,214,214,214,214,119,214,119, -214,214,119,214,214,119,214,214,214,214,214,214,214,214,214,214, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, + 35, 35, 35, 35, 35, 35, 35,120,120,120,120,120,120,120,120,120, +120,120,120,206,206,206,206,206,120,120,120,120,120,215,212,215, +215,215,215,215,215,215,215,215,215,673,215,215,215,215,215,215, +215,215,215,215,215,215,215,120,215,215,215,215,215,120,215,120, +215,215,120,215,215,120,215,215,215,215,215,215,215,215,215,215, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, /* block 130 */ -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,661,661,661,661,661,661,661,661,661,661,661,661,661,661, -661,661,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,674,674,674,674,674,674,674,674,674,674,674,674,674,674, +674,674,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, /* block 131 */ -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, /* block 132 */ -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224, 8, 7, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225, 8, 7, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, /* block 133 */ -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -119,119,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -224,224,662,224,224,224,224,224,224,224,224,224,219,663,119,119, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +120,120,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +225,225,675,225,225,225,225,225,225,225,225,225,220,676,120,120, /* block 134 */ -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, - 5, 5, 5, 5, 5, 5, 5, 7, 8, 5,119,119,119,119,119,119, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,543,543, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, + 5, 5, 5, 5, 5, 5, 5, 7, 8, 5,120,120,120,120,120,120, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,552,552, 5, 10, 10, 16, 16, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, - 8, 7, 8, 7, 8,547,547, 7, 8, 5, 5, 5, 5, 16, 16, 16, - 5, 5, 5,119, 5, 5, 5, 5, 10, 7, 8, 7, 8, 7, 8, 5, - 5, 5, 9, 10, 9, 9, 9,119, 5, 6, 5, 5,119,119,119,119, -224,224,224,224,224,119,224,224,224,224,224,224,224,224,224,224, + 8, 7, 8, 7, 8,556,556, 7, 8, 5, 5, 5, 5, 16, 16, 16, + 5, 5, 5,120, 5, 5, 5, 5, 10, 7, 8, 7, 8, 7, 8, 5, + 5, 5, 9, 10, 9, 9, 9,120, 5, 6, 5, 5,120,120,120,120, +225,225,225,225,225,120,225,225,225,225,225,225,225,225,225,225, /* block 135 */ -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,119,119, 24, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,120,120, 24, /* block 136 */ -119, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5, +120, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 5, 5, 9, 9, 9, 5, 5, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 5, 8, 15, 16, 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 7, 9, 8, 9, 7, - 8,546,551,552,546,546,569,569,569,569,569,569,569,569,569,569, -560,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, + 8,555,560,561,555,555,578,578,578,578,578,578,578,578,578,578, +569,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, /* block 137 */ -569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, -569,569,569,569,569,569,569,569,569,569,569,569,569,569,664,664, -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, -572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,119, -119,119,572,572,572,572,572,572,119,119,572,572,572,572,572,572, -119,119,572,572,572,572,572,572,119,119,572,572,572,119,119,119, - 6, 6, 9, 15, 20, 6, 6,119, 20, 9, 9, 9, 9, 20, 20,119, -502,502,502,502,502,502,502,502,502, 24, 24, 24, 20, 20,119,119, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,677,677, +581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581, +581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120, +120,120,581,581,581,581,581,581,120,120,581,581,581,581,581,581, +120,120,581,581,581,581,581,581,120,120,581,581,581,120,120,120, + 6, 6, 9, 15, 20, 6, 6,120, 20, 9, 9, 9, 9, 20, 20,120, +511,511,511,511,511,511,511,511,511, 24, 24, 24, 20, 20,120,120, /* block 138 */ -665,665,665,665,665,665,665,665,665,665,665,665,119,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,119,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,119,665,665,119,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,119,119, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +678,678,678,678,678,678,678,678,678,678,678,678,120,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,120,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,120,678,678,120,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 139 */ -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, -665,665,665,665,665,665,665,665,665,665,665,119,119,119,119,119, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,678,678,678,678,678,678,678,678,678,678,120,120,120,120,120, /* block 140 */ -666,666,666,119,119,119,119,667,667,667,667,667,667,667,667,667, -667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, -667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667, -667,667,667,667,119,119,119,668,668,668,668,668,668,668,668,668, -669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669, -669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669, -669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669, -669,669,669,669,669,670,670,670,670,671,671,671,671,671,671,671, +679,679,679,120,120,120,120,680,680,680,680,680,680,680,680,680, +680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680, +680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680, +680,680,680,680,120,120,120,681,681,681,681,681,681,681,681,681, +682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682, +682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682, +682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682, +682,682,682,682,682,683,683,683,683,684,684,684,684,684,684,684, /* block 141 */ -671,671,671,671,671,671,671,671,671,671,670,670,671,671,671,119, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119, -671,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +684,684,684,684,684,684,684,684,684,684,683,683,684,684,684,120, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120, +684,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,112,119,119, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,120,120, /* block 142 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 143 */ -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,119,119,119, -673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, -673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, -673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, -673,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -674,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675, -675,675,675,675,675,675,675,675,675,675,675,675,119,119,119,119, +685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685, +685,685,685,685,685,685,685,685,685,685,685,685,685,120,120,120, +686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686, +686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686, +686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686, +686,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +687,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688, +688,688,688,688,688,688,688,688,688,688,688,688,120,120,120,120, /* block 144 */ -676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676, -676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676, -677,677,677,677,119,119,119,119,119,119,119,119,119,676,676,676, -678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, -678,679,678,678,678,678,678,678,678,678,679,119,119,119,119,119, -680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680, -680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680, -680,680,680,680,680,680,681,681,681,681,681,119,119,119,119,119, +689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, +689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, +690,690,690,690,120,120,120,120,120,120,120,120,120,689,689,689, +691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691, +691,692,691,691,691,691,691,691,691,691,692,120,120,120,120,120, +693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693, +693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693, +693,693,693,693,693,693,694,694,694,694,694,120,120,120,120,120, /* block 145 */ -682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682, -682,682,682,682,682,682,682,682,682,682,682,682,682,682,119,683, -684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, -684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, -684,684,684,684,119,119,119,119,684,684,684,684,684,684,684,684, -685,686,686,686,686,686,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695, +695,695,695,695,695,695,695,695,695,695,695,695,695,695,120,696, +697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, +697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, +697,697,697,697,120,120,120,120,697,697,697,697,697,697,697,697, +698,699,699,699,699,699,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 146 */ -687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687, -687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687, -687,687,687,687,687,687,687,687,688,688,688,688,688,688,688,688, -688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688, -688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688, -689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, -689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, -689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, +700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700, +700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700, +700,700,700,700,700,700,700,700,701,701,701,701,701,701,701,701, +701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701, +701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701, +702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702, +702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702, +702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702, /* block 147 */ -690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690, -690,690,690,690,690,690,690,690,690,690,690,690,690,690,119,119, -691,691,691,691,691,691,691,691,691,691,119,119,119,119,119,119, -692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692, -692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692, -692,692,692,692,119,119,119,119,693,693,693,693,693,693,693,693, -693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693, -693,693,693,693,693,693,693,693,693,693,693,693,119,119,119,119, +703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703, +703,703,703,703,703,703,703,703,703,703,703,703,703,703,120,120, +704,704,704,704,704,704,704,704,704,704,120,120,120,120,120,120, +705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705, +705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705, +705,705,705,705,120,120,120,120,706,706,706,706,706,706,706,706, +706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706, +706,706,706,706,706,706,706,706,706,706,706,706,120,120,120,120, /* block 148 */ -694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694, -694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694, -694,694,694,694,694,694,694,694,119,119,119,119,119,119,119,119, -695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695, -695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695, -695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695, -695,695,695,695,119,119,119,119,119,119,119,119,119,119,119,696, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +707,707,707,707,707,707,707,707,120,120,120,120,120,120,120,120, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,120,120,120,120,120,120,120,120,120,120,120,709, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 149 */ -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, /* block 150 */ -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,697,119,119,119,119,119,119,119,119,119, -697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, -697,697,697,697,697,697,119,119,119,119,119,119,119,119,119,119, -697,697,697,697,697,697,697,697,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,710,120,120,120,120,120,120,120,120,120, +710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710, +710,710,710,710,710,710,120,120,120,120,120,120,120,120,120,120, +710,710,710,710,710,710,710,710,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 151 */ -698,698,698,698,698,698,119,119,698,119,698,698,698,698,698,698, -698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698, -698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698, -698,698,698,698,698,698,119,698,698,119,119,119,698,119,119,698, -699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699, -699,699,699,699,699,699,119,700,701,701,701,701,701,701,701,701, -702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702, -702,702,702,702,702,702,702,703,703,704,704,704,704,704,704,704, +711,711,711,711,711,711,120,120,711,120,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711, +711,711,711,711,711,711,120,711,711,120,120,120,711,120,120,711, +712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712, +712,712,712,712,712,712,120,713,714,714,714,714,714,714,714,714, +715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715, +715,715,715,715,715,715,715,716,716,717,717,717,717,717,717,717, /* block 152 */ -705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705, -705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,119, -119,119,119,119,119,119,119,706,706,706,706,706,706,706,706,706, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,119,707,707,119,119,119,119,119,708,708,708,708,708, +718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718, +718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,120, +120,120,120,120,120,120,120,719,719,719,719,719,719,719,719,719, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720, +720,720,720,120,720,720,120,120,120,120,120,721,721,721,721,721, /* block 153 */ -709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709, -709,709,709,709,709,709,710,710,710,710,710,710,119,119,119,711, -712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712, -712,712,712,712,712,712,712,712,712,712,119,119,119,119,119,713, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722, +722,722,722,722,722,722,723,723,723,723,723,723,120,120,120,724, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,120,120,120,120,120,726, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 154 */ -714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714, -714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714, -715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715, -715,715,715,715,715,715,715,715,119,119,119,119,716,716,715,715, -716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716, -119,119,716,716,716,716,716,716,716,716,716,716,716,716,716,716, -716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716, -716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716, +727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727, +727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727, +728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728, +728,728,728,728,728,728,728,728,120,120,120,120,729,729,728,728, +729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729, +120,120,729,729,729,729,729,729,729,729,729,729,729,729,729,729, +729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729, +729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729, /* block 155 */ -717,718,718,718,119,718,718,119,119,119,119,119,718,718,718,718, -717,717,717,717,119,717,717,717,119,717,717,717,717,717,717,717, -717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717, -717,717,717,717,717,717,119,119,718,718,718,119,119,119,119,718, -719,719,719,719,719,719,719,719,719,119,119,119,119,119,119,119, -720,720,720,720,720,720,720,720,720,119,119,119,119,119,119,119, -721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721, -721,721,721,721,721,721,721,721,721,721,721,721,721,722,722,723, +730,731,731,731,120,731,731,120,120,120,120,120,731,731,731,731, +730,730,730,730,120,730,730,730,120,730,730,730,730,730,730,730, +730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730, +730,730,730,730,730,730,120,120,731,731,731,120,120,120,120,731, +732,732,732,732,732,732,732,732,732,120,120,120,120,120,120,120, +733,733,733,733,733,733,733,733,733,120,120,120,120,120,120,120, +734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734, +734,734,734,734,734,734,734,734,734,734,734,734,734,735,735,736, /* block 156 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,725,725,725, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -726,726,726,726,726,726,726,726,727,726,726,726,726,726,726,726, -726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, -726,726,726,726,726,728,728,119,119,119,119,729,729,729,729,729, -730,730,730,730,730,730,730,119,119,119,119,119,119,119,119,119, +737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737, +737,737,737,737,737,737,737,737,737,737,737,737,737,738,738,738, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +739,739,739,739,739,739,739,739,740,739,739,739,739,739,739,739, +739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739, +739,739,739,739,739,741,741,120,120,120,120,742,742,742,742,742, +743,743,743,743,743,743,743,120,120,120,120,120,120,120,120,120, /* block 157 */ -731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731, -731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731, -731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731, -731,731,731,731,731,731,119,119,119,732,732,732,732,732,732,732, -733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733, -733,733,733,733,733,733,119,119,734,734,734,734,734,734,734,734, -735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735, -735,735,735,119,119,119,119,119,736,736,736,736,736,736,736,736, +744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, +744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, +744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, +744,744,744,744,744,744,120,120,120,745,745,745,745,745,745,745, +746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746, +746,746,746,746,746,746,120,120,747,747,747,747,747,747,747,747, +748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748, +748,748,748,120,120,120,120,120,749,749,749,749,749,749,749,749, /* block 158 */ -737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737, -737,737,119,119,119,119,119,119,119,738,738,738,738,119,119,119, -119,119,119,119,119,119,119,119,119,739,739,739,739,739,739,739, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750, +750,750,120,120,120,120,120,120,120,751,751,751,751,120,120,120, +120,120,120,120,120,120,120,120,120,752,752,752,752,752,752,752, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 159 */ -740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, -740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, -740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, -740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, -740,740,740,740,740,740,740,740,740,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, +753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, +753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, +753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, +753,753,753,753,753,753,753,753,753,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 160 */ -741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741, -741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741, -741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741, -741,741,741,119,119,119,119,119,119,119,119,119,119,119,119,119, -742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742, -742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742, -742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742, -742,742,742,119,119,119,119,119,119,119,743,743,743,743,743,743, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,120,120,120,120,120,120,120,120,120,120,120,120,120, +755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755, +755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755, +755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755, +755,755,755,120,120,120,120,120,120,120,756,756,756,756,756,756, /* block 161 */ -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,745,745,745,745,119,119,119,119,119,119,119,119, -746,746,746,746,746,746,746,746,746,746,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, +757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, +757,757,757,757,758,758,758,758,120,120,120,120,120,120,120,120, +759,759,759,759,759,759,759,759,759,759,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 162 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747, -747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760, +760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,120, /* block 163 */ -748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748, -748,748,748,748,748,748,748,748,748,748,748,748,748,749,749,749, -749,749,749,749,749,749,749,748,119,119,119,119,119,119,119,119, -750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750, -750,750,750,750,750,750,751,751,751,751,751,751,751,751,751,751, -751,752,752,752,752,753,753,753,753,753,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761, +761,761,761,761,761,761,761,761,761,761,761,761,761,762,762,762, +762,762,762,762,762,762,762,761,120,120,120,120,120,120,120,120, +763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, +763,763,763,763,763,763,764,764,764,764,764,764,764,764,764,764, +764,765,765,765,765,766,766,766,766,766,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 164 */ -754,755,754,756,756,756,756,756,756,756,756,756,756,756,756,756, -756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756, -756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756, -756,756,756,756,756,756,756,756,755,755,755,755,755,755,755,755, -755,755,755,755,755,755,755,757,757,757,757,757,757,757,119,119, -119,119,758,758,758,758,758,758,758,758,758,758,758,758,758,758, -758,758,758,758,758,758,759,759,759,759,759,759,759,759,759,759, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,755, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,767,120,120,120,120,120,120,120,120,120, /* block 165 */ -760,760,761,762,762,762,762,762,762,762,762,762,762,762,762,762, -762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762, -762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762, -761,761,761,760,760,760,760,761,761,760,760,763,763,764,763,763, -763,763,119,119,119,119,119,119,119,119,119,119,119,764,119,119, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,119,119,119,119,119,119,119, -766,766,766,766,766,766,766,766,766,766,119,119,119,119,119,119, +768,769,768,770,770,770,770,770,770,770,770,770,770,770,770,770, +770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770, +770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770, +770,770,770,770,770,770,770,770,769,769,769,769,769,769,769,769, +769,769,769,769,769,769,769,771,771,771,771,771,771,771,120,120, +120,120,772,772,772,772,772,772,772,772,772,772,772,772,772,772, +772,772,772,772,772,772,773,773,773,773,773,773,773,773,773,773, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,769, /* block 166 */ -767,767,767,768,768,768,768,768,768,768,768,768,768,768,768,768, -768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768, -768,768,768,768,768,768,768,767,767,767,767,767,769,767,767,767, -767,767,767,767,767,119,770,770,770,770,770,770,770,770,770,770, -771,771,771,771,768,769,769,119,119,119,119,119,119,119,119,119, -772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772, -772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772, -772,772,772,773,774,774,772,119,119,119,119,119,119,119,119,119, +774,774,775,776,776,776,776,776,776,776,776,776,776,776,776,776, +776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776, +776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776, +775,775,775,774,774,774,774,775,775,774,774,777,777,778,777,777, +777,777,120,120,120,120,120,120,120,120,120,120,120,778,120,120, +779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779, +779,779,779,779,779,779,779,779,779,120,120,120,120,120,120,120, +780,780,780,780,780,780,780,780,780,780,120,120,120,120,120,120, /* block 167 */ -775,775,776,777,777,777,777,777,777,777,777,777,777,777,777,777, -777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777, -777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777, -777,777,777,776,776,776,775,775,775,775,775,775,775,775,775,776, -776,777,778,778,777,779,779,779,779,775,775,775,775,779,119,119, -780,780,780,780,780,780,780,780,780,780,777,779,777,779,779,779, -119,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, -781,781,781,781,781,119,119,119,119,119,119,119,119,119,119,119, +781,781,781,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,782,782,782,782,782,781,781,781,781,781,783,781,781,781, +781,781,781,781,781,120,784,784,784,784,784,784,784,784,784,784, +785,785,785,785,782,783,783,120,120,120,120,120,120,120,120,120, +786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786, +786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786, +786,786,786,787,788,788,786,120,120,120,120,120,120,120,120,120, /* block 168 */ -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,119,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,783,783,783,784, -784,784,783,783,784,783,784,784,785,785,785,785,785,785,784,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +789,789,790,791,791,791,791,791,791,791,791,791,791,791,791,791, +791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791, +791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791, +791,791,791,790,790,790,789,789,789,789,789,789,789,789,789,790, +790,791,792,792,791,793,793,793,793,789,789,789,789,793,120,120, +794,794,794,794,794,794,794,794,794,794,791,793,791,793,793,793, +120,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795, +795,795,795,795,795,120,120,120,120,120,120,120,120,120,120,120, /* block 169 */ -786,786,786,786,786,786,786,119,786,119,786,786,786,786,119,786, -786,786,786,786,786,786,786,786,786,786,786,786,786,786,119,786, -786,786,786,786,786,786,786,786,786,787,119,119,119,119,119,119, -788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, -788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, -788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,789, -790,790,790,789,789,789,789,789,789,789,789,119,119,119,119,119, -791,791,791,791,791,791,791,791,791,791,119,119,119,119,119,119, +796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796, +796,796,120,796,796,796,796,796,796,796,796,796,796,796,796,796, +796,796,796,796,796,796,796,796,796,796,796,796,797,797,797,798, +798,798,797,797,798,797,798,798,799,799,799,799,799,799,798,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 170 */ -792,793,794,795,119,796,796,796,796,796,796,796,796,119,119,796, -796,119,119,796,796,796,796,796,796,796,796,796,796,796,796,796, -796,796,796,796,796,796,796,796,796,119,796,796,796,796,796,796, -796,119,796,796,119,796,796,796,796,796,119,797,793,796,798,794, -792,794,794,794,794,119,119,794,794,119,119,794,794,794,119,119, -796,119,119,119,119,119,119,798,119,119,119,119,119,796,796,796, -796,796,794,794,119,119,792,792,792,792,792,792,792,119,119,119, -792,792,792,792,792,119,119,119,119,119,119,119,119,119,119,119, +800,800,800,800,800,800,800,120,800,120,800,800,800,800,120,800, +800,800,800,800,800,800,800,800,800,800,800,800,800,800,120,800, +800,800,800,800,800,800,800,800,800,801,120,120,120,120,120,120, +802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802, +802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802, +802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,803, +804,804,804,803,803,803,803,803,803,803,803,120,120,120,120,120, +805,805,805,805,805,805,805,805,805,805,120,120,120,120,120,120, /* block 171 */ -799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799, -799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799, -799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799, -799,799,799,799,799,800,800,800,801,801,801,801,801,801,801,801, -800,800,801,801,801,800,801,799,799,799,799,802,802,802,802,802, -803,803,803,803,803,803,803,803,803,803,119,802,119,802,801,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +806,807,808,809,120,810,810,810,810,810,810,810,810,120,120,810, +810,120,120,810,810,810,810,810,810,810,810,810,810,810,810,810, +810,810,810,810,810,810,810,810,810,120,810,810,810,810,810,810, +810,120,810,810,120,810,810,810,810,810,120,811,807,810,812,808, +806,808,808,808,808,120,120,808,808,120,120,808,808,808,120,120, +810,120,120,120,120,120,120,812,120,120,120,120,120,810,810,810, +810,810,808,808,120,120,806,806,806,806,806,806,806,120,120,120, +806,806,806,806,806,120,120,120,120,120,120,120,120,120,120,120, /* block 172 */ -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -805,806,806,807,807,807,807,807,807,806,807,806,806,805,806,807, -807,806,807,807,804,804,808,804,119,119,119,119,119,119,119,119, -809,809,809,809,809,809,809,809,809,809,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, +813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, +813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813, +813,813,813,813,813,814,814,814,815,815,815,815,815,815,815,815, +814,814,815,815,815,814,815,813,813,813,813,816,816,816,816,816, +817,817,817,817,817,817,817,817,817,817,120,816,120,816,815,813, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 173 */ -810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810, -810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810, -810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,811, -812,812,813,813,813,813,119,119,812,812,812,812,813,813,812,813, -813,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814, -814,814,814,814,814,814,814,814,810,810,810,810,813,813,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, +818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, +818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, +819,820,820,821,821,821,821,821,821,820,821,820,820,819,820,821, +821,820,821,821,818,818,822,818,120,120,120,120,120,120,120,120, +823,823,823,823,823,823,823,823,823,823,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 174 */ -815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815, -815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815, -815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815, -816,816,816,817,817,817,817,817,817,817,817,816,816,817,816,817, -817,818,818,818,815,119,119,119,119,119,119,119,119,119,119,119, -819,819,819,819,819,819,819,819,819,819,119,119,119,119,119,119, -392,392,392,392,392,392,392,392,392,392,392,392,392,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,825, +826,826,827,827,827,827,120,120,826,826,826,826,827,827,826,827, +827,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, +828,828,828,828,828,828,828,828,824,824,824,824,827,827,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 175 */ -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,821,822,821,822,822, -821,821,821,821,821,821,822,821,119,119,119,119,119,119,119,119, -823,823,823,823,823,823,823,823,823,823,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +830,830,830,831,831,831,831,831,831,831,831,830,830,831,830,831, +831,832,832,832,829,120,120,120,120,120,120,120,120,120,120,120, +833,833,833,833,833,833,833,833,833,833,120,120,120,120,120,120, +395,395,395,395,395,395,395,395,395,395,395,395,395,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 176 */ -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,119,119,825,825,825, -826,826,825,825,825,825,826,825,825,825,825,825,119,119,119,119, -827,827,827,827,827,827,827,827,827,827,828,828,829,829,829,830, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,835,836,835,836,836, +835,835,835,835,835,835,836,835,834,120,120,120,120,120,120,120, +837,837,837,837,837,837,837,837,837,837,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 177 */ -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,832,832,832,833, -833,833,833,833,833,833,833,833,832,833,833,834,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,120,120,839,839,839, +840,840,839,839,839,839,840,839,839,839,839,839,120,120,120,120, +841,841,841,841,841,841,841,841,841,841,842,842,843,843,843,844, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 178 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835, -835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835, -836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, -836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, -837,837,837,837,837,837,837,837,837,837,838,838,838,838,838,838, -838,838,838,119,119,119,119,119,119,119,119,119,119,119,119,839, - -/* block 179 */ -840,841,841,841,841,841,841,841,841,841,841,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, -840,840,840,841,841,841,841,841,841,842,843,841,841,841,841,844, -844,844,844,844,844,844,844,841,119,119,119,119,119,119,119,119, -845,846,846,846,846,846,846,847,847,846,846,846,845,845,845,845, 845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, 845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845, +845,845,845,845,845,845,845,845,845,845,845,845,846,846,846,847, +847,847,847,847,847,847,847,847,846,847,847,848,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 180 */ -845,845,845,845,119,119,848,848,848,848,846,846,846,846,846,846, -846,846,846,846,846,846,846,847,846,846,849,849,849,845,849,849, -849,849,849,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850, +/* block 179 */ +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, +849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, 850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850, 850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850, -850,850,850,850,850,850,850,850,850,119,119,119,119,119,119,119, +851,851,851,851,851,851,851,851,851,851,852,852,852,852,852,852, +852,852,852,120,120,120,120,120,120,120,120,120,120,120,120,853, + +/* block 180 */ +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +854,854,854,854,854,854,854,854,120,120,854,854,854,854,854,854, +854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854, +854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854, +854,855,855,855,856,856,856,856,120,120,856,856,855,855,855,855, +856,854,857,854,855,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 181 */ -851,851,851,851,851,851,851,851,851,119,851,851,851,851,851,851, -851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851, -851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,852, -853,853,853,853,853,853,853,119,853,853,853,853,853,853,852,853, -851,854,854,854,854,854,119,119,119,119,119,119,119,119,119,119, -855,855,855,855,855,855,855,855,855,855,856,856,856,856,856,856, -856,856,856,856,856,856,856,856,856,856,856,856,856,119,119,119, -857,857,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,859,859,859,859,859,859,859,859,859,859,858,858,858,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,859,859,859,859,859,859,860,861,859,859,859,859,862, +862,862,862,862,862,862,862,859,120,120,120,120,120,120,120,120, +863,864,864,864,864,864,864,865,865,864,864,864,863,863,863,863, +863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863, +863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863, /* block 182 */ -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -119,119,859,859,859,859,859,859,859,859,859,859,859,859,859,859, -859,859,859,859,859,859,859,859,119,860,859,859,859,859,859,859, -859,860,859,859,860,859,859,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +863,863,863,863,866,866,866,866,866,866,864,864,864,864,864,864, +864,864,864,864,864,864,864,865,864,864,867,867,867,863,867,867, +867,867,867,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868, +868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868, +868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868, +868,868,868,868,868,868,868,868,868,120,120,120,120,120,120,120, /* block 183 */ -861,861,861,861,861,861,861,119,861,861,119,861,861,861,861,861, -861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861, -861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861, -861,862,862,862,862,862,862,119,119,119,862,119,862,862,119,862, -862,862,862,862,862,862,863,862,119,119,119,119,119,119,119,119, -864,864,864,864,864,864,864,864,864,864,119,119,119,119,119,119, -865,865,865,865,865,865,119,865,865,119,865,865,865,865,865,865, -865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865, +869,869,869,869,869,869,869,869,869,120,869,869,869,869,869,869, +869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,869, +869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,870, +871,871,871,871,871,871,871,120,871,871,871,871,871,871,870,871, +869,872,872,872,872,872,120,120,120,120,120,120,120,120,120,120, +873,873,873,873,873,873,873,873,873,873,874,874,874,874,874,874, +874,874,874,874,874,874,874,874,874,874,874,874,874,120,120,120, +875,875,876,876,876,876,876,876,876,876,876,876,876,876,876,876, /* block 184 */ -865,865,865,865,865,865,865,865,865,865,866,866,866,866,866,119, -867,867,119,866,866,867,866,867,865,119,119,119,119,119,119,119, -868,868,868,868,868,868,868,868,868,868,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, +120,120,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,120,878,877,877,877,877,877,877, +877,878,877,877,878,877,877,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 185 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,869, -869,869,869,870,870,871,871,872,872,119,119,119,119,119,119,119, +879,879,879,879,879,879,879,120,879,879,120,879,879,879,879,879, +879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879, +879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879, +879,880,880,880,880,880,880,120,120,120,880,120,880,880,120,880, +880,880,880,880,880,880,881,880,120,120,120,120,120,120,120,120, +882,882,882,882,882,882,882,882,882,882,120,120,120,120,120,120, +883,883,883,883,883,883,120,883,883,120,883,883,883,883,883,883, +883,883,883,883,883,883,883,883,883,883,883,883,883,883,883,883, /* block 186 */ -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +883,883,883,883,883,883,883,883,883,883,884,884,884,884,884,120, +885,885,120,884,884,885,884,885,883,120,120,120,120,120,120,120, +886,886,886,886,886,886,886,886,886,886,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 187 */ -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +887,887,887,887,887,887,887,887,887,887,887,887,887,887,887,887, +887,887,887,888,888,889,889,890,890,120,120,120,120,120,120,120, /* block 188 */ -874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, -874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, -874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, -874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, -874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, -874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, -874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,119, -875,875,875,875,875,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +294,294,891,294,891,296,296,296,296,296,296,296,296,297,297,297, +297,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, +296,296,120,120,120,120,120,120,120,120,120,120,120,120,120,892, /* block 189 */ -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, -873,873,873,873,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, /* block 190 */ -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 191 */ -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, -876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, +894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, +894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, +894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, +894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, +894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894, +894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,120, +895,895,895,895,895,120,120,120,120,120,120,120,120,120,120,120, /* block 192 */ -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 193 */ -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, -877,877,877,877,877,877,877,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, /* block 194 */ -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, +896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,120, +897,897,897,897,897,897,897,897,897,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 195 */ -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,119,119,119,119,119,119,119, -878,878,878,878,878,878,878,878,878,878,878,878,878,878,878,878, -878,878,878,878,878,878,878,878,878,878,878,878,878,878,878,119, -879,879,879,879,879,879,879,879,879,879,119,119,119,119,880,880, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, /* block 196 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881, -881,881,881,881,881,881,881,881,881,881,881,881,881,881,119,119, -882,882,882,882,882,883,119,119,119,119,119,119,119,119,119,119, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898, +898,898,898,898,898,898,898,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 197 */ -884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, -884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, -884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, -885,885,885,885,885,885,885,886,886,886,886,886,887,887,887,887, -888,888,888,888,886,887,119,119,119,119,119,119,119,119,119,119, -889,889,889,889,889,889,889,889,889,889,119,890,890,890,890,890, -890,890,119,884,884,884,884,884,884,884,884,884,884,884,884,884, -884,884,884,884,884,884,884,884,119,119,119,119,119,884,884,884, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, /* block 198 */ -884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601, +601,601,601,601,601,601,601,601,601,120,120,120,120,120,120,120, +899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,899, +899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,120, +900,900,900,900,900,900,900,900,900,900,120,120,120,120,901,901, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 199 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, -892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892, -892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, +902,902,902,902,902,902,902,902,902,902,902,902,902,902,120,120, +903,903,903,903,903,904,120,120,120,120,120,120,120,120,120,120, /* block 200 */ -893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, -893,893,893,893,893,893,893,894,894,894,894,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, +905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, +905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, +906,906,906,906,906,906,906,907,907,907,907,907,908,908,908,908, +909,909,909,909,907,908,120,120,120,120,120,120,120,120,120,120, +910,910,910,910,910,910,910,910,910,910,120,911,911,911,911,911, +911,911,120,905,905,905,905,905,905,905,905,905,905,905,905,905, +905,905,905,905,905,905,905,905,120,120,120,120,120,905,905,905, /* block 201 */ -895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, -895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, -895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, -895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, -895,895,895,895,895,119,119,119,119,119,119,119,119,119,119,119, -895,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896, -896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,119, +905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 202 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,897, -897,897,897,898,898,898,898,898,898,898,898,898,898,898,898,898, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -899,900,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, +912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, +913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, +913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913, /* block 203 */ -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914, +914,914,914,914,914,914,914,915,915,915,915,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 204 */ -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, +916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, +916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, +916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916, +916,916,916,916,916,916,916,916,916,916,916,120,120,120,120,917, +916,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, +918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, /* block 205 */ -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, -901,901,901,119,119,119,119,119,119,119,119,119,119,119,119,119, +918,918,918,918,918,918,918,918,120,120,120,120,120,120,120,917, +917,917,917,919,919,919,919,919,919,919,919,919,919,919,919,919, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +920,921, 5,111,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 206 */ -569,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, /* block 207 */ -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,120,120,120,120,120,120,120,120, /* block 208 */ -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922, +922,922,922,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 209 */ -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, +578,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, /* block 210 */ -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, -902,902,902,902,902,902,902,902,902,902,902,902,119,119,119,119, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, /* block 211 */ -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, -903,903,903,903,903,903,903,903,903,903,903,119,119,119,119,119, -903,903,903,903,903,903,903,903,903,903,903,903,903,119,119,119, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +573,573,573,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,578,578,578,578,120,120,120,120,120,120,120,120, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, /* block 212 */ -903,903,903,903,903,903,903,903,903,119,119,119,119,119,119,119, -903,903,903,903,903,903,903,903,903,903,119,119,904,905,905,906, -907,907,907,907,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, /* block 213 */ +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,120,120,120,120, + +/* block 214 */ +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, +924,924,924,924,924,924,924,924,924,924,924,120,120,120,120,120, +924,924,924,924,924,924,924,924,924,924,924,924,924,120,120,120, + +/* block 215 */ +924,924,924,924,924,924,924,924,924,120,120,120,120,120,120,120, +924,924,924,924,924,924,924,924,924,924,120,120,925,926,926,927, +928,928,928,928,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 216 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -3802,309 +3867,339 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119,119, + 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,120, -/* block 214 */ +/* block 217 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20,908,909,112,112,112, 20, 20, 20,909,908,908, -908,908,908, 24, 24, 24, 24, 24, 24, 24, 24,112,112,112,112,112, + 20, 20, 20, 20, 20,929,930,113,113,113, 20, 20, 20,930,929,929, +929,929,929, 24, 24, 24, 24, 24, 24, 24, 24,113,113,113,113,113, -/* block 215 */ -112,112,112, 20, 20,112,112,112,112,112,112,112, 20, 20, 20, 20, +/* block 218 */ +113,113,113, 20, 20,113,113,113,113,113,113,113, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,112,112,112,112, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,113,113,113, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 216 */ -671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, -671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, -671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, -671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671, -671,671,910,910,910,671,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +/* block 219 */ +684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, +684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, +684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, +684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684, +684,684,931,931,931,684,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 217 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +/* block 220 */ +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25,119,119,119,119,119,119,119,119,119,119,119,119, + 25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120,120, -/* block 218 */ +/* block 221 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119, -573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, -573,573, 25, 25, 25, 25, 25, 25, 25,119,119,119,119,119,119,119, - -/* block 219 */ -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,505,505, -505,505,505,505,505,119,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, - -/* block 220 */ -504,504,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,504,119,504,504, -119,119,504,119,119,504,504,119,119,504,504,504,504,119,504,504, -504,504,504,504,504,504,505,505,505,505,119,505,119,505,505,505, -505,505,505,505,119,505,505,505,505,505,505,505,505,505,505,505, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, - -/* block 221 */ -505,505,505,505,504,504,119,504,504,504,504,119,119,504,504,504, -504,504,504,504,504,119,504,504,504,504,504,504,504,119,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,504,504,119,504,504,504,504,119, -504,504,504,504,504,119,504,119,119,119,504,504,504,504,504,504, -504,119,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, + 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120, +582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582, +582,582, 25, 25, 25, 25, 25, 25, 25,120,120,120,120,120,120,120, /* block 222 */ -504,504,504,504,504,504,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,514,514, +514,514,514,514,514,120,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, /* block 223 */ -505,505,505,505,505,505,505,505,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,513,120,513,513, +120,120,513,120,120,513,513,120,120,513,513,513,513,120,513,513, +513,513,513,513,513,513,514,514,514,514,120,514,120,514,514,514, +514,514,514,514,120,514,514,514,514,514,514,514,514,514,514,514, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, /* block 224 */ -504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,119,119,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504, 9,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505, 9,505,505,505,505, -505,505,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504, 9,505,505,505,505, +514,514,514,514,513,513,120,513,513,513,513,120,120,513,513,513, +513,513,513,513,513,120,513,513,513,513,513,513,513,120,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,513,513,120,513,513,513,513,120, +513,513,513,513,513,120,513,120,120,120,513,513,513,513,513,513, +513,120,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, /* block 225 */ -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505, 9,505,505,505,505,505,505,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504, 9,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, 9, -505,505,505,505,505,505,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, 9, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +513,513,513,513,513,513,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, /* block 226 */ -505,505,505,505,505,505,505,505,505, 9,505,505,505,505,505,505, -504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, -504,504,504,504,504,504,504,504,504, 9,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505, 9,505,505,505,505,505,505,504,505,119,119, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, /* block 227 */ -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, -911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,120,120,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513, 9,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514, 9,514,514,514,514, +514,514,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513, 9,514,514,514,514, /* block 228 */ -912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -912,912,912,912,912,912,912,911,911,911,911,912,912,912,912,912, -912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -912,912,912,912,912,912,912,912,912,912,912,912,912,911,911,911, -911,911,911,911,911,912,911,911,911,911,911,911,911,911,911,911, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514, 9,514,514,514,514,514,514,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513, 9,514,514,514,514,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 9, +514,514,514,514,514,514,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 9, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, /* block 229 */ -911,911,911,911,912,911,911,913,913,913,913,913,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,912,912,912,912,912, -119,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +514,514,514,514,514,514,514,514,514, 9,514,514,514,514,514,514, +513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, +513,513,513,513,513,513,513,513,513, 9,514,514,514,514,514,514, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,514, 9,514,514,514,514,514,514,513,514,120,120, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, /* block 230 */ -914,914,914,914,914,914,914,119,914,914,914,914,914,914,914,914, -914,914,914,914,914,914,914,914,914,119,119,914,914,914,914,914, -914,914,119,914,914,119,914,914,914,914,914,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, +932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932, /* block 231 */ -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, +933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, +933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, +933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, +933,933,933,933,933,933,933,932,932,932,932,933,933,933,933,933, +933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, +933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, +933,933,933,933,933,933,933,933,933,933,933,933,933,932,932,932, +932,932,932,932,932,933,932,932,932,932,932,932,932,932,932,932, /* block 232 */ -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915, -915,915,915,915,915,119,119,916,916,916,916,916,916,916,916,916, -917,917,917,917,917,917,917,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +932,932,932,932,933,932,932,934,934,934,934,934,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,933,933,933,933,933, +120,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 233 */ -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918, -918,918,919,919,919,919,919,919,919,919,919,919,919,919,919,919, -919,919,919,919,919,919,919,919,919,919,919,919,919,919,919,919, -919,919,919,919,920,920,920,920,920,920,920,119,119,119,119,119, -921,921,921,921,921,921,921,921,921,921,119,119,119,119,922,922, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +935,935,935,935,935,935,935,120,935,935,935,935,935,935,935,935, +935,935,935,935,935,935,935,935,935,120,120,935,935,935,935,935, +935,935,120,935,935,120,935,935,935,935,935,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 234 */ -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936, +936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936, +936,936,936,936,936,936,936,936,936,936,936,936,936,120,120,120, +937,937,937,937,937,937,937,938,938,938,938,938,938,938,120,120, +939,939,939,939,939,939,939,939,939,939,120,120,120,120,936,940, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 235 */ - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25, - 6, 25, 25, 25, 25,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941, +941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941, +941,941,941,941,941,941,941,941,941,941,941,941,942,942,942,942, +943,943,943,943,943,943,943,943,943,943,120,120,120,120,120,944, /* block 236 */ -224,224,224,224,119,224,224,224,224,224,224,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, -119,224,224,119,224,119,119,224,119,224,224,224,224,224,224,224, -224,224,224,119,224,224,224,224,119,224,119,224,119,119,119,119, -119,119,224,119,119,119,119,224,119,224,119,224,119,224,224,224, -119,224,224,119,224,119,119,224,119,224,119,224,119,224,119,224, -119,224,224,119,224,119,119,224,224,224,224,119,224,224,224,224, -224,224,224,119,224,224,224,224,119,224,224,224,224,119,224,119, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, /* block 237 */ -224,224,224,224,224,224,224,224,224,224,119,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,119,119,119,119, -119,224,224,224,119,224,224,224,224,224,119,224,224,224,224,224, -224,224,224,224,224,224,224,224,224,224,224,224,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -217,217,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,120,120,946,946,946,946,946,946,946,946,946, +947,947,947,947,947,947,947,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 238 */ +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948, +948,948,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,950,950,950,950,950,950,950,951,120,120,120,120, +952,952,952,952,952,952,952,952,952,952,120,120,120,120,953,953, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 239 */ +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + +/* block 240 */ + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25, + 6, 25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 241 */ +120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 242 */ +225,225,225,225,120,225,225,225,225,225,225,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225, +120,225,225,120,225,120,120,225,120,225,225,225,225,225,225,225, +225,225,225,120,225,225,225,225,120,225,120,225,120,120,120,120, +120,120,225,120,120,120,120,225,120,225,120,225,120,225,225,225, +120,225,225,120,225,120,120,225,120,225,120,225,120,225,120,225, +120,225,225,120,225,120,120,225,225,225,225,120,225,225,225,225, +225,225,225,120,225,225,225,225,120,225,225,225,225,120,225,120, + +/* block 243 */ +225,225,225,225,225,225,225,225,225,225,120,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120, +120,225,225,225,120,225,225,225,225,225,120,225,225,225,225,225, +225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +218,218,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 244 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -/* block 239 */ +/* block 245 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923, -923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954, +954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, -/* block 240 */ - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,923,923,923, +/* block 246 */ + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,954,954,954, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,954,954,954, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, -/* block 241 */ +/* block 247 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,924,924,924,924,924,924,924,924,924,924, -924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,955,955,955,955,955,955,955,955,955,955, +955,955,955,955,955,955,955,955,955,955,955,955,955,955,955,955, -/* block 242 */ -925, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923, +/* block 248 */ +956, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, - 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,923,923,923,923, - 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923, -575,575,923,923,923,923,923,923,923,923,923,923,923,923,923,923, - 21, 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, + 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,954,954,954,954, + 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954, +584,584,954,954,954,954,954,954,954,954,954,954,954,954,954,954, + 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -/* block 243 */ -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +/* block 249 */ +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -/* block 244 */ +/* block 250 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4114,7 +4209,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -/* block 245 */ +/* block 251 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4122,9 +4217,9 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,926,926,926,926,926, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,957,957,957,957,957, -/* block 246 */ +/* block 252 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4134,7 +4229,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, -/* block 247 */ +/* block 253 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4144,17 +4239,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -/* block 248 */ +/* block 254 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,954, -/* block 249 */ +/* block 255 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, @@ -4162,187 +4257,197 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20,923,923,923,923,923,923,923,923,923,923,923,923, + 20, 20, 20, 20,954,954,954,954,954,954,954,954,954,954,954,954, -/* block 250 */ +/* block 256 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 21, 21, 21, 21,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, + 20, 20, 20, 20, 20, 21, 21, 21, 21,954,954,954,954,954,954,954, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -/* block 251 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923, +/* block 257 */ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923,923, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923, + 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -/* block 252 */ - 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923,923, +/* block 258 */ + 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, -/* block 253 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923, +/* block 259 */ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21,923,923, 21, 21, 21, 21,923,923,923, 21,923, 21, 21, 21, 21, + 21, 21,954, 21, 21, 21, 21,954,954,954, 21, 21, 21, 21, 21, 21, -/* block 254 */ +/* block 260 */ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923,923,923, - 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21,954,954, 21, 21, 21, 21, 21, 21,954,954,954, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - -/* block 255 */ -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, - -/* block 256 */ -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, -923,923,923,923,923,923,923,923,923,923,923,923,923,923,119,119, - -/* block 257 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, - -/* block 258 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,119,119,119,119,119,119,119,119,119,119,119, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, - -/* block 259 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, - -/* block 260 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, /* block 261 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954, + 21, 21, 21, 21,954,954,954,954, 21, 21, 21,954,954,954,954,954, /* block 262 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, -119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954, + 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, /* block 263 */ -502, 24,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, -927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, -927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, -927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, -927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, -927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954, +954,954,954,954,954,954,954,954,954,954,954,954,954,954,120,120, /* block 264 */ -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, /* block 265 */ -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,120,120,120,120,120,120,120,120,120,120,120, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, /* block 266 */ -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, /* block 267 */ -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, -659,659,659,659,659,659,659,659,659,659,659,659,659,659,119,119, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, + +/* block 268 */ +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 269 */ +586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, +586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, +120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120, + +/* block 270 */ +511, 24,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, +958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, +958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, +958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, +958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, +958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, + +/* block 271 */ +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, + +/* block 272 */ +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, + +/* block 273 */ +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113, +511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511, + +/* block 274 */ +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,120,120, }; diff --git a/ext/pcre/pcre2lib/pcre2_ucp.h b/ext/pcre/pcre2lib/pcre2_ucp.h index 483abd18fc29e..84b22fb06494c 100644 --- a/ext/pcre/pcre2lib/pcre2_ucp.h +++ b/ext/pcre/pcre2lib/pcre2_ucp.h @@ -281,7 +281,12 @@ enum { ucp_Makasar, ucp_Medefaidrin, ucp_Old_Sogdian, - ucp_Sogdian + ucp_Sogdian, + /* New for Unicode 12.0.0 */ + ucp_Elymaic, + ucp_Nandinagari, + ucp_Nyiakeng_Puachue_Hmong, + ucp_Wancho }; #endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */ diff --git a/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h b/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h index ba60311e45423..acba9da4be4d8 100644 --- a/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h +++ b/ext/pcre/pcre2lib/sljit/sljitConfigInternal.h @@ -214,6 +214,10 @@ #define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len) #endif +#ifndef SLJIT_MEMMOVE +#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len) +#endif + #ifndef SLJIT_ZEROMEM #define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len) #endif diff --git a/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c b/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c index 7d9684c9cbb88..92ddb94914382 100644 --- a/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c +++ b/ext/pcre/pcre2lib/sljit/sljitExecAllocator.c @@ -114,26 +114,23 @@ static SLJIT_INLINE int get_map_jit_flag() /* The following code is thread safe because multiple initialization sets map_jit_flag to the same value and the code has no side-effects. - Changing the kernel version without system restart is (very) unlikely. */ + Changing the kernel version witout system restart is (very) unlikely. */ if (map_jit_flag == -1) { struct utsname name; + map_jit_flag = 0; uname(&name); /* Kernel version for 10.14.0 (Mojave) */ if (atoi(name.release) >= 18) { - /* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible - with fork(). */ - void *ptr = mmap( - NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + /* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */ + void *ptr = mmap(NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if (ptr == MAP_FAILED) { map_jit_flag = MAP_JIT; } else { - map_jit_flag = 0; munmap(ptr, getpagesize()); } - } else { - map_jit_flag = 0; } } @@ -150,6 +147,7 @@ static SLJIT_INLINE int get_map_jit_flag() static SLJIT_INLINE void* alloc_chunk(sljit_uw size) { void *retval; + const int prot = PROT_READ | PROT_WRITE | PROT_EXEC; #ifdef MAP_ANON @@ -159,16 +157,25 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size) flags |= get_map_jit_flag(); #endif - retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0); + retval = mmap(NULL, size, prot, flags, -1, 0); #else /* !MAP_ANON */ if (dev_zero < 0) { if (open_dev_zero()) return NULL; } - retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0); + retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0); #endif /* MAP_ANON */ - return (retval != MAP_FAILED) ? retval : NULL; + if (retval == MAP_FAILED) + retval = NULL; + else { + if (mprotect(retval, size, prot) < 0) { + munmap(retval, size); + retval = NULL; + } + } + + return retval; } static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) @@ -358,7 +365,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) free_block = free_blocks; while (free_block) { next_free_block = free_block->next; - if (!free_block->header.prev_size && + if (!free_block->header.prev_size && AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { total_size -= free_block->size; sljit_remove_free_block(free_block); diff --git a/ext/pcre/pcre2lib/sljit/sljitLir.c b/ext/pcre/pcre2lib/sljit/sljitLir.c index 725d10ec938da..9bab0c3ec66ba 100644 --- a/ext/pcre/pcre2lib/sljit/sljitLir.c +++ b/ext/pcre/pcre2lib/sljit/sljitLir.c @@ -144,6 +144,7 @@ #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) # define PATCH_MD 0x10 #endif +# define TYPE_SHIFT 13 #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) @@ -325,7 +326,7 @@ #elif (defined SLJIT_DEBUG && SLJIT_DEBUG) -/* Assertion failure occurs if an invalid argument is passed. */ +/* Assertion failure occures if an invalid argument is passed. */ #undef SLJIT_ARGUMENT_CHECKS #define SLJIT_ARGUMENT_CHECKS 1 @@ -521,6 +522,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw } } +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label) +{ + if (SLJIT_LIKELY(!!put_label)) + put_label->label = label; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags) { SLJIT_UNUSED_ARG(compiler); @@ -620,6 +627,30 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types) return arg_count; } +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump, + struct sljit_const *const_, struct sljit_put_label *put_label) +{ + sljit_uw result = ~(sljit_uw)0; + + if (label) + result = label->size; + + if (jump && jump->addr < result) + result = jump->addr; + + if (const_ && const_->addr < result) + result = const_->addr; + + if (put_label && put_label->addr < result) + result = put_label->addr; + + return result; +} + +#endif /* !SLJIT_CONFIG_X86 */ + static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) @@ -687,6 +718,19 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp compiler->last_const = const_; } +static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset) +{ + put_label->next = NULL; + put_label->label = NULL; + put_label->addr = compiler->size - offset; + put_label->flags = 0; + if (compiler->last_put_label) + compiler->last_put_label->next = put_label; + else + compiler->put_labels = put_label; + compiler->last_put_label = put_label; +} + #define ADDRESSING_DEPENDS_ON(exp, reg) \ (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg)) @@ -1905,6 +1949,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil CHECK_RETURN_OK; } +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + FUNCTION_CHECK_DST(dst, dstw, 0); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " put_label "); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ @@ -2581,6 +2640,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return NULL; } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + return NULL; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { SLJIT_UNUSED_ARG(addr); @@ -2597,4 +2664,4 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta SLJIT_UNREACHABLE(); } -#endif +#endif /* !SLJIT_CONFIG_UNSUPPORTED */ diff --git a/ext/pcre/pcre2lib/sljit/sljitLir.h b/ext/pcre/pcre2lib/sljit/sljitLir.h index e71890cf7bcc9..836d25cf71a53 100644 --- a/ext/pcre/pcre2lib/sljit/sljitLir.h +++ b/ext/pcre/pcre2lib/sljit/sljitLir.h @@ -348,13 +348,20 @@ struct sljit_label { struct sljit_jump { struct sljit_jump *next; sljit_uw addr; - sljit_sw flags; + sljit_uw flags; union { sljit_uw target; - struct sljit_label* label; + struct sljit_label *label; } u; }; +struct sljit_put_label { + struct sljit_put_label *next; + struct sljit_label *label; + sljit_uw addr; + sljit_uw flags; +}; + struct sljit_const { struct sljit_const *next; sljit_uw addr; @@ -366,10 +373,12 @@ struct sljit_compiler { struct sljit_label *labels; struct sljit_jump *jumps; + struct sljit_put_label *put_labels; struct sljit_const *consts; struct sljit_label *last_label; struct sljit_jump *last_jump; struct sljit_const *last_const; + struct sljit_put_label *last_put_label; void *allocator_data; struct sljit_memory_fragment *buf; @@ -1314,10 +1323,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil Flags: - (may destroy flags) */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset); -/* The constant can be changed runtime (see: sljit_set_const) +/* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const) Flags: - (does not modify flags) */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value); +/* Store the value of a label (see: sljit_set_put_label) + Flags: - (does not modify flags) */ +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); + +/* Set the value stored by put_label to this label. */ +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label); + /* After the code generation the address for label, jump and const instructions are computed. Since these structures are freed by sljit_free_compiler, the addresses must be preserved by the user program elsewere. */ diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c index 6d61eed9a7db0..71f7bcdadbef8 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_32.c @@ -583,8 +583,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_uw *buf_end; sljit_uw size; sljit_uw word_count; + sljit_uw next_addr; sljit_sw executable_offset; - sljit_sw jump_addr; + sljit_sw addr; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw cpool_size; sljit_uw cpool_skip_alignment; @@ -597,6 +598,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; + struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -625,11 +627,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + next_addr = 1; executable_offset = SLJIT_EXEC_OFFSET(code); label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + put_label = compiler->put_labels; if (label && label->size == 0) { label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); @@ -669,35 +673,45 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil else if ((*buf_ptr & 0xff000000) != PUSH_POOL) { #endif *code_ptr = *buf_ptr++; + if (next_addr == word_count) { + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + /* These structures are ordered by their address. */ - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - if (jump && jump->addr == word_count) { + if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (detect_jump_type(jump, code_ptr, code, executable_offset)) - code_ptr--; - jump->addr = (sljit_uw)code_ptr; + if (detect_jump_type(jump, code_ptr, code, executable_offset)) + code_ptr--; + jump->addr = (sljit_uw)code_ptr; #else - jump->addr = (sljit_uw)(code_ptr - 2); - if (detect_jump_type(jump, code_ptr, code, executable_offset)) - code_ptr -= 2; + jump->addr = (sljit_uw)(code_ptr - 2); + if (detect_jump_type(jump, code_ptr, code, executable_offset)) + code_ptr -= 2; #endif - jump = jump->next; - } - if (label && label->size == word_count) { - /* code_ptr can be affected above. */ - label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset); - label->size = (code_ptr + 1) - code; - label = label->next; - } - if (const_ && const_->addr == word_count) { + jump = jump->next; + } + if (label && label->size == word_count) { + /* code_ptr can be affected above. */ + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset); + label->size = (code_ptr + 1) - code; + label = label->next; + } + if (const_ && const_->addr == word_count) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - const_->addr = (sljit_uw)code_ptr; + const_->addr = (sljit_uw)code_ptr; #else - const_->addr = (sljit_uw)(code_ptr - 1); + const_->addr = (sljit_uw)(code_ptr - 1); #endif - const_ = const_->next; + const_ = const_->next; + } + if (put_label && put_label->addr == word_count) { + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)code_ptr; + put_label = put_label->next; + } + next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr++; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) @@ -725,6 +739,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); + SLJIT_ASSERT(!put_label); #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) SLJIT_ASSERT(cpool_size == 0); @@ -755,15 +770,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil buf_ptr = (sljit_uw *)jump->addr; if (jump->flags & PATCH_B) { - jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); + addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); if (!(jump->flags & JUMP_ADDR)) { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff; + SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - addr) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.label->addr - addr) >> 2) & 0x00ffffff; } else { - SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff; + SLJIT_ASSERT(((sljit_sw)jump->u.target - addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - addr) >= -0x02000000); + *buf_ptr |= (((sljit_sw)jump->u.target - addr) >> 2) & 0x00ffffff; } } else if (jump->flags & SLJIT_REWRITABLE_JUMP) { @@ -813,6 +828,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } #endif + put_label = compiler->put_labels; + while (put_label) { + addr = put_label->label->addr; + buf_ptr = (sljit_uw*)put_label->addr; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000); + buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr; +#else + SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT); + buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff); + buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff); +#endif + put_label = put_label->next; + } + SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size); compiler->error = SLJIT_ERR_COMPILED; @@ -2639,28 +2670,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_s32 reg; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); ADJUST_LOCAL_OFFSET(dst, dstw); + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2; + +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), init_value)); + compiler->patches++; +#else + PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value)); +#endif + const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); + set_const(const_, compiler); - reg = SLOW_IS_REG(dst) ? dst : TMP_REG2; + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1)); + return const_; +} + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_s32 dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), init_value)); + PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0)); compiler->patches++; #else - PTR_FAIL_IF(emit_imm(compiler, reg, init_value)); + PTR_FAIL_IF(emit_imm(compiler, dst_r, 0)); #endif - set_const(const_, compiler); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 0); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1)); - return const_; + return put_label; } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c index b015695c52477..e15b3451e8022 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_64.c @@ -161,7 +161,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); } -static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) +static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) { sljit_sw diff; sljit_uw target_addr; @@ -196,14 +196,14 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in return 4; } - if (target_addr <= 0xffffffffl) { + if (target_addr < 0x100000000l) { if (jump->flags & IS_COND) code_ptr[-5] -= (2 << 5); code_ptr[-2] = code_ptr[0]; return 2; } - if (target_addr <= 0xffffffffffffl) { + if (target_addr < 0x1000000000000l) { if (jump->flags & IS_COND) code_ptr[-5] -= (1 << 5); jump->flags |= PATCH_ABS48; @@ -215,6 +215,22 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in return 0; } +static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +{ + if (max_label < 0x100000000l) { + put_label->flags = 0; + return 2; + } + + if (max_label < 0x1000000000000l) { + put_label->flags = 1; + return 1; + } + + put_label->flags = 2; + return 0; +} + SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; @@ -223,6 +239,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_uw next_addr; sljit_sw executable_offset; sljit_uw addr; sljit_s32 dst; @@ -230,6 +247,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; + struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -241,34 +259,47 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + next_addr = 0; executable_offset = SLJIT_EXEC_OFFSET(code); label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + put_label = compiler->put_labels; do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { *code_ptr = *buf_ptr++; - /* These structures are ordered by their address. */ - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - if (label && label->size == word_count) { - label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { - jump->addr = (sljit_uw)(code_ptr - 4); - code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset); - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; + if (next_addr == word_count) { + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { + jump->addr = (sljit_uw)(code_ptr - 4); + code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + if (put_label && put_label->addr == word_count) { + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)(code_ptr - 3); + code_ptr -= put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); + put_label = put_label->next; + } + next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr ++; word_count ++; @@ -286,6 +317,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); + SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); jump = compiler->jumps; @@ -323,6 +355,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = jump->next; } + put_label = compiler->put_labels; + while (put_label) { + addr = put_label->label->addr; + buf_ptr = (sljit_ins *)put_label->addr; + + buf_ptr[0] |= (addr & 0xffff) << 5; + buf_ptr[1] |= ((addr >> 16) & 0xffff) << 5; + + if (put_label->flags >= 1) + buf_ptr[2] |= ((addr >> 32) & 0xffff) << 5; + + if (put_label->flags >= 2) + buf_ptr[3] |= ((addr >> 48) & 0xffff) << 5; + + put_label = put_label->next; + } + compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); @@ -1947,6 +1996,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_s32 dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, 0)); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 1); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2)); + + return put_label; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins* inst = (sljit_ins*)addr; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c index d7024b6d7d417..cdfe4a4d24a93 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeARM_T2_32.c @@ -365,11 +365,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_u16 *buf_ptr; sljit_u16 *buf_end; sljit_uw half_count; + sljit_uw next_addr; sljit_sw executable_offset; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; + struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -381,34 +383,46 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; half_count = 0; + next_addr = 0; executable_offset = SLJIT_EXEC_OFFSET(code); label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + put_label = compiler->put_labels; do { buf_ptr = (sljit_u16*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 1); do { *code_ptr = *buf_ptr++; - /* These structures are ordered by their address. */ - SLJIT_ASSERT(!label || label->size >= half_count); - SLJIT_ASSERT(!jump || jump->addr >= half_count); - SLJIT_ASSERT(!const_ || const_->addr >= half_count); - if (label && label->size == half_count) { - label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1; - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == half_count) { - jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8); - code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset); - jump = jump->next; - } - if (const_ && const_->addr == half_count) { - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; + if (next_addr == half_count) { + SLJIT_ASSERT(!label || label->size >= half_count); + SLJIT_ASSERT(!jump || jump->addr >= half_count); + SLJIT_ASSERT(!const_ || const_->addr >= half_count); + SLJIT_ASSERT(!put_label || put_label->addr >= half_count); + + /* These structures are ordered by their address. */ + if (label && label->size == half_count) { + label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1; + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == half_count) { + jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8); + code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset); + jump = jump->next; + } + if (const_ && const_->addr == half_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + if (put_label && put_label->addr == half_count) { + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)code_ptr; + put_label = put_label->next; + } + next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr ++; half_count ++; @@ -426,6 +440,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); + SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); jump = compiler->jumps; @@ -434,6 +449,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = jump->next; } + put_label = compiler->put_labels; + while (put_label) { + modify_imm32_const((sljit_u16 *)put_label->addr, put_label->label->addr); + put_label = put_label->next; + } + compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16); @@ -2311,6 +2332,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_s32 dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, 0)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2)); + return put_label; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_u16 *inst = (sljit_u16*)addr; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_32.c index ad970bf25a861..16dec052fe75f 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_32.c @@ -425,6 +425,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI); inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); @@ -435,6 +436,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI); inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c index e0d6a3f085432..7d1d08749693c 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeMIPS_common.c @@ -449,6 +449,55 @@ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_ } #endif +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + +static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +{ + if (max_label < 0x80000000l) { + put_label->flags = 0; + return 1; + } + + if (max_label < 0x800000000000l) { + put_label->flags = 1; + return 3; + } + + put_label->flags = 2; + return 5; +} + +static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label) +{ + sljit_uw addr = put_label->label->addr; + sljit_ins *inst = (sljit_ins *)put_label->addr; + sljit_s32 reg = *inst; + + if (put_label->flags == 0) { + SLJIT_ASSERT(addr < 0x80000000l); + inst[0] = LUI | T(reg) | IMM(addr >> 16); + } + else if (put_label->flags == 1) { + SLJIT_ASSERT(addr < 0x800000000000l); + inst[0] = LUI | T(reg) | IMM(addr >> 32); + inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); + inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); + inst += 2; + } + else { + inst[0] = LUI | T(reg) | IMM(addr >> 48); + inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff); + inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16); + inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff); + inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16); + inst += 4; + } + + inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff); +} + +#endif + SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; @@ -457,12 +506,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_uw next_addr; sljit_sw executable_offset; sljit_uw addr; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; + struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -474,39 +525,54 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + next_addr = 0; executable_offset = SLJIT_EXEC_OFFSET(code); label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + put_label = compiler->put_labels; do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { + if (next_addr == word_count) { + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - jump->addr = (sljit_uw)(code_ptr - 3); + jump->addr = (sljit_uw)(code_ptr - 3); #else - jump->addr = (sljit_uw)(code_ptr - 7); + jump->addr = (sljit_uw)(code_ptr - 7); #endif - code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - /* Just recording the address. */ - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + if (put_label && put_label->addr == word_count) { + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); + word_count += 5; +#endif + put_label = put_label->next; + } + next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr ++; word_count ++; @@ -524,6 +590,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); + SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); jump = compiler->jumps; @@ -571,6 +638,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = jump->next; } + put_label = compiler->put_labels; + while (put_label) { +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + addr = put_label->label->addr; + buf_ptr = (sljit_ins *)put_label->addr; + + SLJIT_ASSERT((buf_ptr[0] & 0xffe00000) == LUI && (buf_ptr[1] & 0xfc000000) == ORI); + buf_ptr[0] |= (addr >> 16) & 0xffff; + buf_ptr[1] |= addr & 0xffff; +#else + put_label_set(put_label); +#endif + put_label = put_label->next; + } + compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); @@ -2157,7 +2239,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_s32 reg; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -2167,11 +2249,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + PTR_FAIL_IF(emit_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_s32 dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + PTR_FAIL_IF(emit_const(compiler, dst_r, 0)); +#else + PTR_FAIL_IF(push_inst(compiler, dst_r, UNMOVABLE_INS)); + compiler->size += 5; +#endif + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + + return put_label; +} diff --git a/ext/pcre/pcre2lib/sljit/sljitNativePPC_32.c b/ext/pcre/pcre2lib/sljit/sljitNativePPC_32.c index fc185f784754c..3ce741153f850 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativePPC_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativePPC_32.c @@ -259,6 +259,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI); inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); @@ -269,6 +270,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI); inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff); inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativePPC_64.c b/ext/pcre/pcre2lib/sljit/sljitNativePPC_64.c index 706b2ba20b59e..3b73021cc8c6b 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativePPC_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativePPC_64.c @@ -35,9 +35,6 @@ #error "Must implement count leading zeroes" #endif -#define RLDI(dst, src, sh, mb, type) \ - (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) - #define PUSH_RLDICR(reg, shift) \ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) diff --git a/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c b/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c index b34e3965ed23d..e8275143153d0 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativePPC_common.c @@ -231,6 +231,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SIMM_MIN (-0x8000) #define UIMM_MAX (0xffff) +#define RLDI(dst, src, sh, mb, type) \ + (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20)) + #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func) { @@ -324,6 +327,55 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in return 0; } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + +static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label) +{ + if (max_label < 0x100000000l) { + put_label->flags = 0; + return 1; + } + + if (max_label < 0x1000000000000l) { + put_label->flags = 1; + return 3; + } + + put_label->flags = 2; + return 4; +} + +static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label) +{ + sljit_uw addr = put_label->label->addr; + sljit_ins *inst = (sljit_ins *)put_label->addr; + sljit_s32 reg = *inst; + + if (put_label->flags == 0) { + SLJIT_ASSERT(addr < 0x100000000l); + inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 16); + } + else { + if (put_label->flags == 1) { + SLJIT_ASSERT(addr < 0x1000000000000l); + inst[0] = ORI | S(TMP_ZERO) | A(reg) | IMM(addr >> 32); + } + else { + inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 48); + inst[1] = ORI | S(reg) | A(reg) | IMM((addr >> 32) & 0xffff); + inst ++; + } + + inst[1] = RLDI(reg, reg, 32, 31, 1); + inst[2] = ORIS | S(reg) | A(reg) | IMM((addr >> 16) & 0xffff); + inst += 2; + } + + inst[1] = ORI | S(reg) | A(reg) | IMM(addr & 0xffff); +} + +#endif + SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; @@ -332,12 +384,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_uw next_addr; sljit_sw executable_offset; sljit_uw addr; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; + struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -356,71 +410,87 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + next_addr = 0; executable_offset = SLJIT_EXEC_OFFSET(code); label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + put_label = compiler->put_labels; do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { + if (next_addr == word_count) { + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - jump->addr = (sljit_uw)(code_ptr - 3); + jump->addr = (sljit_uw)(code_ptr - 3); #else - jump->addr = (sljit_uw)(code_ptr - 6); + jump->addr = (sljit_uw)(code_ptr - 6); #endif - if (detect_jump_type(jump, code_ptr, code, executable_offset)) { + if (detect_jump_type(jump, code_ptr, code, executable_offset)) { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - code_ptr[-3] = code_ptr[0]; - code_ptr -= 3; -#else - if (jump->flags & PATCH_ABS32) { + code_ptr[-3] = code_ptr[0]; code_ptr -= 3; - code_ptr[-1] = code_ptr[2]; - code_ptr[0] = code_ptr[3]; - } - else if (jump->flags & PATCH_ABS48) { - code_ptr--; - code_ptr[-1] = code_ptr[0]; - code_ptr[0] = code_ptr[1]; - /* rldicr rX,rX,32,31 -> rX,rX,16,47 */ - SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); - code_ptr[-3] ^= 0x8422; - /* oris -> ori */ - code_ptr[-2] ^= 0x4000000; - } - else { - code_ptr[-6] = code_ptr[0]; - code_ptr -= 6; - } +#else + if (jump->flags & PATCH_ABS32) { + code_ptr -= 3; + code_ptr[-1] = code_ptr[2]; + code_ptr[0] = code_ptr[3]; + } + else if (jump->flags & PATCH_ABS48) { + code_ptr--; + code_ptr[-1] = code_ptr[0]; + code_ptr[0] = code_ptr[1]; + /* rldicr rX,rX,32,31 -> rX,rX,16,47 */ + SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6); + code_ptr[-3] ^= 0x8422; + /* oris -> ori */ + code_ptr[-2] ^= 0x4000000; + } + else { + code_ptr[-6] = code_ptr[0]; + code_ptr -= 6; + } #endif - if (jump->flags & REMOVE_COND) { - code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); - code_ptr++; - jump->addr += sizeof(sljit_ins); - code_ptr[0] = Bx; - jump->flags -= IS_COND; + if (jump->flags & REMOVE_COND) { + code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001); + code_ptr++; + jump->addr += sizeof(sljit_ins); + code_ptr[0] = Bx; + jump->flags -= IS_COND; + } } + jump = jump->next; } - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; + if (const_ && const_->addr == word_count) { + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + if (put_label && put_label->addr == word_count) { + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); + word_count += 4; +#endif + put_label = put_label->next; + } + next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr ++; word_count ++; @@ -438,6 +508,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); + SLJIT_ASSERT(!put_label); + #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))); #else @@ -503,6 +575,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = jump->next; } + put_label = compiler->put_labels; + while (put_label) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + addr = put_label->label->addr; + buf_ptr = (sljit_ins *)put_label->addr; + + SLJIT_ASSERT((buf_ptr[0] & 0xfc1f0000) == ADDIS && (buf_ptr[1] & 0xfc000000) == ORI); + buf_ptr[0] |= (addr >> 16) & 0xffff; + buf_ptr[1] |= addr & 0xffff; +#else + put_label_set(put_label); +#endif + put_label = put_label->next; + } + compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins); @@ -2261,7 +2348,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_s32 reg; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -2271,11 +2358,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + PTR_FAIL_IF(emit_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + return const_; } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_s32 dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + PTR_FAIL_IF(emit_const(compiler, dst_r, 0)); +#else + PTR_FAIL_IF(push_inst(compiler, dst_r)); + compiler->size += 4; +#endif + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + + return put_label; +} diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_32.c index 0671b130cc6d9..8079fad8df84b 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_32.c @@ -267,6 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000)); inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff); inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); @@ -277,6 +278,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta { sljit_ins *inst = (sljit_ins *)addr; + SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000)); inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff); inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff); inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_common.c index 669ecd8152849..bfa4ecede2f84 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeSPARC_common.c @@ -298,12 +298,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_ptr; sljit_ins *buf_end; sljit_uw word_count; + sljit_uw next_addr; sljit_sw executable_offset; sljit_uw addr; struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; + struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -315,40 +317,52 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil code_ptr = code; word_count = 0; + next_addr = 0; executable_offset = SLJIT_EXEC_OFFSET(code); label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + put_label = compiler->put_labels; do { buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { *code_ptr = *buf_ptr++; - SLJIT_ASSERT(!label || label->size >= word_count); - SLJIT_ASSERT(!jump || jump->addr >= word_count); - SLJIT_ASSERT(!const_ || const_->addr >= word_count); - /* These structures are ordered by their address. */ - if (label && label->size == word_count) { - /* Just recording the address. */ - label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); - label->size = code_ptr - code; - label = label->next; - } - if (jump && jump->addr == word_count) { + if (next_addr == word_count) { + SLJIT_ASSERT(!label || label->size >= word_count); + SLJIT_ASSERT(!jump || jump->addr >= word_count); + SLJIT_ASSERT(!const_ || const_->addr >= word_count); + SLJIT_ASSERT(!put_label || put_label->addr >= word_count); + + /* These structures are ordered by their address. */ + if (label && label->size == word_count) { + /* Just recording the address. */ + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + label->size = code_ptr - code; + label = label->next; + } + if (jump && jump->addr == word_count) { #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - jump->addr = (sljit_uw)(code_ptr - 3); + jump->addr = (sljit_uw)(code_ptr - 3); #else - jump->addr = (sljit_uw)(code_ptr - 6); + jump->addr = (sljit_uw)(code_ptr - 6); #endif - code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); - jump = jump->next; - } - if (const_ && const_->addr == word_count) { - /* Just recording the address. */ - const_->addr = (sljit_uw)code_ptr; - const_ = const_->next; + code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset); + jump = jump->next; + } + if (const_ && const_->addr == word_count) { + /* Just recording the address. */ + const_->addr = (sljit_uw)code_ptr; + const_ = const_->next; + } + if (put_label && put_label->addr == word_count) { + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)code_ptr; + put_label = put_label->next; + } + next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr ++; word_count ++; @@ -366,6 +380,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); + SLJIT_ASSERT(!put_label); SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size); jump = compiler->jumps; @@ -389,8 +404,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* Set the fields of immediate loads. */ #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff); - buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff); + SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000)); + buf_ptr[0] |= (addr >> 10) & 0x3fffff; + buf_ptr[1] |= addr & 0x3ff; #else #error "Implementation required" #endif @@ -398,6 +414,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = jump->next; } + put_label = compiler->put_labels; + while (put_label) { + addr = put_label->label->addr; + buf_ptr = (sljit_ins *)put_label->addr; + +#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) + SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000)); + buf_ptr[0] |= (addr >> 10) & 0x3fffff; + buf_ptr[1] |= addr & 0x3ff; +#else +#error "Implementation required" +#endif + put_label = put_label->next; + } compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; @@ -1465,8 +1495,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { - sljit_s32 reg; struct sljit_const *const_; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -1476,11 +1506,31 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = FAST_IS_REG(dst) ? dst : TMP_REG2; - - PTR_FAIL_IF(emit_const(compiler, reg, init_value)); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + PTR_FAIL_IF(emit_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); return const_; } + +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_s32 dst_r; + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + PTR_FAIL_IF(emit_const(compiler, dst_r, 0)); + + if (dst & SLJIT_MEM) + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); + return put_label; +} diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeTILEGX_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeTILEGX_64.c index adc6d95b8c7e2..003f43a79091d 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeTILEGX_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeTILEGX_64.c @@ -59,7 +59,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { #define TMP_REG3_mapped 6 #define ADDR_TMP_mapped 7 -/* Flags are kept in volatile registers. */ +/* Flags are keept in volatile registers. */ #define EQUAL_FLAG 8 /* And carry flag as well. */ #define ULESS_FLAG 9 @@ -115,7 +115,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void) typedef sljit_uw sljit_ins; struct jit_instr { - const struct tilegx_opcode* opcode; + const struct tilegx_opcode* opcode; tilegx_pipeline pipe; unsigned long input_registers; unsigned long output_registers; @@ -896,7 +896,7 @@ static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic inst_buf[inst_buf_index].output_registers = 0; inst_buf[inst_buf_index].line = line; inst_buf_index++; - + return flush_buffer(compiler); } @@ -1178,7 +1178,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi { sljit_ins base; sljit_s32 i, tmp; - + CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c index 074e64b9f2bb6..34a3a3d940247 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_32.c @@ -38,8 +38,10 @@ static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, s return SLJIT_SUCCESS; } -static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset) { + sljit_s32 type = jump->flags >> TYPE_SHIFT; + if (type == SLJIT_JUMP) { *code_ptr++ = JMP_i32; jump->addr++; diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c index 8506565614422..5758711954047 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_64.c @@ -39,8 +39,10 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, return SLJIT_SUCCESS; } -static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr) { + sljit_s32 type = jump->flags >> TYPE_SHIFT; + int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff); /* The relative jump below specialized for this case. */ @@ -72,6 +74,56 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ return code_ptr; } +static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label) +{ + if (max_label > HALFWORD_MAX) { + put_label->addr -= put_label->flags; + put_label->flags = PATCH_MD; + return code_ptr; + } + + if (put_label->flags == 0) { + /* Destination is register. */ + code_ptr = (sljit_u8*)put_label->addr - 2 - sizeof(sljit_uw); + + SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W); + SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32); + + if ((code_ptr[0] & 0x07) != 0) { + code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x08); + code_ptr += 2 + sizeof(sljit_s32); + } + else { + code_ptr[0] = code_ptr[1]; + code_ptr += 1 + sizeof(sljit_s32); + } + + put_label->addr = (sljit_uw)code_ptr; + return code_ptr; + } + + code_ptr -= put_label->flags + (2 + sizeof(sljit_uw)); + SLJIT_MEMMOVE(code_ptr, code_ptr + (2 + sizeof(sljit_uw)), put_label->flags); + + SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W); + + if ((code_ptr[1] & 0xf8) == MOV_r_i32) { + code_ptr += 2 + sizeof(sljit_uw); + SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W); + } + + SLJIT_ASSERT(code_ptr[1] == MOV_rm_r); + + code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x4); + code_ptr[1] = MOV_rm_i32; + code_ptr[2] = (sljit_u8)(code_ptr[2] & ~(0x7 << 3)); + + code_ptr = (sljit_u8*)(put_label->addr - (2 + sizeof(sljit_uw)) + sizeof(sljit_s32)); + put_label->addr = (sljit_uw)code_ptr; + put_label->flags = 0; + return code_ptr; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) diff --git a/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c b/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c index 6f02ee3e8b4e6..6296da5382251 100644 --- a/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c +++ b/ext/pcre/pcre2lib/sljit/sljitNativeX86_common.c @@ -428,13 +428,15 @@ static sljit_u8 get_jump_code(sljit_s32 type) } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset); +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset); #else -static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type); +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr); +static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label); #endif -static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset) +static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset) { + sljit_s32 type = jump->flags >> TYPE_SHIFT; sljit_s32 short_jump; sljit_uw label_addr; @@ -447,7 +449,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN) - return generate_far_jump_code(jump, code_ptr, type); + return generate_far_jump_code(jump, code_ptr); #endif if (type == SLJIT_JUMP) { @@ -497,6 +499,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil struct sljit_label *label; struct sljit_jump *jump; struct sljit_const *const_; + struct sljit_put_label *put_label; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_generate_code(compiler)); @@ -511,6 +514,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = compiler->labels; jump = compiler->jumps; const_ = compiler->consts; + put_label = compiler->put_labels; executable_offset = SLJIT_EXEC_OFFSET(code); do { @@ -525,27 +529,38 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil buf_ptr += len; } else { - if (*buf_ptr >= 2) { + switch (*buf_ptr) { + case 0: + label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + label->size = code_ptr - code; + label = label->next; + break; + case 1: jump->addr = (sljit_uw)code_ptr; if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) - code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset); + code_ptr = generate_near_jump_code(jump, code_ptr, code, executable_offset); else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2, executable_offset); + code_ptr = generate_far_jump_code(jump, code_ptr, executable_offset); #else - code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2); + code_ptr = generate_far_jump_code(jump, code_ptr); #endif } jump = jump->next; - } - else if (*buf_ptr == 0) { - label->addr = ((sljit_uw)code_ptr) + executable_offset; - label->size = code_ptr - code; - label = label->next; - } - else { /* *buf_ptr is 1 */ + break; + case 2: const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw); const_ = const_->next; + break; + default: + SLJIT_ASSERT(*buf_ptr == 3); + SLJIT_ASSERT(put_label->label); + put_label->addr = (sljit_uw)code_ptr; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size)); +#endif + put_label = put_label->next; + break; } buf_ptr++; } @@ -557,6 +572,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); + SLJIT_ASSERT(!put_label); + SLJIT_ASSERT(code_ptr <= code + compiler->size); jump = compiler->jumps; while (jump) { @@ -591,8 +608,24 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = jump->next; } - /* Some space may be wasted because of short jumps. */ - SLJIT_ASSERT(code_ptr <= code + compiler->size); + put_label = compiler->put_labels; + while (put_label) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr); +#else + if (put_label->flags & PATCH_MD) { + SLJIT_ASSERT(put_label->label->addr > HALFWORD_MAX); + sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr); + } + else { + SLJIT_ASSERT(put_label->label->addr <= HALFWORD_MAX); + sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->addr); + } +#endif + + put_label = put_label->next; + } + compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = code_ptr - code; @@ -2481,7 +2514,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF_NULL(jump); - set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); + set_jump(jump, compiler, (type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT)); type &= 0xff; /* Worst case size. */ @@ -2495,7 +2528,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile PTR_FAIL_IF_NULL(inst); *inst++ = 0; - *inst++ = type + 2; + *inst++ = 1; return jump; } @@ -2513,7 +2546,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi if (src == SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF_NULL(jump); - set_jump(jump, compiler, JUMP_ADDR); + set_jump(jump, compiler, JUMP_ADDR | (type << TYPE_SHIFT)); jump->u.target = srcw; /* Worst case size. */ @@ -2527,7 +2560,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi FAIL_IF_NULL(inst); *inst++ = 0; - *inst++ = type + 2; + *inst++ = 1; } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -2831,7 +2864,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!inst); *inst++ = 0; - *inst++ = 1; + *inst++ = 2; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (dst & SLJIT_MEM) @@ -2842,6 +2875,54 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return const_; } +SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +{ + struct sljit_put_label *put_label; + sljit_u8 *inst; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_s32 reg; + sljit_uw start_size; +#endif + + CHECK_ERROR_PTR(); + CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); + PTR_FAIL_IF(!put_label); + set_put_label(put_label, compiler, 0); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + reg = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if (emit_load_imm64(compiler, reg, 0)) + return NULL; +#else + if (emit_mov(compiler, dst, dstw, SLJIT_IMM, 0)) + return NULL; +#endif + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (dst & SLJIT_MEM) { + start_size = compiler->size; + if (emit_mov(compiler, dst, dstw, TMP_REG1, 0)) + return NULL; + put_label->flags = compiler->size - start_size; + } +#endif + + inst = (sljit_u8*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!inst); + + *inst++ = 0; + *inst++ = 3; + + return put_label; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { SLJIT_UNUSED_ARG(executable_offset); diff --git a/ext/pcre/pcre2lib/sljit/sljitUtils.c b/ext/pcre/pcre2lib/sljit/sljitUtils.c index 03ed886a99ebd..857492a174811 100644 --- a/ext/pcre/pcre2lib/sljit/sljitUtils.c +++ b/ext/pcre/pcre2lib/sljit/sljitUtils.c @@ -70,7 +70,7 @@ static HANDLE allocator_mutex = 0; static SLJIT_INLINE void allocator_grab_lock(void) { - /* No idea what to do if an error occurs. Static mutexes should never fail... */ + /* No idea what to do if an error occures. Static mutexes should never fail... */ if (!allocator_mutex) allocator_mutex = CreateMutex(NULL, TRUE, NULL); else @@ -90,7 +90,7 @@ static HANDLE global_mutex = 0; SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void) { - /* No idea what to do if an error occurs. Static mutexes should never fail... */ + /* No idea what to do if an error occures. Static mutexes should never fail... */ if (!global_mutex) global_mutex = CreateMutex(NULL, TRUE, NULL); else @@ -154,7 +154,13 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void) #include "windows.h" #else /* Provides mmap function. */ +#include #include +#ifndef MAP_ANON +#ifdef MAP_ANONYMOUS +#define MAP_ANON MAP_ANONYMOUS +#endif +#endif /* For detecting the page size. */ #include From 378010a120fcc24a0b33ec68505899830b5f1ca5 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 25 Jan 2020 17:44:18 +0100 Subject: [PATCH 05/80] Fix bundled PCRE2 compilation on ARM64 --- ext/pcre/pcre2lib/pcre2_jit_neon_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h index 55b1f32ac9cef..aec48219eafa2 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h +++ b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h @@ -109,7 +109,7 @@ vect_t vmask = VDUPQ(mask); #if defined(FFCPS) compare_type compare1_type = compare_match1; compare_type compare2_type = compare_match1; -vect_t cmp1a, cmp1b, cmp2a, cmp2b; +vect_t cmp1a = vdupq_n_u8(0), cmp1b = vdupq_n_u8(0), cmp2a = vdupq_n_u8(0), cmp2b = vdupq_n_u8(0); const sljit_u32 diff = IN_UCHARS(offs1 - offs2); PCRE2_UCHAR char1a = ic.c.c1; PCRE2_UCHAR char2a = ic.c.c3; From b836d9cdc161c10d7c4b4eeb50ab123725967893 Mon Sep 17 00:00:00 2001 From: Florian Smeets Date: Sun, 26 Jan 2020 05:18:57 +0100 Subject: [PATCH 06/80] Add CURLOPT CURLOPT_HTTP09_ALLOWED available since 7.64.0 --- ext/curl/interface.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index c45763a967625..f6707310f49c2 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1452,6 +1452,10 @@ PHP_MINIT_FUNCTION(curl) REGISTER_CURL_CONSTANT(CURLOPT_TLS13_CIPHERS); #endif +#if LIBCURL_VERSION_NUM >= 0x074000 /* Available since 7.64.0 */ + REGISTER_CURL_CONSTANT(CURLOPT_HTTP09_ALLOWED); +#endif + #if LIBCURL_VERSION_NUM >= 0x074001 /* Available since 7.64.1 */ REGISTER_CURL_CONSTANT(CURL_VERSION_ALTSVC); #endif @@ -2365,6 +2369,9 @@ static int _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue) /* {{{ #endif #if LIBCURL_VERSION_NUM >= 0x073d00 /* Available since 7.61.0 */ case CURLOPT_DISALLOW_USERNAME_IN_URL: +#endif +#if LIBCURL_VERSION_NUM >= 0x074000 /* Available since 7.64.0 */ + case CURLOPT_HTTP09_ALLOWED: #endif lval = zval_get_long(zvalue); #if LIBCURL_VERSION_NUM >= 0x071304 From 9f4d1b99362f4bf00b8ea27fca39af2faf6bb634 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sat, 25 Jan 2020 12:40:22 +0100 Subject: [PATCH 07/80] Fix typo [ci skip] --- UPGRADING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPGRADING b/UPGRADING index 70b5585fcb8d8..20c3071bd70c1 100644 --- a/UPGRADING +++ b/UPGRADING @@ -352,7 +352,7 @@ PHP 8.0 UPGRADE NOTES . Added WeakMap. RFC: https://wiki.php.net/rfc/weak_maps . Added ValueError class. - . Any number of function parameters may not be replaced by a variadic + . Any number of function parameters may now be replaced by a variadic argument, as long as the types are compatible. For example, the following code is now allowed: From 3f6779879cf7a293541ea10cd2852c9f45cbe73f Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 26 Jan 2020 11:53:42 -0500 Subject: [PATCH 08/80] [skip ci] Fix typos in NEWS --- NEWS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 49cc8993702b1..8290ac3d81ac9 100644 --- a/NEWS +++ b/NEWS @@ -10,7 +10,7 @@ PHP NEWS (Nikita) . Fixed bug #49555 (Fatal error "Function must be a string" message should be renamed). (Nikita) - . Fixed bug #70839 (Convertion optional argument to variadic forbidden by LSP + . Fixed bug #70839 (Converting optional argument to variadic forbidden by LSP checks). (Nikita) - CURL: @@ -19,7 +19,7 @@ PHP NEWS - Date: . Fixed bug #65547 (Default value for sunrise/sunset zenith still wrong). (cmb) - . Fixed bug #69044 (discrepency between time and microtime). (krakjoe) + . Fixed bug #69044 (discrepancy between time and microtime). (krakjoe) - DOM: . Add property DOMXPath::$registerNodeNamespaces and constructor argument @@ -57,7 +57,7 @@ PHP NEWS . Fixed #60594 (mysqlnd exposes 160 lines of stats in phpinfo). (PeeHaa) - OpCache: - . Fixed bug #78654 (Incorrectly computed opcache checksum on files with + . Fixed bug #78654 (Incorrectly computed opcache checksum on files with non-ascii characters). (mhagstrand) - PCRE: @@ -79,7 +79,7 @@ PHP NEWS . Fixed bug #77805 (phpdbg build fails when readline is shared). (krakjoe) - Reflection: - . Fixed bug #78697 (ReflectionClass::implementsInterface - inaccurate error + . Fixed bug #78697 (ReflectionClass::implementsInterface - inaccurate error message with traits). (villfa) - Session: @@ -113,7 +113,7 @@ PHP NEWS . Fixed bug #76874 (xml_parser_free() should never leak memory). (Nikita) - XMLWriter: - . Changed functions to accept/return XMKWriter objects instead of resources. + . Changed functions to accept/return XMLWriter objects instead of resources. (cmb) - Zip: From fd08f062ae5a3c92bfc0345da7e83ab320046864 Mon Sep 17 00:00:00 2001 From: Ivan Mikheykin Date: Fri, 17 Jan 2020 22:26:35 +0300 Subject: [PATCH 09/80] Fix bug #78323: Code 0 is returned on invalid options Set CLI exit code to 1 when invalid parameters are passed, and print error to stderr. --- NEWS | 1 + ext/standard/basic_functions.c | 2 +- main/getopt.c | 3 +- main/php_getopt.h | 3 ++ sapi/cgi/cgi_main.c | 4 ++ sapi/cgi/tests/bug78323.phpt | 41 ++++++++++++++++++ sapi/cli/php_cli.c | 6 ++- sapi/cli/tests/015.phpt | 2 +- sapi/cli/tests/bug78323.phpt | 78 ++++++++++++++++++++++++++++++++++ sapi/fpm/fpm/fpm_main.c | 3 +- sapi/fpm/tests/bug78323.phpt | 39 +++++++++++++++++ 11 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 sapi/cgi/tests/bug78323.phpt create mode 100644 sapi/cli/tests/bug78323.phpt create mode 100644 sapi/fpm/tests/bug78323.phpt diff --git a/NEWS b/NEWS index a41b16a3589fb..fe4c2d37310ad 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ PHP NEWS . Fixed bug #71876 (Memory corruption htmlspecialchars(): charset `*' not supported). (Nikita) . Fixed bug ##79146 (cscript can fail to run on some systems). (clarodeus) + . Fixed bug #78323 (Code 0 is returned on invalid options). (Ivan Mikheykin) - CURL: . Fixed bug #79078 (Hypothetical use-after-free in curl_multi_add_handle()). diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index f34be0d1093a7..bbeb13f649b6b 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4478,7 +4478,7 @@ PHP_FUNCTION(getopt) while ((o = php_getopt(argc, argv, opts, &php_optarg, &php_optind, 0, 1)) != -1) { /* Skip unknown arguments. */ - if (o == '?') { + if (o == PHP_GETOPT_INVALID_ARG) { continue; } diff --git a/main/getopt.c b/main/getopt.c index 3af45e0e964dc..9e802fa23c9ef 100644 --- a/main/getopt.c +++ b/main/getopt.c @@ -26,6 +26,7 @@ #define OPTERRNF (2) #define OPTERRARG (3) +// Print error message to stderr and return -2 to distinguish it from '?' command line option. static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err) /* {{{ */ { if (show_err) @@ -47,7 +48,7 @@ static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int break; } } - return('?'); + return PHP_GETOPT_INVALID_ARG; } /* }}} */ diff --git a/main/php_getopt.h b/main/php_getopt.h index a8b2f89b4cc52..027e15295285d 100644 --- a/main/php_getopt.h +++ b/main/php_getopt.h @@ -35,6 +35,9 @@ extern PHPAPI int php_optidx; PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err, int arg_start); END_EXTERN_C() +/* php_getopt will return this value if there is an error in arguments */ +#define PHP_GETOPT_INVALID_ARG (-2) + #endif /* diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index fb16f2b577ca0..d6449ba228586 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -2283,6 +2283,7 @@ consult the installation file that came with this distribution, or visit \n\ break; case 'h': case '?': + case PHP_GETOPT_INVALID_ARG: if (request) { fcgi_destroy_request(request); } @@ -2292,6 +2293,9 @@ consult the installation file that came with this distribution, or visit \n\ php_cgi_usage(argv[0]); php_output_end_all(); exit_status = 0; + if (c == PHP_GETOPT_INVALID_ARG) { + exit_status = 1; + } goto out; } } diff --git a/sapi/cgi/tests/bug78323.phpt b/sapi/cgi/tests/bug78323.phpt new file mode 100644 index 0000000000000..d89e51874a43f --- /dev/null +++ b/sapi/cgi/tests/bug78323.phpt @@ -0,0 +1,41 @@ +--TEST-- +Bug #78323 Test exit code and error message for invalid parameters +--SKIPIF-- + +--FILE-- +&1", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + $lines[1], "\n", + "Done: $exitCode\n\n"; + + +// Successful execution +ob_start(); +passthru("$php -dmemory-limit=1G -v", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + "Done: $exitCode\n"; + +?> +--EXPECTF-- +Error in argument 1, char 1: no argument for option - +Usage: %s +Done: 1 + +PHP %s +Done: 0 diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 3b053e223ab76..342c5e5feb80a 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1265,7 +1265,7 @@ int main(int argc, char *argv[]) setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ #endif - while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2))!=-1) { + while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 1, 2))!=-1) { switch (c) { case 'c': if (ini_path_override) { @@ -1317,6 +1317,10 @@ int main(int argc, char *argv[]) case '?': php_cli_usage(argv[0]); goto out; + case PHP_GETOPT_INVALID_ARG: /* print usage on bad options, exit 1 */ + php_cli_usage(argv[0]); + exit_status = 1; + goto out; case 'i': case 'v': case 'm': sapi_module = &cli_sapi_module; goto exit_loop; diff --git a/sapi/cli/tests/015.phpt b/sapi/cli/tests/015.phpt index 01f5328e9924d..5a5e6c5190d25 100644 --- a/sapi/cli/tests/015.phpt +++ b/sapi/cli/tests/015.phpt @@ -16,7 +16,7 @@ $php = getenv('TEST_PHP_EXECUTABLE'); echo `"$php" -n --version | grep built:`; echo `echo "&1 | grep Usage:`; echo "Done\n"; ?> diff --git a/sapi/cli/tests/bug78323.phpt b/sapi/cli/tests/bug78323.phpt new file mode 100644 index 0000000000000..02b18e02a2141 --- /dev/null +++ b/sapi/cli/tests/bug78323.phpt @@ -0,0 +1,78 @@ +--TEST-- +Bug #78323 Test exit code and error message for invalid parameters +--SKIPIF-- + +--FILE-- +&1", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + $lines[1], "\n", + "Done: $exitCode\n\n"; + + +// option not found +ob_start(); +passthru("$php -Z 2>&1", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + $lines[1], "\n", + "Done: $exitCode\n\n"; + + +// no argument for option +ob_start(); +passthru("$php --memory-limit=1G 2>&1", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + $lines[1], "\n", + "Done: $exitCode\n\n"; + + +// Successful execution +ob_start(); +passthru("$php -dmemory-limit=1G -v", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + "Done: $exitCode\n"; + +?> +--EXPECTF-- +Error in argument %d, char %d: : in flags +Usage: %s [options] [-f] [--] [args...] +Done: 1 + +Error in argument %d, char %d: option not found %s +Usage: %s [options] [-f] [--] [args...] +Done: 1 + +Error in argument %d, char %d: no argument for option %s +Usage: %s [options] [-f] [--] [args...] +Done: 1 + +PHP %s +Done: 0 diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c index dfc0d8f7413c1..65890f9fdfb44 100644 --- a/sapi/fpm/fpm/fpm_main.c +++ b/sapi/fpm/fpm/fpm_main.c @@ -1707,6 +1707,7 @@ int main(int argc, char *argv[]) default: case 'h': case '?': + case PHP_GETOPT_INVALID_ARG: cgi_sapi_module.startup(&cgi_sapi_module); php_output_activate(); SG(headers_sent) = 1; @@ -1714,7 +1715,7 @@ int main(int argc, char *argv[]) php_output_end_all(); php_output_deactivate(); fcgi_shutdown(); - exit_status = (c == 'h') ? FPM_EXIT_OK : FPM_EXIT_USAGE; + exit_status = (c != PHP_GETOPT_INVALID_ARG) ? FPM_EXIT_OK : FPM_EXIT_USAGE; goto out; case 'v': /* show php version & quit */ diff --git a/sapi/fpm/tests/bug78323.phpt b/sapi/fpm/tests/bug78323.phpt new file mode 100644 index 0000000000000..cf91020573144 --- /dev/null +++ b/sapi/fpm/tests/bug78323.phpt @@ -0,0 +1,39 @@ +--TEST-- +FPM: Bug #78323 Test exit code for invalid parameters +--SKIPIF-- + +--FILE-- +&1", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + "Done: $exitCode\n\n"; + + +// Successful execution +ob_start(); +passthru("$php -dmemory-limit=1G -v", $exitCode); +$output = ob_get_contents(); +ob_end_clean(); + +$lines = preg_split('/\R/', $output); +echo $lines[0], "\n", + "Done: $exitCode\n"; + +?> +--EXPECTF-- +Usage: %s +Done: 64 + +PHP %s +Done: 0 From ea1b8788773fe9d5fd517704da332f0725714b8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Wed, 22 Jan 2020 13:33:11 +0100 Subject: [PATCH 10/80] Fix #78969 Make PASSWORD_DEFAULT match PASSWORD_BCRYPT instead of being null It was an unintentional BC break. --- NEWS | 1 + UPGRADING | 4 ++-- ext/standard/password.c | 2 +- ext/standard/tests/password/password_default.phpt | 9 +++++++++ 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 ext/standard/tests/password/password_default.phpt diff --git a/NEWS b/NEWS index 0f93d0671bfd8..d1d193e9c20dc 100644 --- a/NEWS +++ b/NEWS @@ -43,6 +43,7 @@ PHP NEWS - Standard: . Fixed bug #78902 (Memory leak when using stream_filter_append). (liudaixiao) + . Fixed bug #78969 (PASSWORD_DEFAULT should match PASSWORD_BCRYPT instead of being null). (kocsismate) - Zip: . Add ZipArchive::CM_LZMA2 constant (since libzip 1.6.0). (remi) diff --git a/UPGRADING b/UPGRADING index ccaa6fae44b6a..49634eabcd3b0 100644 --- a/UPGRADING +++ b/UPGRADING @@ -150,7 +150,7 @@ PHP 7.4 UPGRADE NOTES . Password hashing algorithm identifiers are now nullable strings rather than integers. - * PASSWORD_DEFAULT was int 1; now is null + * PASSWORD_DEFAULT was int 1; now is null in PHP <7.4.3 and string '2y' afterwards * PASSWORD_BCRYPT was int 1; now is string '2y' * PASSWORD_ARGON2I was int 2; now is string 'argon2i' * PASSWORD_ARGON2ID was int 3; now is string 'argon2id' @@ -726,7 +726,7 @@ PHP 7.4 UPGRADE NOTES the INI directive opcache.cache_id. All processes with the same cache ID and user share an OPcache instance. -- The OpenSSL default config path has been changed to +- The OpenSSL default config path has been changed to "C:\Program Files\Common Files\SSL\openssl.cnf" and "C:\Program Files (x86)\Common Files\SSL\openssl.cnf", respectively. diff --git a/ext/standard/password.c b/ext/standard/password.c index a12590c0e083c..9fe7fb1a42284 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -496,7 +496,7 @@ const php_password_algo php_password_algo_argon2id = { PHP_MINIT_FUNCTION(password) /* {{{ */ { zend_hash_init(&php_password_algos, 4, NULL, ZVAL_PTR_DTOR, 1); - REGISTER_NULL_CONSTANT("PASSWORD_DEFAULT", CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("PASSWORD_DEFAULT", "2y", CONST_CS | CONST_PERSISTENT); if (FAILURE == php_password_algo_register("2y", &php_password_algo_bcrypt)) { return FAILURE; diff --git a/ext/standard/tests/password/password_default.phpt b/ext/standard/tests/password/password_default.phpt new file mode 100644 index 0000000000000..9736f2309cee7 --- /dev/null +++ b/ext/standard/tests/password/password_default.phpt @@ -0,0 +1,9 @@ +--TEST-- +Test that the value of PASSWORD_DEFAULT matches PASSWORD_BCRYPT +--FILE-- + Date: Mon, 27 Jan 2020 16:13:36 +0100 Subject: [PATCH 11/80] Remove state pointer argument from php_strip_tags --- ext/filter/sanitizing_filters.c | 2 +- ext/standard/php_string.h | 4 ++-- ext/standard/string.c | 22 ++++------------------ 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/ext/filter/sanitizing_filters.c b/ext/filter/sanitizing_filters.c index cb1d3a10b2eff..25b2f39fde38f 100644 --- a/ext/filter/sanitizing_filters.c +++ b/ext/filter/sanitizing_filters.c @@ -194,7 +194,7 @@ void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL) php_filter_encode_html(value, enc); /* strip tags, implicitly also removes \0 chars */ - new_len = php_strip_tags_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), NULL, NULL, 0, 1); + new_len = php_strip_tags_ex(Z_STRVAL_P(value), Z_STRLEN_P(value), NULL, 0, 1); Z_STRLEN_P(value) = new_len; if (new_len == 0) { diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index b7084d09802a5..2c3953b958699 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -123,8 +123,8 @@ PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len); PHPAPI zend_string *php_str_to_str(const char *haystack, size_t length, const char *needle, size_t needle_len, const char *str, size_t str_len); PHPAPI zend_string *php_trim(zend_string *str, char *what, size_t what_len, int mode); -PHPAPI size_t php_strip_tags(char *rbuf, size_t len, uint8_t *state, const char *allow, size_t allow_len); -PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const char *allow, size_t allow_len, zend_bool allow_tag_spaces); +PHPAPI size_t php_strip_tags(char *rbuf, size_t len, const char *allow, size_t allow_len); +PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, const char *allow, size_t allow_len, zend_bool allow_tag_spaces); PHPAPI void php_implode(const zend_string *delim, HashTable *arr, zval *return_value); PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return_value, zend_long limit); diff --git a/ext/standard/string.c b/ext/standard/string.c index ffa05a967b45a..6fb9683c5ad37 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4659,7 +4659,7 @@ PHP_FUNCTION(strip_tags) } buf = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0); - ZSTR_LEN(buf) = php_strip_tags_ex(ZSTR_VAL(buf), ZSTR_LEN(str), NULL, allowed_tags, allowed_tags_len, 0); + ZSTR_LEN(buf) = php_strip_tags_ex(ZSTR_VAL(buf), ZSTR_LEN(str), allowed_tags, allowed_tags_len, 0); smart_str_free(&tags_ss); RETURN_NEW_STR(buf); } @@ -4869,9 +4869,9 @@ int php_tag_find(char *tag, size_t len, const char *set) { } /* }}} */ -PHPAPI size_t php_strip_tags(char *rbuf, size_t len, uint8_t *stateptr, const char *allow, size_t allow_len) /* {{{ */ +PHPAPI size_t php_strip_tags(char *rbuf, size_t len, const char *allow, size_t allow_len) /* {{{ */ { - return php_strip_tags_ex(rbuf, len, stateptr, allow, allow_len, 0); + return php_strip_tags_ex(rbuf, len, allow, allow_len, 0); } /* }}} */ @@ -4895,7 +4895,7 @@ PHPAPI size_t php_strip_tags(char *rbuf, size_t len, uint8_t *stateptr, const ch swm: Added ability to strip = end) { goto finish; @@ -5225,8 +5213,6 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, uint8_t *stateptr, const if (allow_free) { efree(allow_free); } - if (stateptr) - *stateptr = state; return (size_t)(rp - rbuf); } From 5215f072af4bd8993488780df45639f12757124d Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 27 Jan 2020 16:47:28 +0100 Subject: [PATCH 12/80] - bump zip extension version to 1.15.6 - add ZipArchive::LIBZIP_VERSION - skip bug53885.phpt with libzip 1.6.0 (empty file is no more valid archive) --- NEWS | 1 + ext/zip/php_zip.c | 6 ++++++ ext/zip/php_zip.h | 2 +- ext/zip/tests/bug53885.phpt | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d1d193e9c20dc..1eed1627b7d88 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,7 @@ PHP NEWS - Zip: . Add ZipArchive::CM_LZMA2 constant (since libzip 1.6.0). (remi) + . Add ZipArchive::LIBZIP_VERSION constant. (remi) 23 Jan 2020, PHP 7.4.2 diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index b2ac60e9ec96a..bec14f7f77b1e 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -3147,6 +3147,12 @@ static PHP_MINIT_FUNCTION(zip) REGISTER_ZIP_CLASS_CONST_LONG("EM_AES_256", ZIP_EM_AES_256); #endif +#if HAVE_LIBZIP_VERSION + zend_declare_class_constant_string(zip_class_entry, "LIBZIP_VERSION", sizeof("LIBZIP_VERSION")-1, zip_libzip_version()); +#else + zend_declare_class_constant_string(zip_class_entry, "LIBZIP_VERSION", sizeof("LIBZIP_VERSION")-1, LIBZIP_VERSION); +#endif + php_register_url_stream_wrapper("zip", &php_stream_zip_wrapper); le_zip_dir = zend_register_list_destructors_ex(php_zip_free_dir, NULL, le_zip_dir_name, module_number); diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index dc5a7ddfdd614..7caf65f0068ec 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -33,7 +33,7 @@ extern zend_module_entry zip_module_entry; #define ZIP_OVERWRITE ZIP_TRUNCATE #endif -#define PHP_ZIP_VERSION "1.15.5" +#define PHP_ZIP_VERSION "1.15.6" #define ZIP_OPENBASEDIR_CHECKPATH(filename) php_check_open_basedir(filename) diff --git a/ext/zip/tests/bug53885.phpt b/ext/zip/tests/bug53885.phpt index 6f95a661b323b..75f6fe1609eaa 100644 --- a/ext/zip/tests/bug53885.phpt +++ b/ext/zip/tests/bug53885.phpt @@ -3,6 +3,7 @@ Bug #53885 (ZipArchive segfault with FL_UNCHANGED on empty archive) --SKIPIF-- =')) die('skip libzip too recent'); ?> --FILE-- Date: Wed, 11 Dec 2019 21:57:57 +0100 Subject: [PATCH 13/80] Convert some warnings into ValueErrors in the standard file extension Closes GH-5007 --- ext/standard/file.c | 40 +- ext/standard/tests/file/bug71882.phpt | 11 +- .../tests/file/fgetcsv_error_conditions.csv | 2 + .../tests/file/fgetcsv_error_conditions.phpt | 61 ++ .../tests/file/fgetcsv_variation25.phpt | 935 ------------------ .../tests/file/fgetcsv_variation26.phpt | 585 ----------- .../tests/file/fgetcsv_variation27.phpt | 935 ------------------ .../tests/file/fgetcsv_variation28.phpt | 935 ------------------ .../tests/file/fgetcsv_variation3.phpt | 933 ----------------- .../tests/file/fgetcsv_variation4.phpt | 932 ----------------- .../tests/file/fgetcsv_variation5.phpt | 934 ----------------- ext/standard/tests/file/fgets_error.phpt | 25 +- ext/standard/tests/file/file_variation6.phpt | 44 +- .../tests/file/filesize_variation3-win32.phpt | 72 -- .../tests/file/filesize_variation3.phpt | 27 +- ext/standard/tests/file/flock.phpt | 15 +- ext/standard/tests/file/flock_error.phpt | 37 +- .../tests/file/fputcsv_variation2.phpt | 440 +++------ .../tests/file/fputcsv_variation3.phpt | 440 +++------ .../tests/file/fputcsv_variation4.phpt | 440 +++------ ext/standard/tests/file/fread_error.phpt | 25 +- ext/standard/tests/file/ftruncate.phpt | Bin 1137 -> 1143 bytes .../file/ftruncate_variation4-win32.phpt | 558 ----------- .../tests/file/ftruncate_variation4.phpt | 476 ++++----- ext/standard/tests/file/userstreams_005.phpt | 10 +- ext/zlib/tests/gzread_error2.phpt | 22 +- 26 files changed, 715 insertions(+), 8219 deletions(-) create mode 100644 ext/standard/tests/file/fgetcsv_error_conditions.csv create mode 100644 ext/standard/tests/file/fgetcsv_error_conditions.phpt delete mode 100644 ext/standard/tests/file/fgetcsv_variation25.phpt delete mode 100644 ext/standard/tests/file/fgetcsv_variation26.phpt delete mode 100644 ext/standard/tests/file/fgetcsv_variation27.phpt delete mode 100644 ext/standard/tests/file/fgetcsv_variation28.phpt delete mode 100644 ext/standard/tests/file/fgetcsv_variation3.phpt delete mode 100644 ext/standard/tests/file/fgetcsv_variation4.phpt delete mode 100644 ext/standard/tests/file/fgetcsv_variation5.phpt delete mode 100644 ext/standard/tests/file/filesize_variation3-win32.phpt delete mode 100644 ext/standard/tests/file/ftruncate_variation4-win32.phpt diff --git a/ext/standard/file.c b/ext/standard/file.c index aba87443a28b9..473d0510c277b 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -351,8 +351,8 @@ PHP_FUNCTION(flock) act = operation & 3; if (act < 1 || act > 3) { - php_error_docref(NULL, E_WARNING, "Illegal operation argument"); - RETURN_FALSE; + zend_value_error("Illegal operation argument"); + RETURN_THROWS(); } if (wouldblock) { @@ -745,8 +745,8 @@ PHP_FUNCTION(file) ZEND_PARSE_PARAMETERS_END(); if (flags < 0 || flags > (PHP_FILE_USE_INCLUDE_PATH | PHP_FILE_IGNORE_NEW_LINES | PHP_FILE_SKIP_EMPTY_LINES | PHP_FILE_NO_DEFAULT_CONTEXT)) { - php_error_docref(NULL, E_WARNING, "'" ZEND_LONG_FMT "' flag is not supported", flags); - RETURN_FALSE; + zend_value_error("'" ZEND_LONG_FMT "' flag is not supported", flags); + RETURN_THROWS(); } use_include_path = flags & PHP_FILE_USE_INCLUDE_PATH; @@ -1040,8 +1040,8 @@ PHPAPI PHP_FUNCTION(fgets) efree(buf); } else if (argc > 1) { if (len <= 0) { - php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0"); - RETURN_FALSE; + zend_value_error("Length parameter must be greater than 0"); + RETURN_THROWS(); } str = zend_string_alloc(len, 0); @@ -1495,8 +1495,8 @@ PHP_NAMED_FUNCTION(php_if_ftruncate) ZEND_PARSE_PARAMETERS_END(); if (size < 0) { - php_error_docref(NULL, E_WARNING, "Negative size is not supported"); - RETURN_FALSE; + zend_value_error("Negative size is not supported"); + RETURN_THROWS(); } PHP_STREAM_TO_ZVAL(stream, fp); @@ -1750,8 +1750,8 @@ PHPAPI PHP_FUNCTION(fread) PHP_STREAM_TO_ZVAL(stream, res); if (len <= 0) { - php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0"); - RETURN_FALSE; + zend_value_error("Length parameter must be greater than 0"); + RETURN_THROWS(); } str = php_stream_read_to_str(stream, len); @@ -1829,8 +1829,8 @@ PHP_FUNCTION(fputcsv) if (delimiter_str != NULL) { /* Make sure that there is at least one character in string */ if (delimiter_str_len < 1) { - php_error_docref(NULL, E_WARNING, "delimiter must be a character"); - RETURN_FALSE; + zend_value_error("delimiter must be a character"); + RETURN_THROWS(); } else if (delimiter_str_len > 1) { php_error_docref(NULL, E_NOTICE, "delimiter must be a single character"); } @@ -1841,8 +1841,8 @@ PHP_FUNCTION(fputcsv) if (enclosure_str != NULL) { if (enclosure_str_len < 1) { - php_error_docref(NULL, E_WARNING, "enclosure must be a character"); - RETURN_FALSE; + zend_value_error("enclosure must be a character"); + RETURN_THROWS(); } else if (enclosure_str_len > 1) { php_error_docref(NULL, E_NOTICE, "enclosure must be a single character"); } @@ -1967,8 +1967,8 @@ PHP_FUNCTION(fgetcsv) if (delimiter_str != NULL) { /* Make sure that there is at least one character in string */ if (delimiter_str_len < 1) { - php_error_docref(NULL, E_WARNING, "delimiter must be a character"); - RETURN_FALSE; + zend_value_error("delimiter must be a character"); + RETURN_THROWS(); } else if (delimiter_str_len > 1) { php_error_docref(NULL, E_NOTICE, "delimiter must be a single character"); } @@ -1979,8 +1979,8 @@ PHP_FUNCTION(fgetcsv) if (enclosure_str != NULL) { if (enclosure_str_len < 1) { - php_error_docref(NULL, E_WARNING, "enclosure must be a character"); - RETURN_FALSE; + zend_value_error("enclosure must be a character"); + RETURN_THROWS(); } else if (enclosure_str_len > 1) { php_error_docref(NULL, E_NOTICE, "enclosure must be a single character"); } @@ -2004,8 +2004,8 @@ PHP_FUNCTION(fgetcsv) if (len_zv != NULL && Z_TYPE_P(len_zv) != IS_NULL) { len = zval_get_long(len_zv); if (len < 0) { - php_error_docref(NULL, E_WARNING, "Length parameter may not be negative"); - RETURN_FALSE; + zend_value_error("Length parameter may not be negative"); + RETURN_THROWS(); } else if (len == 0) { len = -1; } diff --git a/ext/standard/tests/file/bug71882.phpt b/ext/standard/tests/file/bug71882.phpt index ce3adb1def0cd..7d3b911109b97 100644 --- a/ext/standard/tests/file/bug71882.phpt +++ b/ext/standard/tests/file/bug71882.phpt @@ -3,8 +3,11 @@ Bug #71882 (Negative ftruncate() on php://memory exhausts memory) --FILE-- getMessage() . \PHP_EOL; +} ?> ---EXPECTF-- -Warning: ftruncate(): Negative size is not supported in %s%ebug71882.php on line %d -bool(false) +--EXPECT-- +Negative size is not supported diff --git a/ext/standard/tests/file/fgetcsv_error_conditions.csv b/ext/standard/tests/file/fgetcsv_error_conditions.csv new file mode 100644 index 0000000000000..7bcd2a6a9cb87 --- /dev/null +++ b/ext/standard/tests/file/fgetcsv_error_conditions.csv @@ -0,0 +1,2 @@ +"water",fruit +This is line of text without csv fields \ No newline at end of file diff --git a/ext/standard/tests/file/fgetcsv_error_conditions.phpt b/ext/standard/tests/file/fgetcsv_error_conditions.phpt new file mode 100644 index 0000000000000..2dcd505a7b6ad --- /dev/null +++ b/ext/standard/tests/file/fgetcsv_error_conditions.phpt @@ -0,0 +1,61 @@ +--TEST-- +Various fgetcsv() error conditions +--FILE-- +getMessage() . \PHP_EOL; +} +try { + var_dump( fgetcsv($file_handle, -10, $delimiter) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump( fgetcsv($file_handle, -10, $delimiter, $enclosure) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo 'fgetcsv() with delimiter as NULL' . \PHP_EOL; +try { + var_dump( fgetcsv($file_handle, $length, NULL, $enclosure) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo 'fgetcsv() with enclosure as NULL' . \PHP_EOL; +try { + var_dump( fgetcsv($file_handle, $length, $delimiter, NULL) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +echo 'fgetcsv() with delimiter & enclosure as NULL' . \PHP_EOL; +try { + var_dump( fgetcsv($file_handle, $length, NULL, NULL) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +?> +--EXPECT-- +fgetcsv() with negative length +Length parameter may not be negative +Length parameter may not be negative +Length parameter may not be negative +fgetcsv() with delimiter as NULL +delimiter must be a character +fgetcsv() with enclosure as NULL +enclosure must be a character +fgetcsv() with delimiter & enclosure as NULL +delimiter must be a character diff --git a/ext/standard/tests/file/fgetcsv_variation25.phpt b/ext/standard/tests/file/fgetcsv_variation25.phpt deleted file mode 100644 index 073248c101ebb..0000000000000 --- a/ext/standard/tests/file/fgetcsv_variation25.phpt +++ /dev/null @@ -1,935 +0,0 @@ ---TEST-- -Test fgetcsv() : usage variations - with negative length value along with enclosure and delimiter ---FILE-- - ---EXPECTF-- -*** Testing fgetcsv() : with negative length value *** - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) -Done diff --git a/ext/standard/tests/file/fgetcsv_variation26.phpt b/ext/standard/tests/file/fgetcsv_variation26.phpt deleted file mode 100644 index 3b708c77df839..0000000000000 --- a/ext/standard/tests/file/fgetcsv_variation26.phpt +++ /dev/null @@ -1,585 +0,0 @@ ---TEST-- -Test fgetcsv() : usage variations - reading files opened in write only mode (Bug #42036) ---FILE-- - ---EXPECTF-- -*** Testing fgetcsv() : reading the files opened in write only mode *** - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using wt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using ab mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using at mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xb mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using xt mode -- - -Notice: fgetcsv(): Read of 8192 bytes failed with errno=9 Bad file descriptor in %s on line %d -bool(false) -int(0) -bool(false) -Done diff --git a/ext/standard/tests/file/fgetcsv_variation27.phpt b/ext/standard/tests/file/fgetcsv_variation27.phpt deleted file mode 100644 index 484ac89472d2c..0000000000000 --- a/ext/standard/tests/file/fgetcsv_variation27.phpt +++ /dev/null @@ -1,935 +0,0 @@ ---TEST-- -Test fgetcsv() : usage variations - with negative length value along with delimiter and no enclosure ---FILE-- - ---EXPECTF-- -*** Testing fgetcsv() : with negative length value *** - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) -Done diff --git a/ext/standard/tests/file/fgetcsv_variation28.phpt b/ext/standard/tests/file/fgetcsv_variation28.phpt deleted file mode 100644 index 95d59dcec463e..0000000000000 --- a/ext/standard/tests/file/fgetcsv_variation28.phpt +++ /dev/null @@ -1,935 +0,0 @@ ---TEST-- -Test fgetcsv() : usage variations - with negative length value along with neither enclosure and nor delimiter ---FILE-- - ---EXPECTF-- -*** Testing fgetcsv() : with negative length value *** - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): Length parameter may not be negative in %s on line %d -bool(false) -int(0) -bool(false) -Done diff --git a/ext/standard/tests/file/fgetcsv_variation3.phpt b/ext/standard/tests/file/fgetcsv_variation3.phpt deleted file mode 100644 index e94f81d56d0ad..0000000000000 --- a/ext/standard/tests/file/fgetcsv_variation3.phpt +++ /dev/null @@ -1,933 +0,0 @@ ---TEST-- -Test fgetcsv() : usage variations - with delimiter as NULL ---FILE-- - ---EXPECTF-- -*** Testing fgetcsv() : with delimiter as NULL *** - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) -Done diff --git a/ext/standard/tests/file/fgetcsv_variation4.phpt b/ext/standard/tests/file/fgetcsv_variation4.phpt deleted file mode 100644 index 1f32907b53328..0000000000000 --- a/ext/standard/tests/file/fgetcsv_variation4.phpt +++ /dev/null @@ -1,932 +0,0 @@ ---TEST-- -Test fgetcsv() : usage variations - with enclosure as NULL ---FILE-- - ---EXPECTF-- -*** Testing fgetcsv() : with enclosure as NULL *** - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): enclosure must be a character in %s on line %d -bool(false) -int(0) -bool(false) -Done diff --git a/ext/standard/tests/file/fgetcsv_variation5.phpt b/ext/standard/tests/file/fgetcsv_variation5.phpt deleted file mode 100644 index 4c883abf69c19..0000000000000 --- a/ext/standard/tests/file/fgetcsv_variation5.phpt +++ /dev/null @@ -1,934 +0,0 @@ ---TEST-- -Test fgetcsv() : usage variations - with delimiter & enclosure as NULL ---FILE-- - ---EXPECTF-- -*** Testing fgetcsv() : with delimiter & enclosure as NULL *** - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rb mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using rt mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using r+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using a+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using w+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+ mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+b mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) - --- Testing fgetcsv() with file opened using x+t mode -- - -Warning: fgetcsv(): delimiter must be a character in %s on line %d -bool(false) -int(0) -bool(false) -Done diff --git a/ext/standard/tests/file/fgets_error.phpt b/ext/standard/tests/file/fgets_error.phpt index eed35b30015e2..ffc21ee588028 100644 --- a/ext/standard/tests/file/fgets_error.phpt +++ b/ext/standard/tests/file/fgets_error.phpt @@ -14,22 +14,25 @@ $fp = fopen(__FILE__, "r"); // invalid length argument echo "-- Testing fgets() with invalid length arguments --\n"; $len = 0; -var_dump( fgets($fp, $len) ); +try { + var_dump( fgets($fp, $len) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + $len = -10; -var_dump( fgets($fp, $len) ); +try { + var_dump( fgets($fp, $len) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} $len = 1; var_dump( fgets($fp, $len) ); // return length - 1 always, expect false -echo "Done\n"; ?> ---EXPECTF-- +--EXPECT-- *** Testing error conditions *** -- Testing fgets() with invalid length arguments -- - -Warning: fgets(): Length parameter must be greater than 0 in %s on line %d -bool(false) - -Warning: fgets(): Length parameter must be greater than 0 in %s on line %d -bool(false) +Length parameter must be greater than 0 +Length parameter must be greater than 0 bool(false) -Done diff --git a/ext/standard/tests/file/file_variation6.phpt b/ext/standard/tests/file/file_variation6.phpt index 7e34f285d3792..b8078d2bd17b5 100644 --- a/ext/standard/tests/file/file_variation6.phpt +++ b/ext/standard/tests/file/file_variation6.phpt @@ -9,13 +9,17 @@ fwrite($fd, "Line 1\nLine 2\nLine 3"); fclose($fd); for ($flags = 0; $flags <= 32; $flags++) { - var_dump(file($filepath, $flags)); + try { + var_dump(file($filepath, $flags)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } } unlink($filepath); ?> ---EXPECTF-- +--EXPECT-- array(3) { [0]=> string(7) "Line 1 @@ -232,30 +236,12 @@ array(3) { [2]=> string(6) "Line 3" } - -Warning: file(): '24' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '25' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '26' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '27' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '28' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '29' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '30' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '31' flag is not supported in %s on line %d -bool(false) - -Warning: file(): '32' flag is not supported in %s on line %d -bool(false) +'24' flag is not supported +'25' flag is not supported +'26' flag is not supported +'27' flag is not supported +'28' flag is not supported +'29' flag is not supported +'30' flag is not supported +'31' flag is not supported +'32' flag is not supported \ No newline at end of file diff --git a/ext/standard/tests/file/filesize_variation3-win32.phpt b/ext/standard/tests/file/filesize_variation3-win32.phpt deleted file mode 100644 index 67b97a8009ee3..0000000000000 --- a/ext/standard/tests/file/filesize_variation3-win32.phpt +++ /dev/null @@ -1,72 +0,0 @@ ---TEST-- -Test filesize() function: usage variations - file size after truncate ---SKIPIF-- -=-1200; $size-=1200) { - $file_handle = fopen($filename, "r+"); - var_dump( ftruncate($file_handle, $size) ); - fclose($file_handle); - var_dump( filesize($filename) ); - clearstatcache(); -} - -echo "*** Done ***\n"; -?> ---CLEAN-- - ---EXPECTF-- -*** Testing filesize(): usage variations *** --- Testing filesize() after truncating the file to a new length -- -bool(true) -int(12000) -bool(true) -int(10800) -bool(true) -int(9600) -bool(true) -int(8400) -bool(true) -int(7200) -bool(true) -int(6000) -bool(true) -int(4800) -bool(true) -int(3600) -bool(true) -int(2400) -bool(true) -int(1200) -bool(true) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -*** Done *** diff --git a/ext/standard/tests/file/filesize_variation3.phpt b/ext/standard/tests/file/filesize_variation3.phpt index 09b9c341cae57..74790e687c510 100644 --- a/ext/standard/tests/file/filesize_variation3.phpt +++ b/ext/standard/tests/file/filesize_variation3.phpt @@ -1,10 +1,5 @@ --TEST-- Test filesize() function: usage variations - file size after truncate ---SKIPIF-- -=-1200; $size-=1200) { - $file_handle = fopen($filename, "r+"); - var_dump( ftruncate($file_handle, $size) ); - fclose($file_handle); - var_dump( filesize($filename) ); - clearstatcache(); + $file_handle = fopen($filename, "r+"); + try { + var_dump( ftruncate($file_handle, $size) ); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } + fclose($file_handle); + var_dump( filesize($filename) ); + clearstatcache(); } -echo "*** Done ***\n"; ?> --CLEAN-- ---EXPECTF-- +--EXPECT-- *** Testing filesize(): usage variations *** -- Testing filesize() after truncating the file to a new length -- bool(true) @@ -65,8 +63,5 @@ bool(true) int(1200) bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) -*** Done *** diff --git a/ext/standard/tests/file/flock.phpt b/ext/standard/tests/file/flock.phpt index 48cba22729e58..ab0cfc6f4e13c 100644 --- a/ext/standard/tests/file/flock.phpt +++ b/ext/standard/tests/file/flock.phpt @@ -32,16 +32,20 @@ var_dump(flock($fp, LOCK_UN, $would)); var_dump($would); var_dump(flock($fp, -1)); -var_dump(flock($fp, 0)); -echo "Done\n"; +try { + var_dump(flock($fp, 0)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + ?> --CLEAN-- ---EXPECTF-- +--EXPECT-- flock(): supplied resource is not a valid stream resource bool(true) bool(true) @@ -56,7 +60,4 @@ int(0) bool(true) int(0) bool(true) - -Warning: flock(): Illegal operation argument in %s on line %d -bool(false) -Done +Illegal operation argument diff --git a/ext/standard/tests/file/flock_error.phpt b/ext/standard/tests/file/flock_error.phpt index 90920943394ce..ced25b2e71627 100644 --- a/ext/standard/tests/file/flock_error.phpt +++ b/ext/standard/tests/file/flock_error.phpt @@ -30,13 +30,13 @@ $operations = array( $i = 0; foreach($operations as $operation) { - echo "\n--- Iteration $i ---"; - try { - var_dump(flock($fp, $operation)); - } catch (TypeError $e) { - echo "\n", $e->getMessage(), "\n"; - } - $i++; + echo "--- Iteration $i ---" . \PHP_EOL; + try { + var_dump(flock($fp, $operation)); + } catch (\TypeError|\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } + $i++; } @@ -54,37 +54,24 @@ try { $file = __DIR__."/flock_error.tmp"; unlink($file); ?> ---EXPECTF-- +--EXPECT-- *** Testing error conditions *** - --- Iteration 0 --- -Warning: flock(): Illegal operation argument in %s on line %d -bool(false) - +Illegal operation argument --- Iteration 1 --- -Warning: flock(): Illegal operation argument in %s on line %d -bool(false) - +Illegal operation argument --- Iteration 2 --- -Warning: flock(): Illegal operation argument in %s on line %d -bool(false) - +Illegal operation argument --- Iteration 3 --- -Warning: flock(): Illegal operation argument in %s on line %d -bool(false) - +Illegal operation argument --- Iteration 4 --- flock() expects parameter 2 to be int, array given - --- Iteration 5 --- flock() expects parameter 2 to be int, array given - --- Iteration 6 --- flock() expects parameter 2 to be int, string given - --- Iteration 7 --- flock() expects parameter 2 to be int, string given - --- Iteration 8 --- flock() expects parameter 2 to be int, string given flock(): supplied resource is not a valid stream resource diff --git a/ext/standard/tests/file/fputcsv_variation2.phpt b/ext/standard/tests/file/fputcsv_variation2.phpt index deb2e825651a2..6625ef6ffe0f8 100644 --- a/ext/standard/tests/file/fputcsv_variation2.phpt +++ b/ext/standard/tests/file/fputcsv_variation2.phpt @@ -55,7 +55,11 @@ foreach ($csv_lists as $csv_list) { $csv_field = $csv_list[2]; // write to a file in csv format - var_dump( fputcsv($file_handle, $csv_field, NULL, $enclosure) ); + try { + var_dump( fputcsv($file_handle, $csv_field, NULL, $enclosure) ); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } // check the file pointer position and eof var_dump( ftell($file_handle) ); var_dump( feof($file_handle) ); @@ -72,869 +76,653 @@ foreach ($csv_lists as $csv_list) { echo "Done\n"; ?> ---EXPECTF-- +--EXPECT-- *** Testing fputcsv() : with delimiter as NULL *** -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" diff --git a/ext/standard/tests/file/fputcsv_variation3.phpt b/ext/standard/tests/file/fputcsv_variation3.phpt index 05f29bfc4cd7d..326e92939ceca 100644 --- a/ext/standard/tests/file/fputcsv_variation3.phpt +++ b/ext/standard/tests/file/fputcsv_variation3.phpt @@ -55,7 +55,11 @@ foreach ($csv_lists as $csv_list) { $csv_field = $csv_list[2]; // write to a file in csv format - var_dump( fputcsv($file_handle, $csv_field, $delimiter, NULL) ); + try { + var_dump( fputcsv($file_handle, $csv_field, $delimiter, NULL) ); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } // check the file pointer position and eof var_dump( ftell($file_handle) ); var_dump( feof($file_handle) ); @@ -72,869 +76,653 @@ foreach ($csv_lists as $csv_list) { echo "Done\n"; ?> ---EXPECTF-- +--EXPECT-- *** Testing fputcsv() : with enclosure as NULL *** -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): enclosure must be a character in %s on line %d -bool(false) +enclosure must be a character int(0) bool(false) string(0) "" diff --git a/ext/standard/tests/file/fputcsv_variation4.phpt b/ext/standard/tests/file/fputcsv_variation4.phpt index 0a1a1cb5d7d1b..90cdfd724a8e0 100644 --- a/ext/standard/tests/file/fputcsv_variation4.phpt +++ b/ext/standard/tests/file/fputcsv_variation4.phpt @@ -55,7 +55,11 @@ foreach ($csv_lists as $csv_list) { $csv_field = $csv_list[2]; // write to a file in csv format - var_dump( fputcsv($file_handle, $csv_field, NULL, NULL) ); + try { + var_dump( fputcsv($file_handle, $csv_field, NULL, NULL) ); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } // check the file pointer position and eof var_dump( ftell($file_handle) ); var_dump( feof($file_handle) ); @@ -72,869 +76,653 @@ foreach ($csv_lists as $csv_list) { echo "Done\n"; ?> ---EXPECTF-- +--EXPECT-- *** Testing fputcsv() : with delimiter and enclosure as NULL *** -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in r+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in a+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in w+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+ -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+b -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" -- file opened in x+t -- - -Warning: fputcsv(): delimiter must be a character in %s on line %d -bool(false) +delimiter must be a character int(0) bool(false) string(0) "" diff --git a/ext/standard/tests/file/fread_error.phpt b/ext/standard/tests/file/fread_error.phpt index f51f24c7548e6..953df79556696 100644 --- a/ext/standard/tests/file/fread_error.phpt +++ b/ext/standard/tests/file/fread_error.phpt @@ -17,18 +17,21 @@ $file_handle = fopen($filename, "r"); // invalid length argument echo "-- Testing fread() with invalid length arguments --\n"; $len = 0; -var_dump( fread($file_handle, $len) ); +try { + var_dump( fread($file_handle, $len) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + $len = -10; -var_dump( fread($file_handle, $len) ); +try { + var_dump( fread($file_handle, $len) ); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} -echo "Done\n"; ---EXPECTF-- +--EXPECT-- *** Testing error conditions *** -- Testing fread() with invalid length arguments -- - -Warning: fread(): Length parameter must be greater than 0 in %s on line %d -bool(false) - -Warning: fread(): Length parameter must be greater than 0 in %s on line %d -bool(false) -Done +Length parameter must be greater than 0 +Length parameter must be greater than 0 diff --git a/ext/standard/tests/file/ftruncate.phpt b/ext/standard/tests/file/ftruncate.phpt index 3779cf3378747b09513dc447c1deee91af2a206f..d5d883b1a1b310db179a79d16a4ceb2100bb6fd4 100644 GIT binary patch delta 119 zcmey!@ttGCEhes#qDqBoE(IW%e2`HhP}k4^1~fITxoQ=X6HAga6f|PO5_3vZU5kqH zixgB+HKAHklQZ&xTwS~L)Dqv+;^M^gR1Hl9J%yM6kAQere;=R$lbF3HM>5Zy%*!G- I*@Hy|08WS^r2qf` delta 123 zcmey)@sVT0EvCsvOcIm-F!4_|V>FxG!Ysm%D+RyQ^u&_PvQ&lQ%&Js{%wmPS{1S!Y(t?8gqLS1Uh0Ht! a)nbMGJcXRhyi^6%l*!AP4Ol_uasdEsDJn1k diff --git a/ext/standard/tests/file/ftruncate_variation4-win32.phpt b/ext/standard/tests/file/ftruncate_variation4-win32.phpt deleted file mode 100644 index e2e92269e7c50..0000000000000 --- a/ext/standard/tests/file/ftruncate_variation4-win32.phpt +++ /dev/null @@ -1,558 +0,0 @@ ---TEST-- -Test ftruncate() function : usage variations - truncate file to negative size ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -*** Testing ftruncate() : usage variations *** - --- Testing ftruncate() with file having data of type numeric -- --- Testing ftruncate() with file opening using r mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using rb mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using rt mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using r+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using r+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using r+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using w mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using wb mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using wt mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using w+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using w+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using w+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using x mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using xb mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using xt mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using x+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using x+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using x+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using a mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using ab mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using at mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using a+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using a+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using a+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) - --- Testing ftruncate() with file having data of type text_with_new_line -- --- Testing ftruncate() with file opening using r mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using rb mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using rt mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using r+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using r+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using r+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using w mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using wb mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using wt mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1137) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1137) --- Testing ftruncate() with file opening using w+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using w+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using w+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1137) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1137) --- Testing ftruncate() with file opening using x mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using xb mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using xt mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1137) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1137) --- Testing ftruncate() with file opening using x+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using x+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using x+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1137) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1137) --- Testing ftruncate() with file opening using a mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using ab mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using at mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using a+ mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using a+b mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) --- Testing ftruncate() with file opening using a+t mode -- --- Testing ftruncate(): try truncating file to a negative size -- -int(1024) -int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) -int(0) -bool(false) -int(1024) -Done diff --git a/ext/standard/tests/file/ftruncate_variation4.phpt b/ext/standard/tests/file/ftruncate_variation4.phpt index 3d06d1eb8e4c2..95ae439b4db1c 100644 --- a/ext/standard/tests/file/ftruncate_variation4.phpt +++ b/ext/standard/tests/file/ftruncate_variation4.phpt @@ -1,11 +1,5 @@ --TEST-- Test ftruncate() function : usage variations - truncate file to negative size ---SKIPIF-- - --FILE-- getMessage() . \PHP_EOL; + } + var_dump( ftell($file_handle) ); + var_dump( feof($file_handle) ); + fclose($file_handle); + clearstatcache(); // clear previous size value in cache + $file_size = filesize($filename); // new file size = actual size, no change + var_dump($file_size === 1024 || $file_size === 1137); // 1137 is for Windows with 't' mode + + //delete all files created + delete_file( $filename ); + }//end of inner for loop }//end of outer foreach loop echo "Done\n"; ?> ---EXPECTF-- +--EXPECT-- *** Testing ftruncate() : usage variations *** -- Testing ftruncate() with file having data of type numeric -- -- Testing ftruncate() with file opening using r mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using rb mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using rt mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using r+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using r+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using r+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using wb mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using wt mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using xb mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using xt mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using ab mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using at mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file having data of type text_with_new_line -- -- Testing ftruncate() with file opening using r mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using rb mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using rt mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using r+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using r+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using r+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using wb mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using wt mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using w+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using xb mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using xt mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using x+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using ab mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using at mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a+ mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a+b mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) -- Testing ftruncate() with file opening using a+t mode -- -- Testing ftruncate(): try truncating file to a negative size -- -int(1024) +bool(true) int(0) - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported int(0) bool(false) -int(1024) +bool(true) Done diff --git a/ext/standard/tests/file/userstreams_005.phpt b/ext/standard/tests/file/userstreams_005.phpt index a2af1b4086e68..0c3113c19763c 100644 --- a/ext/standard/tests/file/userstreams_005.phpt +++ b/ext/standard/tests/file/userstreams_005.phpt @@ -38,7 +38,11 @@ $fd3 = fopen("test3://foo","r"); test("stream_truncate not implemented", $fd2, 0); test("stream_truncate size 0", $fd, 0); test("stream_truncate size 10", $fd, 10); -test("stream_truncate negative size", $fd, -1); +try { + test("stream_truncate negative size", $fd, -1); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} test("stream_truncate bad return", $fd3, 0); --EXPECTF-- bool(true) @@ -55,9 +59,7 @@ bool(true) truncation with new_size=10 bool(true) ------ stream_truncate negative size: ------- - -Warning: ftruncate(): Negative size is not supported in %s on line %d -bool(false) +Negative size is not supported ------ stream_truncate bad return: ------- truncation with new_size=0 diff --git a/ext/zlib/tests/gzread_error2.phpt b/ext/zlib/tests/gzread_error2.phpt index 7626eb1de80e0..1c3cce3e87717 100644 --- a/ext/zlib/tests/gzread_error2.phpt +++ b/ext/zlib/tests/gzread_error2.phpt @@ -11,20 +11,24 @@ if (!extension_loaded("zlib")) { $f = __DIR__."/004.txt.gz"; $h = gzopen($f, 'r'); var_dump(gzread($h, 10)); -var_dump(gzread($h, 0)); +try { + var_dump(gzread($h, 0)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump(gzread($h, 5)); -var_dump(gzread($h, -1)); +try { + var_dump(gzread($h, -1)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump(gzread($h, 8)); gzclose($h); ?> ---EXPECTF-- +--EXPECT-- string(10) "When you'r" - -Warning: gzread(): Length parameter must be greater than 0 in %s on line %d -bool(false) +Length parameter must be greater than 0 string(5) "e tau" - -Warning: gzread(): Length parameter must be greater than 0 in %s on line %d -bool(false) +Length parameter must be greater than 0 string(8) "ght thro" From 5f92a085cc50718aa921ba1139f6cc576deb68fa Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 26 Jan 2020 13:05:34 -0500 Subject: [PATCH 14/80] Convert ZEND_ECHO operand to string after sccp And filter out echoes of the empty string (e.g. false/null) Split out of #5097 (on GitHub) Closes GH-5118 --- ext/opcache/Optimizer/zend_optimizer.c | 15 +++++++++++ ext/opcache/tests/opt/sccp_002.phpt | 4 +-- ext/opcache/tests/opt/sccp_003.phpt | 4 +-- ext/opcache/tests/opt/sccp_004.phpt | 4 +-- ext/opcache/tests/opt/sccp_005.phpt | 2 +- ext/opcache/tests/opt/sccp_007.phpt | 2 +- ext/opcache/tests/opt/sccp_009.phpt | 2 +- ext/opcache/tests/opt/sccp_010.phpt | 4 +-- ext/opcache/tests/opt/sccp_011.phpt | 2 +- ext/opcache/tests/opt/sccp_012.phpt | 4 +-- ext/opcache/tests/opt/sccp_022.phpt | 2 +- ext/opcache/tests/opt/sccp_031.phpt | 36 ++++++++++++++++++++++++++ 12 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 ext/opcache/tests/opt/sccp_031.phpt diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 84d4c61831bb7..30743fd7ba44a 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -340,6 +340,21 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_FETCH_LIST_R: case ZEND_COPY_TMP: return 0; + case ZEND_ECHO: + { + zval zv; + if (Z_TYPE_P(val) != IS_STRING && zend_optimizer_eval_cast(&zv, IS_STRING, val) == SUCCESS) { + zval_ptr_dtor_nogc(val); + val = &zv; + } + opline->op1.constant = zend_optimizer_add_literal(op_array, val); + if (Z_TYPE_P(val) == IS_STRING && Z_STRLEN_P(val) == 0) { + MAKE_NOP(opline); + } + /* TODO: In a subsequent pass, *after* this step and compacting nops, combine consecutive ZEND_ECHOs using the block information from ssa->cfg */ + /* (e.g. for ext/opcache/tests/opt/sccp_010.phpt) */ + break; + } case ZEND_CONCAT: case ZEND_FAST_CONCAT: case ZEND_FETCH_R: diff --git a/ext/opcache/tests/opt/sccp_002.phpt b/ext/opcache/tests/opt/sccp_002.phpt index 0fd10f2ac57ad..fd2b373d7332a 100644 --- a/ext/opcache/tests/opt/sccp_002.phpt +++ b/ext/opcache/tests/opt/sccp_002.phpt @@ -32,6 +32,6 @@ foo: ; (lines=4, args=1, vars=1, tmps=0) ; (after optimizer) ; %ssccp_002.php:2-12 L0 (2): CV0($x) = RECV 1 -L1 (9): ECHO int(1) -L2 (11): ECHO int(1) +L1 (9): ECHO string("1") +L2 (11): ECHO string("1") L3 (12): RETURN null diff --git a/ext/opcache/tests/opt/sccp_003.phpt b/ext/opcache/tests/opt/sccp_003.phpt index 282a5788e628b..50ed9eb759c29 100644 --- a/ext/opcache/tests/opt/sccp_003.phpt +++ b/ext/opcache/tests/opt/sccp_003.phpt @@ -31,6 +31,6 @@ L0 (14): RETURN int(1) foo: ; (lines=3, args=0, vars=0, tmps=0) ; (after optimizer) ; %ssccp_003.php:2-12 -L0 (9): ECHO int(1) -L1 (11): ECHO int(1) +L0 (9): ECHO string("1") +L1 (11): ECHO string("1") L2 (12): RETURN null diff --git a/ext/opcache/tests/opt/sccp_004.phpt b/ext/opcache/tests/opt/sccp_004.phpt index d82212e0ef004..495499f8843ea 100644 --- a/ext/opcache/tests/opt/sccp_004.phpt +++ b/ext/opcache/tests/opt/sccp_004.phpt @@ -35,6 +35,6 @@ foo: ; (lines=4, args=1, vars=1, tmps=0) ; (after optimizer) ; %ssccp_004.php:2-15 L0 (2): CV0($x) = RECV 1 -L1 (11): ECHO bool(true) -L2 (14): ECHO int(1) +L1 (11): ECHO string("1") +L2 (14): ECHO string("1") L3 (15): RETURN null diff --git a/ext/opcache/tests/opt/sccp_005.phpt b/ext/opcache/tests/opt/sccp_005.phpt index 7fbb062922fbe..1ff0d4e4ae7f5 100644 --- a/ext/opcache/tests/opt/sccp_005.phpt +++ b/ext/opcache/tests/opt/sccp_005.phpt @@ -25,5 +25,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0) ; (after optimizer) ; %ssccp_005.php:2-5 L0 (2): CV0($x) = RECV 1 -L1 (4): ECHO int(2) +L1 (4): ECHO string("2") L2 (5): RETURN null diff --git a/ext/opcache/tests/opt/sccp_007.phpt b/ext/opcache/tests/opt/sccp_007.phpt index 82feb04e226a5..c502a5c6beec8 100644 --- a/ext/opcache/tests/opt/sccp_007.phpt +++ b/ext/opcache/tests/opt/sccp_007.phpt @@ -29,5 +29,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0) ; (after optimizer) ; %ssccp_007.php:2-9 L0 (2): CV0($x) = RECV 1 -L1 (8): ECHO int(0) +L1 (8): ECHO string("0") L2 (9): RETURN null diff --git a/ext/opcache/tests/opt/sccp_009.phpt b/ext/opcache/tests/opt/sccp_009.phpt index 1b049810c136d..47612cdb29828 100644 --- a/ext/opcache/tests/opt/sccp_009.phpt +++ b/ext/opcache/tests/opt/sccp_009.phpt @@ -26,5 +26,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0) ; (after optimizer) ; %ssccp_009.php:2-6 L0 (2): CV0($x) = RECV 1 -L1 (5): ECHO int(2) +L1 (5): ECHO string("2") L2 (6): RETURN null diff --git a/ext/opcache/tests/opt/sccp_010.phpt b/ext/opcache/tests/opt/sccp_010.phpt index e88bf579f7178..a2e9945c7f646 100644 --- a/ext/opcache/tests/opt/sccp_010.phpt +++ b/ext/opcache/tests/opt/sccp_010.phpt @@ -32,6 +32,6 @@ L0 (15): RETURN int(1) foo: ; (lines=3, args=0, vars=0, tmps=0) ; (after optimizer) ; %ssccp_010.php:2-13 -L0 (10): ECHO int(1) -L1 (12): ECHO int(1) +L0 (10): ECHO string("1") +L1 (12): ECHO string("1") L2 (13): RETURN null diff --git a/ext/opcache/tests/opt/sccp_011.phpt b/ext/opcache/tests/opt/sccp_011.phpt index 281e3dca2eb00..adb2c0a3638bf 100644 --- a/ext/opcache/tests/opt/sccp_011.phpt +++ b/ext/opcache/tests/opt/sccp_011.phpt @@ -32,5 +32,5 @@ foo: ; (lines=3, args=1, vars=1, tmps=0) ; (after optimizer) ; %ssccp_011.php:2-12 L0 (2): CV0($x) = RECV 1 -L1 (11): ECHO int(0) +L1 (11): ECHO string("0") L2 (12): RETURN null diff --git a/ext/opcache/tests/opt/sccp_012.phpt b/ext/opcache/tests/opt/sccp_012.phpt index 5d2f3e9a01c9b..0e3b872e0ca22 100644 --- a/ext/opcache/tests/opt/sccp_012.phpt +++ b/ext/opcache/tests/opt/sccp_012.phpt @@ -34,6 +34,6 @@ L0 (17): RETURN int(1) foo: ; (lines=3, args=0, vars=0, tmps=0) ; (after optimizer) ; %ssccp_012.php:2-15 -L0 (10): ECHO int(1) -L1 (14): ECHO int(4) +L0 (10): ECHO string("1") +L1 (14): ECHO string("4") L2 (15): RETURN null diff --git a/ext/opcache/tests/opt/sccp_022.phpt b/ext/opcache/tests/opt/sccp_022.phpt index 40c9df5971b3b..6a6bfbfec95a4 100644 --- a/ext/opcache/tests/opt/sccp_022.phpt +++ b/ext/opcache/tests/opt/sccp_022.phpt @@ -32,7 +32,7 @@ L1 (3): ASSIGN_DIM CV1($a) int(0) L2 (3): OP_DATA CV0($x) L3 (4): ASSIGN_DIM CV1($a) int(1) L4 (4): OP_DATA int(5) -L5 (5): ECHO int(5) +L5 (5): ECHO string("5") L6 (6): ASSIGN_OBJ CV1($a) string("foo") L7 (6): OP_DATA int(5) L8 (7): T2 = FETCH_DIM_R CV1($a) int(1) diff --git a/ext/opcache/tests/opt/sccp_031.phpt b/ext/opcache/tests/opt/sccp_031.phpt new file mode 100644 index 0000000000000..0f4ff184bda23 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_031.phpt @@ -0,0 +1,36 @@ +--TEST-- +SCCP 031: Echo optimizations +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +opcache.opt_debug_level=0x20000 +opcache.preload= +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +$_main: ; (lines=1, args=0, vars=0, tmps=0) + ; (after optimizer) + ; %ssccp_031.php:1-13 +L0 (13): RETURN int(1) + +foo: ; (lines=4, args=0, vars=0, tmps=0) + ; (after optimizer) + ; %s_031.php:2-11 +L0 (6): ECHO string("b") +L1 (8): ECHO string("c") +L2 (10): ECHO array(...) +L3 (11): RETURN null From 412b476b7fb386c6aa04efb936881f5b2250ded9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 28 Jan 2020 09:15:23 +0100 Subject: [PATCH 15/80] Fix #79172: STRUCT_OFFSET() relies on undefined behavior Since this pattern is understood by compilers, not a real issue, but certainly cleaner this way. --- ext/mysqlnd/mysqlnd_portability.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/mysqlnd/mysqlnd_portability.h b/ext/mysqlnd/mysqlnd_portability.h index 873f49b0cd196..20649061933b6 100644 --- a/ext/mysqlnd/mysqlnd_portability.h +++ b/ext/mysqlnd/mysqlnd_portability.h @@ -15,7 +15,7 @@ This file is public domain and comes with NO WARRANTY of any kind */ /* Comes from global.h as OFFSET, renamed to STRUCT_OFFSET */ -#define STRUCT_OFFSET(t, f) ((size_t)(char *)&((t *)0)->f) +#define STRUCT_OFFSET(t, f) XtOffsetOf(t, f) #ifndef __attribute #if !defined(__GNUC__) From 136f51f1e1ce25a7d0150857d0846be8c8415a44 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Jan 2020 13:33:07 +0100 Subject: [PATCH 16/80] Fix #76584: PharFileInfo::decompress not working We actually have to decompress, when told to do so. --- NEWS | 3 +++ ext/phar/phar_object.c | 23 ++++++++++++++++++----- ext/phar/tests/bug76584.phpt | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 ext/phar/tests/bug76584.phpt diff --git a/NEWS b/NEWS index fe4c2d37310ad..fc8aac06018e3 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,9 @@ PHP NEWS - OpenSSL: . Fixed bug #79145 (openssl memory leak). (cmb, Nikita) +- Phar: + . Fixed bug #76584 (PharFileInfo::decompress not working). (cmb) + - Reflection: . Fixed bug #79115 (ReflectionClass::isCloneable call reflected class __destruct). (Nikita) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index ed5c546adc5f4..e44bb56231450 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -5011,6 +5011,7 @@ PHP_METHOD(PharFileInfo, compress) PHP_METHOD(PharFileInfo, decompress) { char *error; + char *compression_type; PHAR_ENTRY_OBJECT(); if (zend_parse_parameters_none() == FAILURE) { @@ -5061,12 +5062,24 @@ PHP_METHOD(PharFileInfo, decompress) /* re-populate after copy-on-write */ entry_obj->entry = zend_hash_str_find_ptr(&phar->manifest, entry_obj->entry->filename, entry_obj->entry->filename_len); } - if (!entry_obj->entry->fp) { - if (FAILURE == phar_open_archive_fp(entry_obj->entry->phar)) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Cannot decompress entry \"%s\", phar error: Cannot open phar archive \"%s\" for reading", entry_obj->entry->filename, entry_obj->entry->phar->fname); + switch (entry_obj->entry->flags & PHAR_ENT_COMPRESSION_MASK) { + case PHAR_ENT_COMPRESSED_GZ: + compression_type = "gzip"; + break; + case PHAR_ENT_COMPRESSED_BZ2: + compression_type = "bz2"; + break; + default: + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, + "Cannot decompress file compressed with unknown compression type"); return; - } - entry_obj->entry->fp_type = PHAR_FP; + } + /* decompress this file indirectly */ + if (SUCCESS != phar_open_entry_fp(entry_obj->entry, &error, 1)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, + "Phar error: Cannot decompress %s-compressed file \"%s\" in phar \"%s\": %s", compression_type, entry_obj->entry->filename, entry_obj->entry->phar->fname, error); + efree(error); + return; } entry_obj->entry->old_flags = entry_obj->entry->flags; diff --git a/ext/phar/tests/bug76584.phpt b/ext/phar/tests/bug76584.phpt new file mode 100644 index 0000000000000..b37de08c49459 --- /dev/null +++ b/ext/phar/tests/bug76584.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #76584 (PharFileInfo::decompress not working) +--SKIPIF-- + +--INI-- +phar.readonly=0 +--FILE-- +addFromString('76584.txt', 'This is a test file.'); +$file = $phar['76584.txt']; +var_dump($file->compress(Phar::GZ)); +var_dump($file->isCompressed()); +var_dump($file->decompress()); +var_dump($file->isCompressed()); +mkdir(__DIR__ . '/76584'); +var_dump($phar->extractTo(__DIR__ . '/76584')); +echo file_get_contents(__DIR__ . '/76584/76584.txt'); +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) +This is a test file. +--CLEAN-- + From 1146bdb9b21cdf725dd5ea8882221356779926b6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 10:41:11 +0100 Subject: [PATCH 17/80] Fixed bug #78989 Always operate on copies of the functions, so we don't reference temporary trait methods that have gone out of scope. This could be more efficient, but doing an allocated copy only when strictly necessary turned out to be somewhat tricky. --- NEWS | 2 ++ .../variance/parent_in_class_success.phpt | 27 +++++++++++++++++ .../variance/property_types_early_bind.phpt | 19 ++++++++++++ .../variance/trait_error.phpt | 20 +++++++++++++ .../variance/trait_success.phpt | 29 +++++++++++++++++++ Zend/zend_inheritance.c | 18 +++++++----- 6 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 Zend/tests/type_declarations/variance/parent_in_class_success.phpt create mode 100644 Zend/tests/type_declarations/variance/property_types_early_bind.phpt create mode 100644 Zend/tests/type_declarations/variance/trait_error.phpt create mode 100644 Zend/tests/type_declarations/variance/trait_success.phpt diff --git a/NEWS b/NEWS index 66ef7e0e5c040..be17e672a6217 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS . Fixed bug #79155 (Property nullability lost when using multiple property definition). (Nikita) . Fixed bug #78323 (Code 0 is returned on invalid options). (Ivan Mikheykin) + . Fixed bug #78989 (Delayed variance check involving trait segfaults). + (Nikita) - CURL: . Fixed bug #79078 (Hypothetical use-after-free in curl_multi_add_handle()). diff --git a/Zend/tests/type_declarations/variance/parent_in_class_success.phpt b/Zend/tests/type_declarations/variance/parent_in_class_success.phpt new file mode 100644 index 0000000000000..c3edceaf3bdc2 --- /dev/null +++ b/Zend/tests/type_declarations/variance/parent_in_class_success.phpt @@ -0,0 +1,27 @@ +--TEST-- +Use of parent inside a class that has / has no parent (success cases) +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/type_declarations/variance/property_types_early_bind.phpt b/Zend/tests/type_declarations/variance/property_types_early_bind.phpt new file mode 100644 index 0000000000000..ca3fe1d3ca6be --- /dev/null +++ b/Zend/tests/type_declarations/variance/property_types_early_bind.phpt @@ -0,0 +1,19 @@ +--TEST-- +Early binding should be prevented if property types cannot be checked +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/tests/type_declarations/variance/trait_error.phpt b/Zend/tests/type_declarations/variance/trait_error.phpt new file mode 100644 index 0000000000000..667b177a5b931 --- /dev/null +++ b/Zend/tests/type_declarations/variance/trait_error.phpt @@ -0,0 +1,20 @@ +--TEST-- +Trait delayed variance check fails +--FILE-- + +--EXPECTF-- +Fatal error: Could not check compatibility between T::method($r): B and X::method($a): A, because class B is not available in %s on line %d diff --git a/Zend/tests/type_declarations/variance/trait_success.phpt b/Zend/tests/type_declarations/variance/trait_success.phpt new file mode 100644 index 0000000000000..1efadc00b439d --- /dev/null +++ b/Zend/tests/type_declarations/variance/trait_success.phpt @@ -0,0 +1,29 @@ +--TEST-- +Trait delayed variance check succeeds +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 9a11269801073..442ab8afc14b8 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2237,8 +2237,10 @@ typedef struct { union { zend_class_entry *dependency_ce; struct { - const zend_function *parent_fn; - const zend_function *child_fn; + /* Traits may use temporary on-stack functions during inheritance checks, + * so use copies of functions here as well. */ + zend_function parent_fn; + zend_function child_fn; zend_bool always_error; }; struct { @@ -2292,8 +2294,8 @@ static void add_compatibility_obligation( HashTable *obligations = get_or_init_obligations_for_class(ce); variance_obligation *obligation = emalloc(sizeof(variance_obligation)); obligation->type = OBLIGATION_COMPATIBILITY; - obligation->child_fn = child_fn; - obligation->parent_fn = parent_fn; + obligation->child_fn = *child_fn; + obligation->parent_fn = *parent_fn; obligation->always_error = always_error; zend_hash_next_index_insert_ptr(obligations, obligation); } @@ -2324,7 +2326,7 @@ static int check_variance_obligation(zval *zv) { } else if (obligation->type == OBLIGATION_COMPATIBILITY) { zend_string *unresolved_class; inheritance_status status = zend_do_perform_implementation_check( - &unresolved_class, obligation->child_fn, obligation->parent_fn); + &unresolved_class, &obligation->child_fn, &obligation->parent_fn); if (UNEXPECTED(status != INHERITANCE_SUCCESS)) { if (EXPECTED(status == INHERITANCE_UNRESOLVED)) { @@ -2332,7 +2334,7 @@ static int check_variance_obligation(zval *zv) { } ZEND_ASSERT(status == INHERITANCE_ERROR); emit_incompatible_method_error_or_warning( - obligation->child_fn, obligation->parent_fn, status, unresolved_class, + &obligation->child_fn, &obligation->parent_fn, status, unresolved_class, obligation->always_error); } /* Either the compatibility check was successful or only threw a warning. */ @@ -2402,10 +2404,10 @@ static void report_variance_errors(zend_class_entry *ce) { if (obligation->type == OBLIGATION_COMPATIBILITY) { /* Just used to fetch the unresolved_class in this case. */ status = zend_do_perform_implementation_check( - &unresolved_class, obligation->child_fn, obligation->parent_fn); + &unresolved_class, &obligation->child_fn, &obligation->parent_fn); ZEND_ASSERT(status == INHERITANCE_UNRESOLVED); emit_incompatible_method_error_or_warning( - obligation->child_fn, obligation->parent_fn, + &obligation->child_fn, &obligation->parent_fn, status, unresolved_class, obligation->always_error); } else if (obligation->type == OBLIGATION_PROPERTY_COMPATIBILITY) { emit_incompatible_property_error(obligation->child_prop, obligation->parent_prop); From ac9a265f01385f50718f732b1a5badd2f31469b4 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 28 Jan 2020 10:52:09 +0100 Subject: [PATCH 18/80] - bump zip extension version to 1.16.0 - add ZipArchive::setMtimeName and ZipArchive::setMtimeIndex methods --- NEWS | 1 + ext/zip/config.m4 | 9 ++++ ext/zip/php_zip.c | 65 +++++++++++++++++++++++++++++ ext/zip/php_zip.h | 2 +- ext/zip/php_zip.stub.php | 6 +++ ext/zip/php_zip_arginfo.h | 12 ++++++ ext/zip/tests/oo_setmtime.phpt | 76 ++++++++++++++++++++++++++++++++++ 7 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 ext/zip/tests/oo_setmtime.phpt diff --git a/NEWS b/NEWS index 8290ac3d81ac9..effc968cf40a6 100644 --- a/NEWS +++ b/NEWS @@ -118,5 +118,6 @@ PHP NEWS - Zip: . Fixed bug #72374 (remove_path strips first char of filename). (tyage) + . Add ZipArchive::setMtimeName and ZipArchive::setMtimeIndex methods <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 0b151b7f2ae32..669adb6b9aeda 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -9,6 +9,15 @@ if test "$PHP_ZIP" != "no"; then PHP_EVAL_INCLINE($LIBZIP_CFLAGS) PHP_EVAL_LIBLINE($LIBZIP_LIBS, ZIP_SHARED_LIBADD) + PHP_CHECK_LIBRARY(zip, zip_file_set_mtime, + [ + AC_DEFINE(HAVE_SET_MTIME, 1, [Libzip >= 1.0.0 with zip_file_set_mtime]) + ], [ + AC_MSG_WARN(Libzip >= 1.0.0 needed for setting mtime) + ], [ + -L$LIBZIP_LIBDIR + ]) + PHP_CHECK_LIBRARY(zip, zip_file_set_encryption, [ AC_DEFINE(HAVE_ENCRYPTION, 1, [Libzip >= 1.2.0 with encryption support]) diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index d39ad316ae9b6..1218d707f0ab5 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -2301,6 +2301,67 @@ static ZIPARCHIVE_METHOD(setCompressionIndex) } /* }}} */ +#ifdef HAVE_SET_MTIME +/* {{{ proto bool ZipArchive::setMtimeName(string name, int timestamp[, int flags]) +Set the modification time of a file in zip, using its name */ +static ZIPARCHIVE_METHOD(setMtimeName) + { + struct zip *intern; + zval *this = ZEND_THIS; + size_t name_len; + char *name; + zip_int64_t idx; + zend_long mtime, flags = 0; + + ZIP_FROM_OBJECT(intern, this); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sl|l", + &name, &name_len, &mtime, &flags) == FAILURE) { + return; + } + + if (name_len < 1) { + php_error_docref(NULL, E_NOTICE, "Empty string as entry name"); + } + + idx = zip_name_locate(intern, name, 0); + if (idx < 0) { + RETURN_FALSE; + } + + if (zip_file_set_mtime(intern, (zip_uint64_t)idx, + (time_t)mtime, (zip_uint32_t)flags) != 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto bool ZipArchive::setMtimeIndex(int index, int timestamp[, int flags]) +Set the modification time of a file in zip, using its index */ +static ZIPARCHIVE_METHOD(setMtimeIndex) +{ + struct zip *intern; + zval *this = ZEND_THIS; + zend_long index; + zend_long mtime, flags = 0; + + ZIP_FROM_OBJECT(intern, this); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll|l", + &index, &mtime, &flags) == FAILURE) { + return; + } + + if (zip_file_set_mtime(intern, (zip_uint64_t)index, + (time_t)mtime, (zip_uint32_t)flags) != 0) { + RETURN_FALSE; + } + RETURN_TRUE; +} +/* }}} */ +#endif + /* {{{ proto bool ZipArchive::deleteIndex(int index) Delete a file using its index */ static ZIPARCHIVE_METHOD(deleteIndex) @@ -2755,6 +2816,10 @@ static const zend_function_entry zip_class_functions[] = { #endif ZIPARCHIVE_ME(setCompressionName, arginfo_class_ZipArchive_setCompressionName, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(setCompressionIndex, arginfo_class_ZipArchive_setCompressionIndex, ZEND_ACC_PUBLIC) +#ifdef HAVE_SET_MTIME + ZIPARCHIVE_ME(setMtimeName, arginfo_class_ZipArchive_setMtimeName, ZEND_ACC_PUBLIC) + ZIPARCHIVE_ME(setMtimeIndex, arginfo_class_ZipArchive_setMtimeIndex, ZEND_ACC_PUBLIC) +#endif #ifdef HAVE_ENCRYPTION ZIPARCHIVE_ME(setEncryptionName, arginfo_class_ZipArchive_setEncryptionName, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(setEncryptionIndex, arginfo_class_ZipArchive_setEncryptionIndex, ZEND_ACC_PUBLIC) diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index f900632e56288..d1f46ea4ea24c 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -31,7 +31,7 @@ extern zend_module_entry zip_module_entry; #define ZIP_OVERWRITE ZIP_TRUNCATE #endif -#define PHP_ZIP_VERSION "1.15.6" +#define PHP_ZIP_VERSION "1.16.0" #define ZIP_OPENBASEDIR_CHECKPATH(filename) php_check_open_basedir(filename) diff --git a/ext/zip/php_zip.stub.php b/ext/zip/php_zip.stub.php index e312bfd0312d0..c88d2742eeee8 100644 --- a/ext/zip/php_zip.stub.php +++ b/ext/zip/php_zip.stub.php @@ -90,6 +90,12 @@ public function setCommentIndex(int $index, string $comment) {} /** @return null|false */ public function setCommentName(string $name, string $comment) {} + /** @return null|false */ + public function setMtimeIndex(int $index, int $timestamp, int $flags = 0) {} + + /** @return null|false */ + public function setMtimeName(string $name, int $timestamp, int $flags = 0) {} + /** @return string|false */ public function getCommentIndex(int $index, int $flags = 0) {} diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index ed5ecc6a31263..4839eb68b4afe 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -111,6 +111,18 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setCommentName, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, comment, IS_STRING, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setMtimeIndex, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setMtimeName, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_getCommentIndex, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) diff --git a/ext/zip/tests/oo_setmtime.phpt b/ext/zip/tests/oo_setmtime.phpt new file mode 100644 index 0000000000000..aa1ceb56bb7b8 --- /dev/null +++ b/ext/zip/tests/oo_setmtime.phpt @@ -0,0 +1,76 @@ +--TEST-- +setMtime +--SKIPIF-- + +--INI-- +date.timezone=UTC +--FILE-- +open($file, ZIPARCHIVE::CREATE)) { + exit('failed'); +} + +$zip->addFromString('foo', 'entry #1'); +$zip->addFromString('bar', 'entry #2'); + +$t1 = mktime(0,0,0,12,25,2019); +$t2 = mktime(0,0,0,14,7,2018); + +echo "Set 1\n"; +$s = $zip->statName('foo'); +var_dump($s['mtime'] > $t1); +var_dump($zip->setMtimeName('foo', $t1)); +$s = $zip->statName('foo'); +// ONLY with 1.6.0 - var_dump($s['mtime'] == $t1); + +echo "Set 2\n"; +$s = $zip->statIndex(1); +var_dump($s['mtime'] > $t2); +var_dump($zip->setMtimeIndex(1, $t2)); +$s = $zip->statIndex(1); +// ONLY with 1.6.0 - var_dump($s['mtime'] == $t2); + +if (!$zip->status == ZIPARCHIVE::ER_OK) { + echo "failed to write zip\n"; +} +$zip->close(); + +if (!$zip->open($file)) { + @unlink($file); + exit('failed'); +} + +echo "Get 1\n"; +$s = $zip->statIndex(0); +var_dump($s['mtime'] == $t1); + +echo "Get 2\n"; +$s = $zip->statName('bar'); +var_dump($s['mtime'] == $t2); + +$zip->close(); +@unlink($file); + +?> +--EXPECTF-- +Set 1 +bool(true) +bool(true) +Set 2 +bool(true) +bool(true) +Get 1 +bool(true) +Get 2 +bool(true) From 521c4051083d79255a52aa427d073727e3cc000a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 11:16:53 +0100 Subject: [PATCH 19/80] Don't index NULL pointer when fetching non-existent constant --- Zend/zend_constants.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 0885525676bff..958bd36d1dab5 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -454,12 +454,15 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, } } - if (!(flags & ZEND_FETCH_CLASS_SILENT)) { - if (!c) { + if (!c) { + if (!(flags & ZEND_FETCH_CLASS_SILENT)) { zend_throw_error(NULL, "Undefined constant '%s'", name); - } else if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) { - zend_error(E_DEPRECATED, "Constant %s is deprecated", name); } + return NULL; + } + + if (!(flags & ZEND_FETCH_CLASS_SILENT) && (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED)) { + zend_error(E_DEPRECATED, "Constant %s is deprecated", name); } return &c->value; } From c59219de85a82548e7ba12399b95eae9087b3dfd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 11:23:16 +0100 Subject: [PATCH 20/80] Perform map ptr base arithmetic through uintptr_t Adding an offset to the NULL pointer is undefined behavior. Avoid this by performing arithmetic on uintptr_t instead. --- Zend/zend_map_ptr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_map_ptr.h b/Zend/zend_map_ptr.h index 46596b5c37f2b..c6930473cf724 100644 --- a/Zend/zend_map_ptr.h +++ b/Zend/zend_map_ptr.h @@ -80,9 +80,9 @@ ZEND_MAP_PTR(ptr) = zend_map_ptr_new(); \ } while (0) # define ZEND_MAP_PTR_REAL_BASE(base) \ - ((void*)(((char*)(base)) + 1)) + ((void*)(((uintptr_t)(base)) + 1)) # define ZEND_MAP_PTR_SET_REAL_BASE(base, ptr) do { \ - base = (void*)(((char*)(ptr)) - 1); \ + base = (void*)(((uintptr_t)(ptr)) - 1); \ } while (0) #else # error "Unknown ZEND_MAP_PTR_KIND" From d91abf76e01a3c39424e8192ad049f473f900936 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 28 Jan 2020 11:32:42 +0100 Subject: [PATCH 21/80] zip: fix lib check --- ext/zip/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 669adb6b9aeda..943852e4e6102 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -15,7 +15,7 @@ if test "$PHP_ZIP" != "no"; then ], [ AC_MSG_WARN(Libzip >= 1.0.0 needed for setting mtime) ], [ - -L$LIBZIP_LIBDIR + $LIBZIP_LIBS ]) PHP_CHECK_LIBRARY(zip, zip_file_set_encryption, From 2342c06584cec50645945ba19321dc16786e02ca Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 12:33:58 +0100 Subject: [PATCH 22/80] Throw an exception if default_dir not set, but required Previously the RETURN_THROWS() assertion failed for this case. --- ext/standard/dir.c | 6 ++++-- ext/standard/tests/dir/closedir_without_arg.phpt | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 ext/standard/tests/dir/closedir_without_arg.phpt diff --git a/ext/standard/dir.c b/ext/standard/dir.c index d2b3736089b5c..5554a689b35b8 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -74,8 +74,10 @@ static zend_class_entry *dir_class_entry_ptr; RETURN_THROWS(); \ } \ } else { \ - if (!DIRG(default_dir) || \ - (dirp = (php_stream *)zend_fetch_resource(DIRG(default_dir), "Directory", php_file_le_stream())) == NULL) { \ + if (!DIRG(default_dir)) { \ + zend_type_error("No resource supplied"); \ + RETURN_THROWS(); \ + } else if ((dirp = (php_stream *)zend_fetch_resource(DIRG(default_dir), "Directory", php_file_le_stream())) == NULL) { \ RETURN_THROWS(); \ } \ } \ diff --git a/ext/standard/tests/dir/closedir_without_arg.phpt b/ext/standard/tests/dir/closedir_without_arg.phpt new file mode 100644 index 0000000000000..27884c1a2b645 --- /dev/null +++ b/ext/standard/tests/dir/closedir_without_arg.phpt @@ -0,0 +1,12 @@ +--TEST-- +Calling closedir() without argument and without opening a directory beforehand +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +No resource supplied From 648f16c2ec27800411b00a7fd07fa9c7e0db7f25 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 13:11:49 +0100 Subject: [PATCH 23/80] Fix rel_date leak on DateInterval construction failure --- ext/date/php_date.c | 3 +++ ext/date/tests/date_interval_bad_format_leak.phpt | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 ext/date/tests/date_interval_bad_format_leak.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 0f6432b1a79f9..8b1bda20f0b92 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -3838,6 +3838,9 @@ static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *forma if (errors->error_count > 0) { php_error_docref(NULL, E_WARNING, "Unknown or bad format (%s)", format); retval = FAILURE; + if (p) { + timelib_rel_time_dtor(p); + } } else { if(p) { *rt = p; diff --git a/ext/date/tests/date_interval_bad_format_leak.phpt b/ext/date/tests/date_interval_bad_format_leak.phpt new file mode 100644 index 0000000000000..9d8af25ea4d4c --- /dev/null +++ b/ext/date/tests/date_interval_bad_format_leak.phpt @@ -0,0 +1,14 @@ +--TEST-- +DateInterval with bad format should not leak period +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +DateInterval::__construct(): Unknown or bad format (P3"D) From d7052765ed0b3b957ba4562f900ee528c132f78b Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 28 Jan 2020 13:30:53 +0100 Subject: [PATCH 24/80] Enable support for LIBZIP_VERSION This is already supported by non Windows builds for libzip >= 1.3.1, and since we're using at least libzip 1.4.0 on Windows, we should support it there as well. --- ext/zip/config.w32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index 2ac637189c65a..034543fabd8cf 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -15,7 +15,7 @@ if (PHP_ZIP != "no") { } AC_DEFINE('HAVE_ZIP', 1); - ADD_FLAG("CFLAGS_ZIP", "/D _WIN32 /D HAVE_ENCRYPTION"); + ADD_FLAG("CFLAGS_ZIP", "/D _WIN32 /D HAVE_ENCRYPTION /D HAVE_LIBZIP_VERSION"); } else { WARNING("zip not enabled; libraries and headers not found"); } From b0d7b126a29a1972229ac91d6d28f5331912eddb Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 14:42:19 +0100 Subject: [PATCH 25/80] Make BG(syslog_device) per request This is not supposed to be retained across requests. Explicitly free it at the end of a request, and use the per-request allocator. --- ext/standard/syslog.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/standard/syslog.c b/ext/standard/syslog.c index b07f6d6a51c94..d5a8fa6e2b418 100644 --- a/ext/standard/syslog.c +++ b/ext/standard/syslog.c @@ -91,7 +91,6 @@ PHP_MINIT_FUNCTION(syslog) /* AIX doesn't have LOG_PERROR */ REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ #endif - BG(syslog_device)=NULL; return SUCCESS; } @@ -108,16 +107,16 @@ PHP_RINIT_FUNCTION(syslog) PHP_RSHUTDOWN_FUNCTION(syslog) { closelog(); + if (BG(syslog_device)) { + efree(BG(syslog_device)); + BG(syslog_device) = NULL; + } return SUCCESS; } #endif PHP_MSHUTDOWN_FUNCTION(syslog) { - if (BG(syslog_device)) { - free(BG(syslog_device)); - BG(syslog_device) = NULL; - } return SUCCESS; } @@ -147,9 +146,9 @@ PHP_FUNCTION(openlog) ZEND_PARSE_PARAMETERS_END(); if (BG(syslog_device)) { - free(BG(syslog_device)); + efree(BG(syslog_device)); } - BG(syslog_device) = zend_strndup(ident, ident_len); + BG(syslog_device) = estrndup(ident, ident_len); if(BG(syslog_device) == NULL) { RETURN_FALSE; } @@ -166,8 +165,8 @@ PHP_FUNCTION(closelog) closelog(); if (BG(syslog_device)) { - free(BG(syslog_device)); - BG(syslog_device)=NULL; + efree(BG(syslog_device)); + BG(syslog_device) = NULL; } RETURN_TRUE; } From 7db3a51884b12175d6b12e9fd13665d18a064905 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 15:12:24 +0100 Subject: [PATCH 26/80] Only fetch to_encoding once in mb_convert_encoding() Instead of doing it on every conversion. This is both more efficient and avoids generating multiple warnings. --- ext/mbstring/mbstring.c | 37 ++++++++++++++++--------------------- ext/mbstring/mbstring.h | 2 +- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index de4ccfc4278de..402ec11d09007 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2691,9 +2691,9 @@ MBSTRING_API char *php_mb_convert_encoding_ex(const char *input, size_t length, /* }}} */ /* {{{ MBSTRING_API char *php_mb_convert_encoding() */ -MBSTRING_API char *php_mb_convert_encoding(const char *input, size_t length, const char *_to_encoding, const char *_from_encodings, size_t *output_len) +MBSTRING_API char *php_mb_convert_encoding(const char *input, size_t length, const mbfl_encoding *to_encoding, const char *_from_encodings, size_t *output_len) { - const mbfl_encoding *from_encoding, *to_encoding; + const mbfl_encoding *from_encoding; if (output_len) { *output_len = 0; @@ -2701,16 +2701,6 @@ MBSTRING_API char *php_mb_convert_encoding(const char *input, size_t length, con if (!input) { return NULL; } - /* new encoding */ - if (_to_encoding && strlen(_to_encoding)) { - to_encoding = mbfl_name2encoding(_to_encoding); - if (!to_encoding) { - php_error_docref(NULL, E_WARNING, "Unknown encoding \"%s\"", _to_encoding); - return NULL; - } - } else { - to_encoding = MBSTRG(current_internal_encoding); - } /* pre-conversion encoding */ from_encoding = MBSTRG(current_internal_encoding); @@ -2743,7 +2733,7 @@ MBSTRING_API char *php_mb_convert_encoding(const char *input, size_t length, con } /* }}} */ -MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, const char *_to_encoding, const char *_from_encodings) +MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, const mbfl_encoding *to_encoding, const char *_from_encodings) { HashTable *output, *chash; zend_long idx; @@ -2766,7 +2756,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons ZEND_HASH_FOREACH_KEY_VAL(input, idx, key, entry) { /* convert key */ if (key) { - ckey = php_mb_convert_encoding(ZSTR_VAL(key), ZSTR_LEN(key), _to_encoding, _from_encodings, &ckey_len); + ckey = php_mb_convert_encoding(ZSTR_VAL(key), ZSTR_LEN(key), to_encoding, _from_encodings, &ckey_len); key = zend_string_init(ckey, ckey_len, 0); efree(ckey); } @@ -2774,7 +2764,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons ZEND_ASSERT(entry); switch(Z_TYPE_P(entry)) { case IS_STRING: - cval = php_mb_convert_encoding(Z_STRVAL_P(entry), Z_STRLEN_P(entry), _to_encoding, _from_encodings, &cval_len); + cval = php_mb_convert_encoding(Z_STRVAL_P(entry), Z_STRLEN_P(entry), to_encoding, _from_encodings, &cval_len); ZVAL_STRINGL(&entry_tmp, cval, cval_len); efree(cval); break; @@ -2786,7 +2776,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons ZVAL_COPY(&entry_tmp, entry); break; case IS_ARRAY: - chash = php_mb_convert_encoding_recursive(Z_ARRVAL_P(entry), _to_encoding, _from_encodings); + chash = php_mb_convert_encoding_recursive(Z_ARRVAL_P(entry), to_encoding, _from_encodings); if (chash) { ZVAL_ARR(&entry_tmp, chash); } else { @@ -2820,19 +2810,24 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons PHP_FUNCTION(mb_convert_encoding) { zval *input; - char *arg_new; - size_t new_len; zval *arg_old = NULL; size_t size, l, n; char *_from_encodings = NULL, *ret, *s_free = NULL; + zend_string *to_encoding_name; + const mbfl_encoding *to_encoding; zval *hash_entry; HashTable *target_hash; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs|z", &input, &arg_new, &new_len, &arg_old) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "zS|z", &input, &to_encoding_name, &arg_old) == FAILURE) { RETURN_THROWS(); } + to_encoding = php_mb_get_encoding(to_encoding_name); + if (!to_encoding) { + RETURN_FALSE; + } + if (Z_TYPE_P(input) != IS_STRING && Z_TYPE_P(input) != IS_ARRAY) { if (!try_convert_to_string(input)) { RETURN_THROWS(); @@ -2884,7 +2879,7 @@ PHP_FUNCTION(mb_convert_encoding) if (Z_TYPE_P(input) == IS_STRING) { /* new encoding */ - ret = php_mb_convert_encoding(Z_STRVAL_P(input), Z_STRLEN_P(input), arg_new, _from_encodings, &size); + ret = php_mb_convert_encoding(Z_STRVAL_P(input), Z_STRLEN_P(input), to_encoding, _from_encodings, &size); if (ret != NULL) { // TODO: avoid reallocation ??? RETVAL_STRINGL(ret, size); /* the string is already strdup()'ed */ @@ -2897,7 +2892,7 @@ PHP_FUNCTION(mb_convert_encoding) } } else { HashTable *tmp; - tmp = php_mb_convert_encoding_recursive(Z_ARRVAL_P(input), arg_new, _from_encodings); + tmp = php_mb_convert_encoding_recursive(Z_ARRVAL_P(input), to_encoding, _from_encodings); RETURN_ARR(tmp); } diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index 1928030381c1c..48a33023fc684 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -118,7 +118,7 @@ MBSTRING_API char *php_mb_convert_encoding_ex( const char *input, size_t length, const mbfl_encoding *to_encoding, const mbfl_encoding *from_encoding, size_t *output_len); MBSTRING_API char * php_mb_convert_encoding(const char *input, size_t length, - const char *_to_encoding, + const mbfl_encoding *to_encoding, const char *_from_encodings, size_t *output_len); From d91b166c3a6dcc18dfdcc4d549746fe29bd0b4d3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 15:33:33 +0100 Subject: [PATCH 27/80] Avoid shift UB for large arrays Don't shift into the sign bit. --- Zend/zend_hash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 79a2f52d6c00e..7a251ecaca1f8 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -102,14 +102,14 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize) #if defined(ZEND_WIN32) if (BitScanReverse(&index, nSize - 1)) { - return 0x2 << ((31 - index) ^ 0x1f); + return 0x2u << ((31 - index) ^ 0x1f); } else { /* nSize is ensured to be in the valid range, fall back to it rather than using an undefined bis scan result. */ return nSize; } #elif (defined(__GNUC__) || __has_builtin(__builtin_clz)) && defined(PHP_HAVE_BUILTIN_CLZ) - return 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f); + return 0x2u << (__builtin_clz(nSize - 1) ^ 0x1f); #else nSize -= 1; nSize |= (nSize >> 1); From addc3c92f2956b4efea9d78f34262403adc393ad Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 28 Jan 2020 15:11:59 +0100 Subject: [PATCH 28/80] Fix #79174: cookie values with spaces fail to round-trip The fix for bug #78929 disabled the conversion of spaces in cookie values to plus signs, but failed to adapt `php_setcookie()` accordingly, so that it uses raw URL encoding as well. --- NEWS | 1 + ext/standard/head.c | 2 +- ext/standard/tests/network/setcookie.phpt | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index be17e672a6217..c80597e6fdf5b 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ PHP NEWS . Fixed bug #78323 (Code 0 is returned on invalid options). (Ivan Mikheykin) . Fixed bug #78989 (Delayed variance check involving trait segfaults). (Nikita) + . Fixed bug #79174 (cookie values with spaces fail to round-trip). (cmb) - CURL: . Fixed bug #79078 (Hypothetical use-after-free in curl_multi_add_handle()). diff --git a/ext/standard/head.c b/ext/standard/head.c index 91b12108bf32e..4d15815076335 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -125,7 +125,7 @@ PHPAPI int php_setcookie(zend_string *name, zend_string *value, time_t expires, smart_str_append(&buf, name); smart_str_appendc(&buf, '='); if (url_encode) { - zend_string *encoded_value = php_url_encode(ZSTR_VAL(value), ZSTR_LEN(value)); + zend_string *encoded_value = php_raw_url_encode(ZSTR_VAL(value), ZSTR_LEN(value)); smart_str_append(&buf, encoded_value); zend_string_release_ex(encoded_value, 0); } else { diff --git a/ext/standard/tests/network/setcookie.phpt b/ext/standard/tests/network/setcookie.phpt index d41bed01f4e9e..1033b7bbbe76e 100644 --- a/ext/standard/tests/network/setcookie.phpt +++ b/ext/standard/tests/network/setcookie.phpt @@ -24,7 +24,7 @@ $expected = array( 'Set-Cookie: name=deleted; expires='.date('D, d-M-Y H:i:s', 1).' GMT; Max-Age=0', 'Set-Cookie: name=deleted; expires='.date('D, d-M-Y H:i:s', 1).' GMT; Max-Age=0', 'Set-Cookie: name=value', - 'Set-Cookie: name=space+value', + 'Set-Cookie: name=space%20value', 'Set-Cookie: name=value', 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsp).' GMT; Max-Age=5', 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsn).' GMT; Max-Age=0', From 8a5bc8c6be8e9ea5b7480a99f1e9b8c4bd6466e6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 17:12:45 +0100 Subject: [PATCH 29/80] Fix mysqli_get_warnings() with multi queries In this case warning_count may be non-zero, but php_get_warnings() may still return no warnings. In this case we should return false rather than returning a corrupted mysqli_warning object. --- ext/mysqli/mysqli_nonapi.c | 10 ++++++---- ext/mysqli/tests/bug54221.phpt | 1 - 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index ef20f9801913a..e3f64ae275271 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -973,7 +973,7 @@ PHP_FUNCTION(mysqli_get_warnings) MY_MYSQL *mysql; zval *mysql_link; MYSQLI_RESOURCE *mysqli_resource; - MYSQLI_WARNING *w; + MYSQLI_WARNING *w = NULL; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) { return; @@ -986,7 +986,8 @@ PHP_FUNCTION(mysqli_get_warnings) #else w = php_get_warnings(mysql->mysql); #endif - } else { + } + if (!w) { RETURN_FALSE; } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); @@ -1002,7 +1003,7 @@ PHP_FUNCTION(mysqli_stmt_get_warnings) MY_STMT *stmt; zval *stmt_link; MYSQLI_RESOURCE *mysqli_resource; - MYSQLI_WARNING *w; + MYSQLI_WARNING *w = NULL; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) { return; @@ -1011,7 +1012,8 @@ PHP_FUNCTION(mysqli_stmt_get_warnings) if (mysqli_stmt_warning_count(stmt->stmt)) { w = php_get_warnings(mysqli_stmt_get_connection(stmt->stmt)); - } else { + } + if (!w) { RETURN_FALSE; } mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE)); diff --git a/ext/mysqli/tests/bug54221.phpt b/ext/mysqli/tests/bug54221.phpt index 8346ccfbee314..eef4695327ca7 100644 --- a/ext/mysqli/tests/bug54221.phpt +++ b/ext/mysqli/tests/bug54221.phpt @@ -42,6 +42,5 @@ mysqli.reconnect = Off print "done!"; ?> --EXPECT-- -Warning: : Warning: 1050: Table 't54221' already exists done! From 9fcaf25c93aed2f70343d9f092627570ff1946e3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 17:39:37 +0100 Subject: [PATCH 30/80] Fix memory leak in mb_str_split --- ext/mbstring/mbstring.c | 1 + ext/mbstring/tests/mb_str_split_utf8_utf16.phpt | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index c0ba05cba38d8..78557e7f942f0 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2461,6 +2461,7 @@ PHP_FUNCTION(mb_str_split) mbfl_convert_filter_delete(decoder); mbfl_convert_filter_delete(filter); + mbfl_memory_device_clear(&device); return; } diff --git a/ext/mbstring/tests/mb_str_split_utf8_utf16.phpt b/ext/mbstring/tests/mb_str_split_utf8_utf16.phpt index b8234bb322527..d53dd088dec8e 100644 --- a/ext/mbstring/tests/mb_str_split_utf8_utf16.phpt +++ b/ext/mbstring/tests/mb_str_split_utf8_utf16.phpt @@ -69,6 +69,10 @@ foreach(mb_str_split($utf16le_bad, 1, "UTF-16LE") as $chunk){ } echo PHP_EOL; +var_dump(mb_str_split("", 1, "ASCII")); +var_dump(mb_str_split("", 1, "UTF-8")); +var_dump(mb_str_split("", 1, "UTF-16LE")); + ?> --EXPECT-- UTF-8: l:2 v:3132 l:5 v:33f09280a9 @@ -77,5 +81,9 @@ UTF-16BE: l:4 v:d800dc00 l:4 v:dbffdfff UTF-16LE: l:4 v:00d800dc l:4 v:ffdbffdf BAD UTF-16BE: l:4 v:d800dc00 l:2 v:003f l:2 v:003f BAD UTF-16LE: l:4 v:00d800dc l:2 v:3f00 l:2 v:3f00 - - +array(0) { +} +array(0) { +} +array(0) { +} From d39edebbce35890aafd77cc47e1830e851287219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 24 Jan 2020 20:08:32 +0100 Subject: [PATCH 31/80] Fix #78666 mysqli_options generates Warning on var_dump() Closes GH-5121 --- NEWS | 3 + ext/mysqli/mysqli.c | 18 ++- ext/mysqli/mysqli_driver.c | 32 +++-- ext/mysqli/mysqli_prop.c | 121 ++++++++++-------- ext/mysqli/mysqli_warning.c | 40 ++++-- ext/mysqli/php_mysqli_structs.h | 2 +- ext/mysqli/tests/bug28817.phpt | 4 +- ext/mysqli/tests/bug34810.phpt | 29 +---- ext/mysqli/tests/mysqli_real_connect.phpt | 32 +---- .../tests/mysqli_result_references.phpt | 14 +- 10 files changed, 138 insertions(+), 157 deletions(-) diff --git a/NEWS b/NEWS index c80597e6fdf5b..47e6a2968d7a1 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,9 @@ PHP NEWS . Fixed bug #79149 (SEGV in mb_convert_encoding with non-string encodings). (cmb) +- MySQLi: + . Fixed bug #78666 (Properties may emit a warning on var_dump()). (kocsismate) + - MySQLnd: . Fixed bug #79084 (mysqlnd may fetch wrong column indexes with MYSQLI_BOTH). (cmb) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 612239527e3c7..dc2e0e7e33aa3 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -69,7 +69,7 @@ zend_class_entry *mysqli_warning_class_entry; zend_class_entry *mysqli_exception_class_entry; -typedef zval *(*mysqli_read_t)(mysqli_object *obj, zval *rv); +typedef int (*mysqli_read_t)(mysqli_object *obj, zval *rv, zend_bool quiet); typedef int (*mysqli_write_t)(mysqli_object *obj, zval *newval); typedef struct _mysqli_prop_handler { @@ -281,10 +281,13 @@ static void mysqli_warning_free_storage(zend_object *object) /* }}} */ /* {{{ mysqli_read_na */ -static zval *mysqli_read_na(mysqli_object *obj, zval *retval) +static int mysqli_read_na(mysqli_object *obj, zval *retval, zend_bool quiet) { - zend_throw_error(NULL, "Cannot read property"); - return NULL; + if (!quiet) { + zend_throw_error(NULL, "Cannot read property"); + } + + return FAILURE; } /* }}} */ @@ -292,6 +295,7 @@ static zval *mysqli_read_na(mysqli_object *obj, zval *retval) static int mysqli_write_na(mysqli_object *obj, zval *newval) { zend_throw_error(NULL, "Cannot write property"); + return FAILURE; } /* }}} */ @@ -320,8 +324,9 @@ zval *mysqli_read_property(zval *object, zval *member, int type, void **cache_sl } if (hnd) { - retval = hnd->read_func(obj, rv); - if (retval == NULL) { + if (hnd->read_func(obj, rv, type == BP_VAR_IS) == SUCCESS || type != BP_VAR_IS) { + retval = rv; + } else { retval = &EG(uninitialized_zval); } } else { @@ -435,6 +440,7 @@ HashTable *mysqli_object_get_debug_info(zval *object, int *is_temp) zval rv, member; zval *value; ZVAL_STR(&member, entry->name); + value = mysqli_read_property(object, &member, BP_VAR_IS, 0, &rv); if (value != &EG(uninitialized_zval)) { zend_hash_add(retval, Z_STR(member), value); diff --git a/ext/mysqli/mysqli_driver.c b/ext/mysqli/mysqli_driver.c index 7df2eca11b0c1..3e21534dd9354 100644 --- a/ext/mysqli/mysqli_driver.c +++ b/ext/mysqli/mysqli_driver.c @@ -30,10 +30,10 @@ #include "mysqli_fe.h" #define MAP_PROPERTY_MYG_BOOL_READ(name, value) \ -static zval *name(mysqli_object *obj, zval *retval) \ +static int name(mysqli_object *obj, zval *retval, zend_bool quiet) \ { \ ZVAL_BOOL(retval, MyG(value)); \ - return retval; \ + return SUCCESS; \ } \ #define MAP_PROPERTY_MYG_BOOL_WRITE(name, value) \ @@ -44,10 +44,10 @@ static int name(mysqli_object *obj, zval *value) \ } \ #define MAP_PROPERTY_MYG_LONG_READ(name, value) \ -static zval *name(mysqli_object *obj, zval *retval) \ +static int name(mysqli_object *obj, zval *retval, zend_bool quiet) \ { \ ZVAL_LONG(retval, MyG(value)); \ - return retval; \ + return SUCCESS; \ } \ #define MAP_PROPERTY_MYG_LONG_WRITE(name, value) \ @@ -58,10 +58,10 @@ static int name(mysqli_object *obj, zval *value) \ } \ #define MAP_PROPERTY_MYG_STRING_READ(name, value) \ -static zval *name(mysqli_object *obj, zval *retval) \ +static int name(mysqli_object *obj, zval *retval, zend_bool quiet) \ { \ ZVAL_STRING(retval, MyG(value)); \ - return retval; \ + return SUCCESS; \ } \ #define MAP_PROPERTY_MYG_STRING_WRITE(name, value) \ @@ -82,34 +82,38 @@ static int driver_report_write(mysqli_object *obj, zval *value) /* }}} */ /* {{{ property driver_embedded_read */ -static zval *driver_embedded_read(mysqli_object *obj, zval *retval) +static int driver_embedded_read(mysqli_object *obj, zval *retval, zend_bool quiet) { ZVAL_FALSE(retval); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property driver_client_version_read */ -static zval *driver_client_version_read(mysqli_object *obj, zval *retval) +static int driver_client_version_read(mysqli_object *obj, zval *retval, zend_bool quiet) { ZVAL_LONG(retval, MYSQL_VERSION_ID); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property driver_client_info_read */ -static zval *driver_client_info_read(mysqli_object *obj, zval *retval) +static int driver_client_info_read(mysqli_object *obj, zval *retval, zend_bool quiet) { ZVAL_STRING(retval, (char *)mysql_get_client_info()); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property driver_driver_version_read */ -static zval *driver_driver_version_read(mysqli_object *obj, zval *retval) +static int driver_driver_version_read(mysqli_object *obj, zval *retval, zend_bool quiet) { ZVAL_LONG(retval, MYSQLI_VERSION_ID); - return retval; + + return SUCCESS; } /* }}} */ diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index eab1a0676c9a4..8190d4ab0e465 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -29,49 +29,56 @@ #include "php_mysqli_structs.h" #include "mysqli_priv.h" -#define CHECK_STATUS(value) \ +#define CHECK_STATUS(value, quiet) \ if (!obj->ptr || ((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \ - php_error_docref(NULL, E_WARNING, "Property access is not allowed yet"); \ + if (!quiet) { \ + php_error_docref(NULL, E_WARNING, "Property access is not allowed yet"); \ + } \ ZVAL_FALSE(retval); \ - return retval; \ + return FAILURE; \ } \ #define MYSQLI_GET_MYSQL(statusval) \ MYSQL *p; \ if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));\ + if (!quiet) { \ + php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \ + } \ ZVAL_FALSE(retval);\ - return retval; \ + return FAILURE; \ } else { \ - CHECK_STATUS(statusval);\ + CHECK_STATUS(statusval, quiet);\ p = (MYSQL *)((MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->mysql;\ } #define MYSQLI_GET_RESULT(statusval) \ MYSQL_RES *p; \ if (!obj->ptr) { \ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));\ + if (!quiet) { \ + php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \ + } \ ZVAL_NULL(retval);\ - return retval; \ + return FAILURE; \ } else { \ - CHECK_STATUS(statusval);\ + CHECK_STATUS(statusval, quiet);\ p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; \ } - #define MYSQLI_GET_STMT(statusval) \ MYSQL_STMT *p; \ if (!obj->ptr) { \ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));\ + if (!quiet) { \ + php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \ + } \ ZVAL_NULL(retval);\ - return retval; \ + return FAILURE; \ } else { \ - CHECK_STATUS(statusval);\ - p = (MYSQL_STMT *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt;\ + CHECK_STATUS(statusval, quiet); \ + p = (MYSQL_STMT *)((MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr)->stmt; \ } #define MYSQLI_MAP_PROPERTY_FUNC_LONG( __func, __int_func, __get_type, __ret_type, __ret_type_sprint_mod)\ -static zval *__func(mysqli_object *obj, zval *retval) \ +static int __func(mysqli_object *obj, zval *retval, zend_bool quiet) \ {\ __ret_type l;\ __get_type;\ @@ -84,12 +91,12 @@ static zval *__func(mysqli_object *obj, zval *retval) \ } else { \ ZVAL_NEW_STR(retval, strpprintf(0, __ret_type_sprint_mod, l)); \ } \ - }\ - return retval;\ + } \ + return SUCCESS; \ } #define MYSQLI_MAP_PROPERTY_FUNC_STRING(__func, __int_func, __get_type)\ -static zval *__func(mysqli_object *obj, zval *retval)\ +static int __func(mysqli_object *obj, zval *retval, zend_bool quiet)\ {\ char *c;\ __get_type;\ @@ -103,66 +110,70 @@ static zval *__func(mysqli_object *obj, zval *retval)\ ZVAL_STRING(retval, c);\ }\ }\ - return retval; \ + return SUCCESS; \ } /* {{{ property link_client_version_read */ -static zval *link_client_version_read(mysqli_object *obj, zval *retval) +static int link_client_version_read(mysqli_object *obj, zval *retval, zend_bool quiet) { ZVAL_LONG(retval, MYSQL_VERSION_ID); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property link_client_info_read */ -static zval *link_client_info_read(mysqli_object *obj, zval *retval) +static int link_client_info_read(mysqli_object *obj, zval *retval, zend_bool quiet) { - CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED, quiet); ZVAL_STRING(retval, MYSQL_SERVER_VERSION); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property link_connect_errno_read */ -static zval *link_connect_errno_read(mysqli_object *obj, zval *retval) +static int link_connect_errno_read(mysqli_object *obj, zval *retval, zend_bool quiet) { ZVAL_LONG(retval, (zend_long)MyG(error_no)); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property link_connect_error_read */ -static zval *link_connect_error_read(mysqli_object *obj, zval *retval) +static int link_connect_error_read(mysqli_object *obj, zval *retval, zend_bool quiet) { if (MyG(error_msg)) { ZVAL_STRING(retval, MyG(error_msg)); } else { ZVAL_NULL(retval); } - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property link_affected_rows_read */ -static zval *link_affected_rows_read(mysqli_object *obj, zval *retval) +static int link_affected_rows_read(mysqli_object *obj, zval *retval, zend_bool quiet) { MY_MYSQL *mysql; my_ulonglong rc; - CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED, quiet); mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; if (!mysql) { ZVAL_NULL(retval); } else { - CHECK_STATUS(MYSQLI_STATUS_VALID); + CHECK_STATUS(MYSQLI_STATUS_VALID, quiet); rc = mysql_affected_rows(mysql->mysql); if (rc == (my_ulonglong) -1) { ZVAL_LONG(retval, -1); - return retval; + return SUCCESS; } if (rc < ZEND_LONG_MAX) { @@ -171,16 +182,17 @@ static zval *link_affected_rows_read(mysqli_object *obj, zval *retval) ZVAL_NEW_STR(retval, strpprintf(0, MYSQLI_LLU_SPEC, rc)); } } - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property link_error_list_read */ -static zval *link_error_list_read(mysqli_object *obj, zval *retval) +static int link_error_list_read(mysqli_object *obj, zval *retval, zend_bool quiet) { MY_MYSQL *mysql; - CHECK_STATUS(MYSQLI_STATUS_VALID); + CHECK_STATUS(MYSQLI_STATUS_VALID, quiet); mysql = (MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; @@ -216,7 +228,7 @@ static zval *link_error_list_read(mysqli_object *obj, zval *retval) ZVAL_EMPTY_ARRAY(retval); } - return retval; + return SUCCESS; } /* }}} */ @@ -237,11 +249,11 @@ MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQ /* result properties */ /* {{{ property result_type_read */ -static zval *result_type_read(mysqli_object *obj, zval *retval) +static int result_type_read(mysqli_object *obj, zval *retval, zend_bool quiet) { MYSQL_RES *p; - CHECK_STATUS(MYSQLI_STATUS_VALID); + CHECK_STATUS(MYSQLI_STATUS_VALID, quiet); p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; if (!p) { @@ -249,12 +261,13 @@ static zval *result_type_read(mysqli_object *obj, zval *retval) } else { ZVAL_LONG(retval, mysqli_result_is_unbuffered(p) ? MYSQLI_USE_RESULT:MYSQLI_STORE_RESULT); } - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property result_lengths_read */ -static zval *result_lengths_read(mysqli_object *obj, zval *retval) +static int result_lengths_read(mysqli_object *obj, zval *retval, zend_bool quiet) { MYSQL_RES *p; #if defined(MYSQLI_USE_MYSQLND) @@ -264,7 +277,7 @@ static zval *result_lengths_read(mysqli_object *obj, zval *retval) #endif uint32_t field_count; - CHECK_STATUS(MYSQLI_STATUS_VALID); + CHECK_STATUS(MYSQLI_STATUS_VALID, quiet); p = (MYSQL_RES *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; field_count = mysql_num_fields(p); if (!p || !field_count || !(ret = mysql_fetch_lengths(p))) { @@ -278,7 +291,8 @@ static zval *result_lengths_read(mysqli_object *obj, zval *retval) add_index_long(retval, i, ret[i]); } } - return retval; + + return SUCCESS; } /* }}} */ @@ -289,11 +303,11 @@ MYSQLI_MAP_PROPERTY_FUNC_LONG(result_num_rows_read, mysql_num_rows, MYSQLI_GET_R /* statement properties */ /* {{{ property stmt_id_read */ -static zval *stmt_id_read(mysqli_object *obj, zval *retval) +static int stmt_id_read(mysqli_object *obj, zval *retval, zend_bool quiet) { MY_STMT *p; - CHECK_STATUS(MYSQLI_STATUS_VALID); + CHECK_STATUS(MYSQLI_STATUS_VALID, quiet); p = (MY_STMT*)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; @@ -302,17 +316,18 @@ static zval *stmt_id_read(mysqli_object *obj, zval *retval) } else { ZVAL_LONG(retval, mysqli_stmt_get_id(p->stmt)); } - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property stmt_affected_rows_read */ -static zval *stmt_affected_rows_read(mysqli_object *obj, zval *retval) +static int stmt_affected_rows_read(mysqli_object *obj, zval *retval, zend_bool quiet) { MY_STMT *p; my_ulonglong rc; - CHECK_STATUS(MYSQLI_STATUS_VALID); + CHECK_STATUS(MYSQLI_STATUS_VALID, quiet); p = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; @@ -323,7 +338,7 @@ static zval *stmt_affected_rows_read(mysqli_object *obj, zval *retval) if (rc == (my_ulonglong) -1) { ZVAL_LONG(retval, -1); - return retval; + return SUCCESS; } if (rc < ZEND_LONG_MAX) { @@ -332,16 +347,17 @@ static zval *stmt_affected_rows_read(mysqli_object *obj, zval *retval) ZVAL_NEW_STR(retval, strpprintf(0, MYSQLI_LLU_SPEC, rc)); } } - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property stmt_error_list_read */ -static zval *stmt_error_list_read(mysqli_object *obj, zval *retval) +static int stmt_error_list_read(mysqli_object *obj, zval *retval, zend_bool quiet) { MY_STMT * stmt; - CHECK_STATUS(MYSQLI_STATUS_INITIALIZED); + CHECK_STATUS(MYSQLI_STATUS_INITIALIZED, quiet); stmt = (MY_STMT *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; if (stmt && stmt->stmt) { @@ -375,7 +391,8 @@ static zval *stmt_error_list_read(mysqli_object *obj, zval *retval) } else { ZVAL_EMPTY_ARRAY(retval); } - return retval; + + return SUCCESS; } /* }}} */ diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index 248d9a281f2a4..ab6a0d3830d74 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -199,49 +199,65 @@ PHP_METHOD(mysqli_warning, next) /* }}} */ /* {{{ property mysqli_warning_message */ -static -zval *mysqli_warning_message(mysqli_object *obj, zval *retval) +static int mysqli_warning_message(mysqli_object *obj, zval *retval, zend_bool quiet) { MYSQLI_WARNING *w; if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { - return NULL; + if (!quiet) { + php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); + } + ZVAL_NULL(retval); + + return FAILURE; } w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; ZVAL_COPY(retval, &w->reason); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property mysqli_warning_sqlstate */ -static -zval *mysqli_warning_sqlstate(mysqli_object *obj, zval *retval) +static int mysqli_warning_sqlstate(mysqli_object *obj, zval *retval, zend_bool quiet) { MYSQLI_WARNING *w; if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { - return NULL; + if (!quiet) { + php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); + } + ZVAL_NULL(retval); + + return FAILURE; } w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; ZVAL_COPY(retval, &w->sqlstate); - return retval; + + return SUCCESS; } /* }}} */ /* {{{ property mysqli_warning_error */ -static -zval *mysqli_warning_errno(mysqli_object *obj, zval *retval) +static int mysqli_warning_errno(mysqli_object *obj, zval *retval, zend_bool quiet) { MYSQLI_WARNING *w; if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { - return NULL; + if (!quiet) { + php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); + } + ZVAL_NULL(retval); + + return FAILURE; } + w = (MYSQLI_WARNING *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr; ZVAL_LONG(retval, w->errorno); - return retval; + + return SUCCESS; } /* }}} */ diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h index 93fbc15e91b0f..96fbacb82e737 100644 --- a/ext/mysqli/php_mysqli_structs.h +++ b/ext/mysqli/php_mysqli_structs.h @@ -158,7 +158,7 @@ struct st_mysqli_warning { typedef struct _mysqli_property_entry { const char *pname; size_t pname_length; - zval *(*r_func)(mysqli_object *obj, zval *retval); + int (*r_func)(mysqli_object *obj, zval *retval, zend_bool quiet); int (*w_func)(mysqli_object *obj, zval *value); } mysqli_property_entry; diff --git a/ext/mysqli/tests/bug28817.phpt b/ext/mysqli/tests/bug28817.phpt index 5a5e9244764c5..18370485178d3 100644 --- a/ext/mysqli/tests/bug28817.phpt +++ b/ext/mysqli/tests/bug28817.phpt @@ -22,7 +22,7 @@ require_once('skipifconnectfailure.inc'); $mysql = new my_mysql(); var_dump($mysql->p_test); - @var_dump($mysql->errno); + var_dump($mysql->errno); $mysql->connect($host, $user, $passwd, $db, $port, $socket); $mysql->select_db("nonexistingdb"); @@ -38,5 +38,7 @@ array(2) { [1]=> %s(3) "bar" } + +Warning: main(): Couldn't fetch my_mysql in %s on line %d bool(false) bool(true) diff --git a/ext/mysqli/tests/bug34810.phpt b/ext/mysqli/tests/bug34810.phpt index d9afc246eb668..b56d1a5ac7cfc 100644 --- a/ext/mysqli/tests/bug34810.phpt +++ b/ext/mysqli/tests/bug34810.phpt @@ -16,8 +16,7 @@ class DbConnection { var_dump($link); $link = mysqli_init(); - /* @ is to suppress 'Property access is not allowed yet' */ - @var_dump($link); + var_dump($link); $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $mysql->query("DROP TABLE IF EXISTS test_warnings"); @@ -36,8 +35,6 @@ class DbConnection { if ("" == $warning->message) printf("[004] Message string must not be empty\n"); - - } else { printf("[002] Empty error message!\n"); var_dump($warning); @@ -102,8 +99,6 @@ object(mysqli)#%d (%d) { int(0) } object(mysqli)#%d (%d) { - ["affected_rows"]=> - bool(false) ["client_info"]=> string(%d) "%s" ["client_version"]=> @@ -116,27 +111,5 @@ object(mysqli)#%d (%d) { int(0) ["error"]=> string(0) "" - ["error_list"]=> - bool(false) - ["field_count"]=> - bool(false) - ["host_info"]=> - bool(false) - ["info"]=> - bool(false) - ["insert_id"]=> - bool(false) - ["server_info"]=> - bool(false) - ["server_version"]=> - bool(false) - ["sqlstate"]=> - bool(false) - ["protocol_version"]=> - bool(false) - ["thread_id"]=> - bool(false) - ["warning_count"]=> - bool(false) } Done diff --git a/ext/mysqli/tests/mysqli_real_connect.phpt b/ext/mysqli/tests/mysqli_real_connect.phpt index 1316d1a981948..2e39833ffe808 100644 --- a/ext/mysqli/tests/mysqli_real_connect.phpt +++ b/ext/mysqli/tests/mysqli_real_connect.phpt @@ -138,7 +138,7 @@ mysqli.allow_local_infile=1 } mysqli_close($link); - @var_dump($link); + var_dump($link); if ($IS_MYSQLND) { ini_set('mysqli.default_host', 'p:' . $host); @@ -179,42 +179,12 @@ mysqli.allow_local_infile=1 --EXPECTF-- Warning: mysqli_real_connect(): (%s/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d object(mysqli)#%d (%d) { - ["affected_rows"]=> - bool(false) - ["client_info"]=> - %s ["client_version"]=> int(%d) ["connect_errno"]=> int(%d) ["connect_error"]=> NULL - ["errno"]=> - %s - ["error"]=> - %s - ["error_list"]=> - bool(false) - ["field_count"]=> - bool(false) - ["host_info"]=> - bool(false) - ["info"]=> - bool(false) - ["insert_id"]=> - bool(false) - ["server_info"]=> - bool(false) - ["server_version"]=> - bool(false) - ["sqlstate"]=> - bool(false) - ["protocol_version"]=> - bool(false) - ["thread_id"]=> - bool(false) - ["warning_count"]=> - bool(false) } Warning: mysqli_real_connect(): Couldn't fetch mysqli in %s on line %d diff --git a/ext/mysqli/tests/mysqli_result_references.phpt b/ext/mysqli/tests/mysqli_result_references.phpt index 33e5a1f1dae5d..d4fe48816a511 100644 --- a/ext/mysqli/tests/mysqli_result_references.phpt +++ b/ext/mysqli/tests/mysqli_result_references.phpt @@ -59,7 +59,7 @@ require_once('skipifconnectfailure.inc'); $references[$idx++] = &$res; mysqli_free_result($res); - @debug_zval_dump($references); + debug_zval_dump($references); if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 1")) || !($res = mysqli_use_result($link))) @@ -129,17 +129,7 @@ array(7) refcount(2){ &int(4) } [6]=> - &object(mysqli_result)#%d (5) refcount(%d){ - ["current_field"]=> - NULL - ["field_count"]=> - NULL - ["lengths"]=> - bool(false) - ["num_rows"]=> - NULL - ["type"]=> - bool(false) + &object(mysqli_result)#%d (0) refcount(%d){ } } array(1) refcount(2){ From ce44cd3b3c32a1ef400065468df94efa6a9624dd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 29 Jan 2020 12:15:03 +0300 Subject: [PATCH 32/80] Fixed bug #79092 (Building with clang+lld-9 results in a broken PHP binary) --- configure.ac | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 56a5127667d80..501730ba47fbc 100644 --- a/configure.ac +++ b/configure.ac @@ -1050,6 +1050,42 @@ esyscmd(./build/config-stubs ext) dnl Extensions post-config. dnl ---------------------------------------------------------------------------- +dnl Align segments on huge page boundary +case $host_alias in + i[[3456]]86-*-linux-* | x86_64-*-linux-*) + AC_MSG_CHECKING(linker support for -zcommon-page-size=2097152) + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152" + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[int main() {return 0;}]])], + [ac_cv_common_page_size=yes], + [ac_cv_common_page_size=no], + [ac_cv_common_page_size=no]) + LDFLAGS=$save_LDFLAGS + if test "$ac_cv_common_page_size" = "yes"; then + AC_MSG_RESULT([yes]) + EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152" + else + AC_MSG_RESULT([no]) + AC_MSG_CHECKING(linker support for -zmax-page-size=2097152) + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-zmax-page-size=2097152" + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[int main() {return 0;}]])], + [ac_cv_max_page_size=yes], + [ac_cv_max_page_size=no], + [ac_cv_max_page_size=no]) + LDFLAGS=$save_LDFLAGS + if test "$ac_cv_max_page_size" = "yes"; then + AC_MSG_RESULT([yes]) + EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM -Wl,-zmax-page-size=2097152" + else + AC_MSG_RESULT([no]) + fi + fi + ;; +esac + enable_shared=yes enable_static=yes @@ -1168,13 +1204,6 @@ if test "$PHP_THREAD_SAFETY" = "yes"; then TSRM_THREADS_CHECKS fi -dnl Align segments on huge page boundary -case $host_alias in - i[[3456]]86-*-linux-* | x86_64-*-linux-*) - EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM -Wl,-zcommon-page-size=2097152 -Wl,-zmax-page-size=2097152" - ;; -esac - EXTRA_LDFLAGS="$EXTRA_LDFLAGS $LDFLAGS" EXTRA_LDFLAGS_PROGRAM="$EXTRA_LDFLAGS_PROGRAM $LDFLAGS" EXTRA_LIBS="$EXTRA_LIBS $LIBS" From 5265fabc2501999dcfc1615980f25bce25d58e92 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 28 Jan 2020 20:41:56 +0100 Subject: [PATCH 33/80] Use "%define parse.error verbose" The YYERROR_VERBOSE macro will no longer be supported in Bison 3.6. It was superseded by the "%error-verbose" directive in Bison 1.875 (2003-01-01). Bison 2.6 (2012-07-19) clearly announced that support for YYERROR_VERBOSE would be removed. Note that since Bison 3.0 (2013-07-25), "%error-verbose" is deprecated in favor of "%define parse.error verbose". Closes GH-5125. --- Zend/zend_ini_parser.y | 3 ++- Zend/zend_language_parser.y | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 5d21bb101696a..749f929a9bf1b 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -1,3 +1,4 @@ +%require "3.0" %{ /* +----------------------------------------------------------------------+ @@ -31,7 +32,6 @@ #include "win32/syslog.h" #endif -#define YYERROR_VERBOSE #define YYSTYPE zval int ini_parse(void); @@ -290,6 +290,7 @@ static void zval_ini_dtor(zval *zv) %expect 0 %define api.pure full +%define parse.error verbose %token TC_SECTION %token TC_RAW diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index f3bb663e0c7ab..56a354b9cce3d 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -1,3 +1,4 @@ +%require "3.0" %{ /* +----------------------------------------------------------------------+ @@ -32,7 +33,6 @@ #define yytnamerr zend_yytnamerr static YYSIZE_T zend_yytnamerr(char*, const char*); -#define YYERROR_VERBOSE #define YYSTYPE zend_parser_stack_elem #ifdef _MSC_VER @@ -43,6 +43,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %} %define api.pure full +%define parse.error verbose %expect 0 %code requires { From 91f878779cdad878ae664e2abad83a2967ae56d1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 29 Jan 2020 11:44:56 +0100 Subject: [PATCH 34/80] Fix recovery of large entities in mb_decode_numericentity() Make sure we don't overflow the integer. --- ext/mbstring/libmbfl/mbfl/mbfilter.c | 8 ++------ ext/mbstring/tests/mb_decode_numericentity.phpt | 8 ++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index 1cb6d28e7b4e0..baaa4c3f36095 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -2586,12 +2586,10 @@ collector_decode_htmlnumericentity(int c, void *data) (*pc->decoder->filter_function)(0x23, pc->decoder); /* '#' */ r = 1; n = pc->digit; - while (n > 0) { + while (n > 1) { r *= 10; n--; } - s %= r; - r /= 10; while (r > 0) { d = s/r; s %= r; @@ -2764,12 +2762,10 @@ int mbfl_filt_decode_htmlnumericentity_flush(mbfl_convert_filter *filter) s = pc->cache; r = 1; n = pc->digit; - while (n > 0) { + while (n > 1) { r *= 10; n--; } - s %= r; - r /= 10; while (r > 0) { d = s/r; s %= r; diff --git a/ext/mbstring/tests/mb_decode_numericentity.phpt b/ext/mbstring/tests/mb_decode_numericentity.phpt index 6008ef9a9b0fb..b6a7c622a668c 100644 --- a/ext/mbstring/tests/mb_decode_numericentity.phpt +++ b/ext/mbstring/tests/mb_decode_numericentity.phpt @@ -14,8 +14,16 @@ $convmap = array(0x0, 0x2FFFF, 0, 0xFFFF); echo mb_decode_numericentity($str1, $convmap, "UTF-8")."\n"; echo mb_decode_numericentity($str2, $convmap, "UTF-8")."\n"; echo mb_decode_numericentity($str3, $convmap, "UTF-8")."\n"; + +echo mb_decode_numericentity('�', $convmap), "\n"; +echo mb_decode_numericentity('�', $convmap), "\n"; +echo mb_decode_numericentity('�', $convmap), "\n"; + ?> --EXPECT-- ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ ƒΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωϑϒϖ•…′″‾⁄℘ℑℜ™ℵ←↑→↓↔↵⇐⇑⇒⇓⇔∀∂∃∅∇∈∉∋∏∑−∗√∝∞∠∧∨∩∪∫∴∼≅≈≠≡≤≥⊂⊃⊄⊆⊇⊕⊗⊥⋅⌈⌉⌊⌋〈〉◊♠♣♥♦ aŒbœcŠdše€fg +� +� +� From 5589bf4d4af830b2a081475cf8065bf1ed9cf19a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 29 Jan 2020 12:19:28 +0100 Subject: [PATCH 35/80] Fix length inconsistency in mb_convert_encoding Don't mix strlen() and ZSTR_LEN(). If the encoding contains a NULL byte, this will overflow the buffer. NULL bytes will still make this behave oddly because the consuming code will cut off the string there, but let's address that in master... --- ext/mbstring/mbstring.c | 2 +- ext/mbstring/tests/bug79149.phpt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 78557e7f942f0..d6b633ff3a1b1 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3370,7 +3370,7 @@ PHP_FUNCTION(mb_convert_encoding) if ( _from_encodings) { l = strlen(_from_encodings); - n = strlen(ZSTR_VAL(encoding_str)); + n = ZSTR_LEN(encoding_str); _from_encodings = erealloc(_from_encodings, l+n+2); memcpy(_from_encodings + l, ",", 1); memcpy(_from_encodings + l + 1, ZSTR_VAL(encoding_str), ZSTR_LEN(encoding_str) + 1); diff --git a/ext/mbstring/tests/bug79149.phpt b/ext/mbstring/tests/bug79149.phpt index fc3751d933ad8..fe2007536e35e 100644 --- a/ext/mbstring/tests/bug79149.phpt +++ b/ext/mbstring/tests/bug79149.phpt @@ -8,6 +8,7 @@ if (!extension_loaded('mbstring')) die('skip mbstring extension not available'); --EXPECTF-- Warning: mb_convert_encoding(): Illegal character encoding specified in %s on line %d @@ -19,3 +20,6 @@ Notice: Array to string conversion in %s on line %d Warning: mb_convert_encoding(): Illegal character encoding specified in %s on line %d string(3) "foo" + +Warning: mb_convert_encoding(): Illegal character encoding specified in %s on line %d +string(3) "foo" From 7d2ef3d2e540885dec26d91dad061bff1621ad07 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 29 Jan 2020 12:34:04 +0100 Subject: [PATCH 36/80] Fix datatype This has been introduced by 84b0d0fabaaf21ee056984a33b573121296af942. Besides it causes runtime issues on POWER5 (and presumably later), the implementation would expect this array to consist on 32-bit integers. --- ext/hash/php_hash_gost.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index 537e3d0bdc701..987eb655cb30a 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -22,7 +22,7 @@ /* GOST context */ typedef struct { uint32_t state[16]; - size_t count[2]; + uint32_t count[2]; unsigned char length; unsigned char buffer[32]; const uint32_t (*tables)[4][256]; From 392ad206a4f63fedf61d8086e390c73de8b72767 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 29 Jan 2020 12:49:28 +0100 Subject: [PATCH 37/80] Fix use of mb_ereg_search_getregs() after invalid pattern This segfaulted because we assumed that if there are matches, there must be a regular expression as well. --- ext/mbstring/php_mbregex.c | 8 +++++--- .../tests/mb_ereg_search_invalid_pattern.phpt | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 47dd41ba05290..aa1eec168611e 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -1426,6 +1426,11 @@ _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode) _php_mb_regex_init_options(arg_options, arg_options_len, &option, &syntax, NULL); } + if (MBREX(search_regs)) { + onig_region_free(MBREX(search_regs), 1); + MBREX(search_regs) = NULL; + } + if (arg_pattern) { /* create regex pattern buffer */ if ((MBREX(search_re) = php_mbregex_compile_pattern(arg_pattern, arg_pattern_len, option, MBREX(current_mbctype), MBREX(regex_default_syntax))) == NULL) { @@ -1451,9 +1456,6 @@ _php_mb_regex_ereg_search_exec(INTERNAL_FUNCTION_PARAMETERS, int mode) RETURN_FALSE; } - if (MBREX(search_regs)) { - onig_region_free(MBREX(search_regs), 1); - } MBREX(search_regs) = onig_region_new(); err = _php_mb_onig_search(MBREX(search_re), str, str + len, str + pos, str + len, MBREX(search_regs), 0); diff --git a/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt new file mode 100644 index 0000000000000..7fe6d31128192 --- /dev/null +++ b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt @@ -0,0 +1,17 @@ +--TEST-- +mb_ereg_search() with invalid pattern should discard old matches +--FILE-- + +--EXPECTF-- +bool(true) + +Warning: mb_ereg_search(): Pattern is not valid under UTF-8 encoding in %s on line %d +bool(false) +bool(false) From 6352e9a98925d375d0c2d3d8b0de66966d9522fc Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 29 Jan 2020 13:19:27 +0100 Subject: [PATCH 38/80] Backport 7d2ef3d2e540885dec26d91dad061bff1621ad07 into 7.4 As the data structures are public, the fix for 64-bit consists on replacing the blanket memcpy with individual assignments. --- ext/hash/hash_gost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index f51b310b70ad8..ded6d1c6a74bc 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -291,7 +291,8 @@ PHP_HASH_API void PHP_GOSTFinal(unsigned char digest[32], PHP_GOST_CTX *context) GostTransform(context, context->buffer); } - memcpy(l, context->count, sizeof(context->count)); + l[0] = context->count[0]; + l[1] = context->count[1]; Gost(context, l); memcpy(l, &context->state[8], sizeof(l)); Gost(context, l); From bdcfdd4402b0b7c10a1ad27a5b7f8ac754886344 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 29 Jan 2020 14:25:16 +0100 Subject: [PATCH 39/80] zip: more constants --- NEWS | 3 ++- ext/zip/php_zip.c | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 47e6a2968d7a1..13bcaebde362f 100644 --- a/NEWS +++ b/NEWS @@ -55,7 +55,8 @@ PHP NEWS . Fixed bug #78969 (PASSWORD_DEFAULT should match PASSWORD_BCRYPT instead of being null). (kocsismate) - Zip: - . Add ZipArchive::CM_LZMA2 constant (since libzip 1.6.0). (remi) + . Add ZipArchive::CM_LZMA2 and ZipArchive::CM_XZ constants (since libzip 1.6.0). (remi) + . Add ZipArchive::ER_* missing constants. (remi) . Add ZipArchive::LIBZIP_VERSION constant. (remi) 23 Jan 2020, PHP 7.4.2 diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index bec14f7f77b1e..c6ce639b88f40 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -3082,6 +3082,9 @@ static PHP_MINIT_FUNCTION(zip) REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA", ZIP_CM_LZMA); #ifdef ZIP_CM_LZMA2 REGISTER_ZIP_CLASS_CONST_LONG("CM_LZMA2", ZIP_CM_LZMA2); +#endif +#ifdef ZIP_CM_XZ + REGISTER_ZIP_CLASS_CONST_LONG("CM_XZ", ZIP_CM_XZ); #endif REGISTER_ZIP_CLASS_CONST_LONG("CM_TERSE", ZIP_CM_TERSE); REGISTER_ZIP_CLASS_CONST_LONG("CM_LZ77", ZIP_CM_LZ77); @@ -3113,6 +3116,27 @@ static PHP_MINIT_FUNCTION(zip) REGISTER_ZIP_CLASS_CONST_LONG("ER_INCONS", ZIP_ER_INCONS); /* N Zip archive inconsistent */ REGISTER_ZIP_CLASS_CONST_LONG("ER_REMOVE", ZIP_ER_REMOVE); /* S Can't remove file */ REGISTER_ZIP_CLASS_CONST_LONG("ER_DELETED", ZIP_ER_DELETED); /* N Entry has been deleted */ + REGISTER_ZIP_CLASS_CONST_LONG("ER_ENCRNOTSUPP", ZIP_ER_ENCRNOTSUPP);/* N Encryption method not supported */ + REGISTER_ZIP_CLASS_CONST_LONG("ER_RDONLY", ZIP_ER_RDONLY); /* N Read-only archive */ + REGISTER_ZIP_CLASS_CONST_LONG("ER_NOPASSWD", ZIP_ER_NOPASSWD); /* N Entry has been deleted */ + REGISTER_ZIP_CLASS_CONST_LONG("ER_WRONGPASSWD", ZIP_ER_WRONGPASSWD);/* N Wrong password provided */ +/* since 1.0.0 */ +#ifdef ZIP_ER_OPNOTSUPP + REGISTER_ZIP_CLASS_CONST_LONG("ER_OPNOTSUPP", ZIP_ER_OPNOTSUPP); /* N Operation not supported */ +#endif +#ifdef ZIP_ER_INUSE + REGISTER_ZIP_CLASS_CONST_LONG("ER_INUSE", ZIP_ER_INUSE); /* N Resource still in use */ +#endif +#ifdef ZIP_ER_TELL + REGISTER_ZIP_CLASS_CONST_LONG("ER_TELL", ZIP_ER_TELL); /* S Tell error */ +#endif +/* since 1.6.0 */ +#ifdef ZIP_ER_COMPRESSED_DATA + REGISTER_ZIP_CLASS_CONST_LONG("ER_COMPRESSED_DATA", ZIP_ER_COMPRESSED_DATA);/* N Compressed data invalid */ +#endif +#ifdef ZIP_ER_CANCELLED + REGISTER_ZIP_CLASS_CONST_LONG("ER_CANCELLED", ZIP_ER_CANCELLED); /* N Operation cancelled */ +#endif #ifdef ZIP_OPSYS_DEFAULT REGISTER_ZIP_CLASS_CONST_LONG("OPSYS_DOS", ZIP_OPSYS_DOS); From b8d635cd221ea1afe883187955b8ae8315c36043 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 29 Jan 2020 14:26:03 +0100 Subject: [PATCH 40/80] zip extension version is now 1.16.1 --- ext/zip/php_zip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index d1f46ea4ea24c..1eb100d45feb3 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -31,7 +31,7 @@ extern zend_module_entry zip_module_entry; #define ZIP_OVERWRITE ZIP_TRUNCATE #endif -#define PHP_ZIP_VERSION "1.16.0" +#define PHP_ZIP_VERSION "1.16.1" #define ZIP_OPENBASEDIR_CHECKPATH(filename) php_check_open_basedir(filename) From 560ff9725e6fb05942dd0c891c8a4496c57bcb4b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 29 Jan 2020 16:03:44 +0100 Subject: [PATCH 41/80] Reset MBREX(search_re) in RSHUTDOWN This is going to cause a segfault if reused in the next request. To illustrate the issue, run these two scripts in sequence with the built-in server: // script1.php mb_ereg_search_init('foobar'); mb_ereg_search('foo'); // script2.php var_dump(mb_ereg_search_init("foobar")); var_dump(mb_ereg_search_pos()); --- ext/mbstring/php_mbregex.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index aa1eec168611e..b6ed2b86e908e 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -149,6 +149,7 @@ PHP_RSHUTDOWN_FUNCTION(mb_regex) ZVAL_UNDEF(&MBREX(search_str)); } MBREX(search_pos) = 0; + MBREX(search_re) = NULL; if (MBREX(search_regs) != NULL) { onig_region_free(MBREX(search_regs), 1); From 18599f9c52959b2e8cbfac57e278644499a3547d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 29 Jan 2020 14:22:45 +0100 Subject: [PATCH 42/80] Better overflow check for entity decoding Check for multiplication overflow rather than number of digits. --- ext/mbstring/libmbfl/mbfl/mbfilter.c | 7 ++++--- ext/mbstring/tests/mb_decode_numericentity.phpt | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index baaa4c3f36095..cec6daad945d5 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -86,6 +86,7 @@ #include #include +#include #include "mbfilter.h" #include "mbfl_filter_output.h" @@ -2552,12 +2553,12 @@ collector_decode_htmlnumericentity(int c, void *data) s = 0; f = 0; if (c >= 0x30 && c <= 0x39) { /* '0' - '9' */ - if (pc->digit > 9) { + s = pc->cache; + if (s > INT_MAX/10) { pc->status = 0; - s = pc->cache; f = 1; } else { - s = pc->cache*10 + c - 0x30; + s = s*10 + (c - 0x30); pc->cache = s; pc->digit++; } diff --git a/ext/mbstring/tests/mb_decode_numericentity.phpt b/ext/mbstring/tests/mb_decode_numericentity.phpt index b6a7c622a668c..c728e2aa6927d 100644 --- a/ext/mbstring/tests/mb_decode_numericentity.phpt +++ b/ext/mbstring/tests/mb_decode_numericentity.phpt @@ -16,6 +16,7 @@ echo mb_decode_numericentity($str2, $convmap, "UTF-8")."\n"; echo mb_decode_numericentity($str3, $convmap, "UTF-8")."\n"; echo mb_decode_numericentity('�', $convmap), "\n"; +echo mb_decode_numericentity('�', $convmap), "\n"; echo mb_decode_numericentity('�', $convmap), "\n"; echo mb_decode_numericentity('�', $convmap), "\n"; @@ -25,5 +26,6 @@ echo mb_decode_numericentity('�', $convmap), "\n"; ƒΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωϑϒϖ•…′″‾⁄℘ℑℜ™ℵ←↑→↓↔↵⇐⇑⇒⇓⇔∀∂∃∅∇∈∉∋∏∑−∗√∝∞∠∧∨∩∪∫∴∼≅≈≠≡≤≥⊂⊃⊄⊆⊇⊕⊗⊥⋅⌈⌉⌊⌋〈〉◊♠♣♥♦ aŒbœcŠdše€fg � +� � � From a62c06c4cf2020c04a2f5ac0b55aff4bb71f3edc Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 29 Jan 2020 16:17:30 +0100 Subject: [PATCH 43/80] Fix mb_ord() crash if internal encoding not supported enc_name can be NULL here. Take the name from the mbfl_encoding instead. --- ext/mbstring/mbstring.c | 2 +- ext/mbstring/tests/mb_ord.phpt | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 7f4cd451da764..49adb167b2ccf 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -4850,7 +4850,7 @@ static inline zend_long php_mb_ord(const char* str, size_t str_len, const char* no_enc = enc->no_encoding; if (php_mb_is_unsupported_no_encoding(no_enc)) { - php_error_docref(NULL, E_WARNING, "Unsupported encoding \"%s\"", enc_name); + php_error_docref(NULL, E_WARNING, "Unsupported encoding \"%s\"", enc->name); return -1; } diff --git a/ext/mbstring/tests/mb_ord.phpt b/ext/mbstring/tests/mb_ord.phpt index b42bd054250fe..e0c5610c0b395 100644 --- a/ext/mbstring/tests/mb_ord.phpt +++ b/ext/mbstring/tests/mb_ord.phpt @@ -19,6 +19,9 @@ var_dump( mb_ord("\u{d800}", "utf-7"), mb_ord("") ); + +mb_internal_encoding("utf-7"); +mb_ord(""); ?> --EXPECTF-- bool(true) @@ -29,11 +32,11 @@ Warning: mb_ord(): Unknown encoding "typo" %s 10 Warning: mb_ord(): Unsupported encoding "pass" %s 11 -Warning: mb_ord(): Unsupported encoding "jis" %s 12 +Warning: mb_ord(): Unsupported encoding "JIS" in %s on line %d -Warning: mb_ord(): Unsupported encoding "cp50222" %s 13 +Warning: mb_ord(): Unsupported encoding "CP50222" in %s on line %d -Warning: mb_ord(): Unsupported encoding "utf-7" %s 14 +Warning: mb_ord(): Unsupported encoding "UTF-7" in %s on line %d Warning: mb_ord(): Empty string in %s on line %d bool(false) @@ -42,3 +45,5 @@ bool(false) bool(false) bool(false) bool(false) + +Warning: mb_ord(): Unsupported encoding "UTF-7" in %s on line %d From dda67d32265c2a5d751471c64922e8dea2d61290 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 29 Jan 2020 18:19:54 +0100 Subject: [PATCH 44/80] Enable ZipArchive::setMtime(Name|Index) on Windows These are enabled on non Windows systems as of zip 1.16.0 with libzip >= 1.0.0. Since Windows builds use at least libzip 1.4.0, we also enable these methods there. --- ext/zip/config.w32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index 034543fabd8cf..f27b047b2f49a 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -15,7 +15,7 @@ if (PHP_ZIP != "no") { } AC_DEFINE('HAVE_ZIP', 1); - ADD_FLAG("CFLAGS_ZIP", "/D _WIN32 /D HAVE_ENCRYPTION /D HAVE_LIBZIP_VERSION"); + ADD_FLAG("CFLAGS_ZIP", "/D _WIN32 /D HAVE_SET_MTIME /D HAVE_ENCRYPTION /D HAVE_LIBZIP_VERSION"); } else { WARNING("zip not enabled; libraries and headers not found"); } From 9aadcb18e1d6c7f7736a00e246e193671353d741 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 29 Jan 2020 16:40:13 +0100 Subject: [PATCH 45/80] Restore digit check in mb_decode_numericentity() I replaced it with a multiplication overflow check in 18599f9c52959b2e8cbfac57e278644499a3547d. However, we need both, because the code for restoring the number can't handle numbers with many leading zeros right now and I don't feel like teaching it. --- ext/mbstring/libmbfl/mbfl/mbfilter.c | 2 +- ext/mbstring/tests/mb_decode_numericentity.phpt | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index cec6daad945d5..544eae9121d80 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -2554,7 +2554,7 @@ collector_decode_htmlnumericentity(int c, void *data) f = 0; if (c >= 0x30 && c <= 0x39) { /* '0' - '9' */ s = pc->cache; - if (s > INT_MAX/10) { + if (pc->digit > 9 || s > INT_MAX/10) { pc->status = 0; f = 1; } else { diff --git a/ext/mbstring/tests/mb_decode_numericentity.phpt b/ext/mbstring/tests/mb_decode_numericentity.phpt index c728e2aa6927d..f70e26a43c3fe 100644 --- a/ext/mbstring/tests/mb_decode_numericentity.phpt +++ b/ext/mbstring/tests/mb_decode_numericentity.phpt @@ -19,6 +19,7 @@ echo mb_decode_numericentity('�', $convmap), "\n"; echo mb_decode_numericentity('�', $convmap), "\n"; echo mb_decode_numericentity('�', $convmap), "\n"; echo mb_decode_numericentity('�', $convmap), "\n"; +echo mb_decode_numericentity('�', $convmap), "\n"; ?> --EXPECT-- @@ -29,3 +30,4 @@ aŒbœcŠdše€fg � � � +� From 43465768f1aba95afd1ea5a0ac40af2cb440d1e4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 28 Jan 2020 16:18:46 +0100 Subject: [PATCH 46/80] Fix shift ub in mbstring Ideally "c" would be an unsigned integer... --- ext/mbstring/libmbfl/filters/mbfilter_ucs4.c | 8 ++++---- ext/mbstring/libmbfl/filters/mbfilter_utf32.c | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c index 26ae5d47ccb87..34715cd560f6b 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c @@ -139,7 +139,7 @@ int mbfl_filt_conv_ucs4_wchar(int c, mbfl_convert_filter *filter) if (endian) { n = c & 0xff; } else { - n = (c & 0xff) << 24; + n = (c & 0xffu) << 24; } filter->cache = n; filter->status++; @@ -164,7 +164,7 @@ int mbfl_filt_conv_ucs4_wchar(int c, mbfl_convert_filter *filter) break; default: if (endian) { - n = (c & 0xff) << 24; + n = (c & 0xffu) << 24; } else { n = c & 0xff; } @@ -195,7 +195,7 @@ int mbfl_filt_conv_ucs4be_wchar(int c, mbfl_convert_filter *filter) if (filter->status == 0) { filter->status = 1; - n = (c & 0xff) << 24; + n = (c & 0xffu) << 24; filter->cache = n; } else if (filter->status == 1) { filter->status = 2; @@ -251,7 +251,7 @@ int mbfl_filt_conv_ucs4le_wchar(int c, mbfl_convert_filter *filter) filter->cache |= n; } else { filter->status = 0; - n = ((c & 0xff) << 24) | filter->cache; + n = ((c & 0xffu) << 24) | filter->cache; CK((*filter->output_function)(n, filter->data)); } return c; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c index 9f7ddf1deaf0a..3281cf9494a46 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c @@ -138,7 +138,7 @@ int mbfl_filt_conv_utf32_wchar(int c, mbfl_convert_filter *filter) if (endian) { n = c & 0xff; } else { - n = (unsigned) (c & 0xff) << 24; + n = (c & 0xffu) << 24; } filter->cache = n; filter->status++; @@ -163,7 +163,7 @@ int mbfl_filt_conv_utf32_wchar(int c, mbfl_convert_filter *filter) break; default: if (endian) { - n = (c & 0xff) << 24; + n = (c & 0xffu) << 24; } else { n = c & 0xff; } @@ -199,7 +199,7 @@ int mbfl_filt_conv_utf32be_wchar(int c, mbfl_convert_filter *filter) if (filter->status == 0) { filter->status = 1; - n = (c & 0xff) << 24; + n = (c & 0xffu) << 24; filter->cache = n; } else if (filter->status == 1) { filter->status = 2; @@ -260,7 +260,7 @@ int mbfl_filt_conv_utf32le_wchar(int c, mbfl_convert_filter *filter) filter->cache |= n; } else { filter->status = 0; - n = ((c & 0xff) << 24) | filter->cache; + n = ((c & 0xffu) << 24) | filter->cache; if (n < MBFL_WCSPLANE_UTF32MAX && (n < 0xd800 || n > 0xdfff)) { CK((*filter->output_function)(n, filter->data)); } else { From 146848429605752e156a9f0ced4bfb079720d094 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 29 Jan 2020 16:18:46 +0100 Subject: [PATCH 47/80] Fix #74063: NumberFormatter fails after retrieval from session While it would be desireable to actually support unserialization of NumberFormatter instances, at least we should not allow serialization for now. We also remove some doubtful tests, which have been added[1] claiming that they would crash the intl extension, but apparently no fix has been applied, and the test cases have not been marked as XFAIL. [1] --- ext/intl/formatter/formatter_class.c | 3 ++ ext/intl/tests/bug74063.phpt | 17 +++++++ .../symfony_format_type_double_intl1.phpt | 30 ------------ .../symfony_format_type_double_intl2.phpt | 30 ------------ .../symfony_format_type_double_intl3.phpt | 30 ------------ .../symfony_format_type_double_intl4.phpt | 31 ------------ .../symfony_format_type_int32_intl1.phpt | 49 ------------------- .../symfony_format_type_int32_intl2.phpt | 33 ------------- .../symfony_format_type_int32_intl3.phpt | 32 ------------ .../symfony_format_type_int32_intl4.phpt | 30 ------------ .../symfony_format_type_int32_intl5.phpt | 30 ------------ .../symfony_format_type_int32_intl6.phpt | 32 ------------ .../symfony_format_type_int32_intl7.phpt | 32 ------------ .../symfony_format_type_int64_intl1.phpt | 30 ------------ .../symfony_format_type_int64_intl2.phpt | 30 ------------ .../symfony_format_type_int64_intl3.phpt | 30 ------------ .../symfony_format_type_int64_intl4.phpt | 30 ------------ .../symfony_format_type_int64_intl5.phpt | 30 ------------ .../symfony_format_type_int64_intl6.phpt | 30 ------------ .../symfony_format_type_int64_intl7.phpt | 30 ------------ .../symfony_format_type_int64_intl8.phpt | 30 ------------ 21 files changed, 20 insertions(+), 599 deletions(-) create mode 100644 ext/intl/tests/bug74063.phpt delete mode 100644 ext/intl/tests/symfony_format_type_double_intl1.phpt delete mode 100644 ext/intl/tests/symfony_format_type_double_intl2.phpt delete mode 100644 ext/intl/tests/symfony_format_type_double_intl3.phpt delete mode 100644 ext/intl/tests/symfony_format_type_double_intl4.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int32_intl1.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int32_intl2.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int32_intl3.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int32_intl4.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int32_intl5.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int32_intl6.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int32_intl7.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl1.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl2.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl3.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl4.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl5.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl6.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl7.phpt delete mode 100644 ext/intl/tests/symfony_format_type_int64_intl8.phpt diff --git a/ext/intl/formatter/formatter_class.c b/ext/intl/formatter/formatter_class.c index 91efbed94ed87..d6c3493c8cb68 100644 --- a/ext/intl/formatter/formatter_class.c +++ b/ext/intl/formatter/formatter_class.c @@ -23,6 +23,7 @@ #include "formatter_attr.h" #include +#include "Zend/zend_interfaces.h" zend_class_entry *NumberFormatter_ce_ptr = NULL; static zend_object_handlers NumberFormatter_handlers; @@ -181,6 +182,8 @@ void formatter_register_class( void ) INIT_CLASS_ENTRY( ce, "NumberFormatter", NumberFormatter_class_functions ); ce.create_object = NumberFormatter_object_create; NumberFormatter_ce_ptr = zend_register_internal_class( &ce ); + NumberFormatter_ce_ptr->serialize = zend_class_serialize_deny; + NumberFormatter_ce_ptr->unserialize = zend_class_unserialize_deny; memcpy(&NumberFormatter_handlers, &std_object_handlers, sizeof(NumberFormatter_handlers)); diff --git a/ext/intl/tests/bug74063.phpt b/ext/intl/tests/bug74063.phpt new file mode 100644 index 0000000000000..126c4cc5233b4 --- /dev/null +++ b/ext/intl/tests/bug74063.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #74063 (NumberFormatter fails after retrieval from session) +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +?> +--EXPECT-- +Serialization of 'NumberFormatter' is not allowed diff --git a/ext/intl/tests/symfony_format_type_double_intl1.phpt b/ext/intl/tests/symfony_format_type_double_intl1.phpt deleted file mode 100644 index 9a5c6b2a25893..0000000000000 --- a/ext/intl/tests/symfony_format_type_double_intl1.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeDoubleIntl #1 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_DOUBLE); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - int(1) - [2]=> - string(1) "1" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_double_intl2.phpt b/ext/intl/tests/symfony_format_type_double_intl2.phpt deleted file mode 100644 index e5014c6f34db1..0000000000000 --- a/ext/intl/tests/symfony_format_type_double_intl2.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeDoubleIntl #2 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_DOUBLE); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(1.1) - [2]=> - string(3) "1.1" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_double_intl3.phpt b/ext/intl/tests/symfony_format_type_double_intl3.phpt deleted file mode 100644 index fbfd629b75a92..0000000000000 --- a/ext/intl/tests/symfony_format_type_double_intl3.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeDoubleIntl #3 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_DOUBLE); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - int(1) - [2]=> - string(7) "SFD1.00" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_double_intl4.phpt b/ext/intl/tests/symfony_format_type_double_intl4.phpt deleted file mode 100644 index b736c23dab31b..0000000000000 --- a/ext/intl/tests/symfony_format_type_double_intl4.phpt +++ /dev/null @@ -1,31 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeDoubleIntl #4 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_DOUBLE); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} -?> ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(1.1) - [2]=> - string(7) "SFD1.10" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int32_intl1.phpt b/ext/intl/tests/symfony_format_type_int32_intl1.phpt deleted file mode 100644 index 717414fc6f16f..0000000000000 --- a/ext/intl/tests/symfony_format_type_int32_intl1.phpt +++ /dev/null @@ -1,49 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #1 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT32); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - int(1) - [2]=> - string(1) "1" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int32_intl2.phpt b/ext/intl/tests/symfony_format_type_int32_intl2.phpt deleted file mode 100644 index 4b84ec1979281..0000000000000 --- a/ext/intl/tests/symfony_format_type_int32_intl2.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #2 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT32); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(1.1) - [2]=> - string(1) "1" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int32_intl3.phpt b/ext/intl/tests/symfony_format_type_int32_intl3.phpt deleted file mode 100644 index efe35dd8b01b0..0000000000000 --- a/ext/intl/tests/symfony_format_type_int32_intl3.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #3 ---SKIPIF-- - ---FILE-- -format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range.";}'); - -var_dump($unit_test_args); - -// execute the code from #testFormatTypeInt32Intl -try { - $unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(4) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(2147483648) - [2]=> - string(14) "-2,147,483,648" - [3]=> - string(83) "->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range." -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int32_intl4.phpt b/ext/intl/tests/symfony_format_type_int32_intl4.phpt deleted file mode 100644 index 8f6ea7b0c0594..0000000000000 --- a/ext/intl/tests/symfony_format_type_int32_intl4.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #4 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT32); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - int(1) - [2]=> - string(7) "SFD1.00" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int32_intl5.phpt b/ext/intl/tests/symfony_format_type_int32_intl5.phpt deleted file mode 100644 index b9d302a12f250..0000000000000 --- a/ext/intl/tests/symfony_format_type_int32_intl5.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #5 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT32); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(1.1) - [2]=> - string(7) "SFD1.00" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int32_intl6.phpt b/ext/intl/tests/symfony_format_type_int32_intl6.phpt deleted file mode 100644 index b00f3f7ce9480..0000000000000 --- a/ext/intl/tests/symfony_format_type_int32_intl6.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #6 ---SKIPIF-- - ---FILE-- -format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range.";}'); - -var_dump($unit_test_args); - -// execute the code from #testFormatTypeInt32Intl -try { - $unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(4) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(2147483648) - [2]=> - string(21) "(SFD2,147,483,648.00)" - [3]=> - string(83) "->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range." -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int32_intl7.phpt b/ext/intl/tests/symfony_format_type_int32_intl7.phpt deleted file mode 100644 index 747074f090665..0000000000000 --- a/ext/intl/tests/symfony_format_type_int32_intl7.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt32Intl #7 ---SKIPIF-- - ---FILE-- -format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range.";}'); - -var_dump($unit_test_args); - -// execute the code from #testFormatTypeInt32Intl -try { - $unit_test_args[0]->format($unit_test_args[1], \NumberFormatter::TYPE_INT32); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(4) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(-2147483649) - [2]=> - string(19) "SFD2,147,483,647.00" - [3]=> - string(83) "->format() TYPE_INT32 formats inconsistently an integer if out of the 32 bit range." -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int64_intl1.phpt b/ext/intl/tests/symfony_format_type_int64_intl1.phpt deleted file mode 100644 index 01f5820911748..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl1.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #1 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); - -echo "== didn't crash ==".PHP_EOL; - -?> ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - int(1) - [2]=> - string(1) "1" -} -== didn't crash == diff --git a/ext/intl/tests/symfony_format_type_int64_intl2.phpt b/ext/intl/tests/symfony_format_type_int64_intl2.phpt deleted file mode 100644 index f659ac373d516..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl2.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #2 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(1.1) - [2]=> - string(1) "1" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int64_intl3.phpt b/ext/intl/tests/symfony_format_type_int64_intl3.phpt deleted file mode 100644 index e40b74775c6ea..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl3.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #3 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(2147483648) - [2]=> - string(13) "2,147,483,648" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int64_intl4.phpt b/ext/intl/tests/symfony_format_type_int64_intl4.phpt deleted file mode 100644 index 8785b83c0adae..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl4.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #4 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(-2147483649) - [2]=> - string(14) "-2,147,483,649" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int64_intl5.phpt b/ext/intl/tests/symfony_format_type_int64_intl5.phpt deleted file mode 100644 index 476e66b61ea51..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl5.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #5 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - int(1) - [2]=> - string(7) "SFD1.00" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int64_intl6.phpt b/ext/intl/tests/symfony_format_type_int64_intl6.phpt deleted file mode 100644 index 5c24fe9617a07..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl6.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #6 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(1.1) - [2]=> - string(7) "SFD1.00" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int64_intl7.phpt b/ext/intl/tests/symfony_format_type_int64_intl7.phpt deleted file mode 100644 index 27b5a79f24d0d..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl7.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #7 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(2147483648) - [2]=> - string(19) "SFD2,147,483,648.00" -} -Found unconstructed NumberFormatter diff --git a/ext/intl/tests/symfony_format_type_int64_intl8.phpt b/ext/intl/tests/symfony_format_type_int64_intl8.phpt deleted file mode 100644 index d33395d6b3059..0000000000000 --- a/ext/intl/tests/symfony_format_type_int64_intl8.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Symfony StubNumberFormatterTest#testFormatTypeInt64Intl #8 ---SKIPIF-- - ---FILE-- -format($unit_test_args[1], \NumberFormatter::TYPE_INT64); -} catch (Error $exception) { - echo $exception->getMessage() . "\n"; -} ---EXPECT-- -array(3) { - [0]=> - object(NumberFormatter)#1 (0) { - } - [1]=> - float(-2147483649) - [2]=> - string(21) "(SFD2,147,483,649.00)" -} -Found unconstructed NumberFormatter From 429f194f406e8d8255a12af210aa4bde3f9e1433 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 11:01:13 +0100 Subject: [PATCH 48/80] Fix UAF in is_callable() and allocated trampoline By nulling out the function_handler, so it will not get used below. Reuse the existing helper for this purpose. --- Zend/tests/is_callable_trampoline_uaf.phpt | 27 ++++++++++++++++++++++ Zend/zend_API.c | 8 +------ 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 Zend/tests/is_callable_trampoline_uaf.phpt diff --git a/Zend/tests/is_callable_trampoline_uaf.phpt b/Zend/tests/is_callable_trampoline_uaf.phpt new file mode 100644 index 0000000000000..2410864410ab4 --- /dev/null +++ b/Zend/tests/is_callable_trampoline_uaf.phpt @@ -0,0 +1,27 @@ +--TEST-- +is_callable() with trampoline should not caused UAF +--FILE-- +bar('foo')); + +?> +--EXPECT-- +bool(false) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 4511368bea7a0..b7af44a32a573 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3154,13 +3154,7 @@ static zend_always_inline int zend_is_callable_check_func(int check_flags, zval if (strict_class && (!fcc->function_handler->common.scope || !instanceof_function(ce_org, fcc->function_handler->common.scope))) { - if (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION && - fcc->function_handler->common.function_name) { - zend_string_release_ex(fcc->function_handler->common.function_name, 0); - } - zend_free_trampoline(fcc->function_handler); - } + zend_release_fcall_info_cache(fcc); } else { retval = 1; call_via_handler = (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; From 98deece6f75c173e4847c5fd16b4c0b2ba0b47ac Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 11:03:14 +0100 Subject: [PATCH 49/80] Reset trampoline on executor startup Make sure the trampoline is usable, even if we had an unclean shutdown on the last request. --- Zend/zend_execute_API.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e1001062e570e..4277df1a1fe11 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -173,6 +173,7 @@ void init_executor(void) /* {{{ */ EG(prev_exception) = NULL; EG(fake_scope) = NULL; + EG(trampoline).common.function_name = NULL; EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator); EG(ht_iterators_used) = 0; From 472fc3a2a9accc695aae1c3c10cb846396d64910 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 11:13:04 +0100 Subject: [PATCH 50/80] Fix leak in DatePeriod construction with invalid format Same issue as I fixed in DateInterval construction before. --- ext/date/php_date.c | 3 +++ ext/date/tests/date_interval_bad_format_leak.phpt | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 8b1bda20f0b92..2ac5a30d937ed 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4266,6 +4266,9 @@ static int date_period_initialize(timelib_time **st, timelib_time **et, timelib_ if (errors->error_count > 0) { php_error_docref(NULL, E_WARNING, "Unknown or bad format (%s)", format); retval = FAILURE; + if (p) { + timelib_rel_time_dtor(p); + } } else { *st = b; *et = e; diff --git a/ext/date/tests/date_interval_bad_format_leak.phpt b/ext/date/tests/date_interval_bad_format_leak.phpt index 9d8af25ea4d4c..d15bf57b3f010 100644 --- a/ext/date/tests/date_interval_bad_format_leak.phpt +++ b/ext/date/tests/date_interval_bad_format_leak.phpt @@ -9,6 +9,13 @@ try { echo $e->getMessage(), "\n"; } +try { + $perid = new DatePeriod('P3"D'); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + ?> --EXPECT-- DateInterval::__construct(): Unknown or bad format (P3"D) +DatePeriod::__construct(): Unknown or bad format (P3"D) From 6ccd67577696b9c8bf3d88b521320720771dfc09 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 11:20:42 +0100 Subject: [PATCH 51/80] Add SKIPIF to test requiring mbregex --- ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt index 7fe6d31128192..1a78b2727286c 100644 --- a/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt +++ b/ext/mbstring/tests/mb_ereg_search_invalid_pattern.phpt @@ -1,5 +1,7 @@ --TEST-- mb_ereg_search() with invalid pattern should discard old matches +--SKIPIF-- + --FILE-- Date: Thu, 30 Jan 2020 11:55:38 +0100 Subject: [PATCH 52/80] Fix copying of functions in variance obligations Only copy sizeof(zend_internal_function) for internal functions. --- .../type_declarations/variance/internal_parent.phpt | 12 ++++++++++++ Zend/zend_inheritance.c | 13 +++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/type_declarations/variance/internal_parent.phpt diff --git a/Zend/tests/type_declarations/variance/internal_parent.phpt b/Zend/tests/type_declarations/variance/internal_parent.phpt new file mode 100644 index 0000000000000..eaef902b668f3 --- /dev/null +++ b/Zend/tests/type_declarations/variance/internal_parent.phpt @@ -0,0 +1,12 @@ +--TEST-- +Internal class as parent +--FILE-- + +--EXPECTF-- +Warning: Could not check compatibility between Test::createFromFormat($format, $time, ?Wrong $timezone = NULL) and DateTime::createFromFormat($format, $time, ?DateTimeZone $object = NULL), because class Wrong is not available in %s on line %d diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 442ab8afc14b8..6bd35a6bb788d 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -2294,8 +2294,17 @@ static void add_compatibility_obligation( HashTable *obligations = get_or_init_obligations_for_class(ce); variance_obligation *obligation = emalloc(sizeof(variance_obligation)); obligation->type = OBLIGATION_COMPATIBILITY; - obligation->child_fn = *child_fn; - obligation->parent_fn = *parent_fn; + /* Copy functions, because they may be stack-allocated in the case of traits. */ + if (child_fn->common.type == ZEND_INTERNAL_FUNCTION) { + memcpy(&obligation->child_fn, child_fn, sizeof(zend_internal_function)); + } else { + memcpy(&obligation->child_fn, child_fn, sizeof(zend_op_array)); + } + if (parent_fn->common.type == ZEND_INTERNAL_FUNCTION) { + memcpy(&obligation->parent_fn, parent_fn, sizeof(zend_internal_function)); + } else { + memcpy(&obligation->parent_fn, parent_fn, sizeof(zend_op_array)); + } obligation->always_error = always_error; zend_hash_next_index_insert_ptr(obligations, obligation); } From 24a3d0dbd0b4a7eb543483a28e8497d9c79ab206 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 12:12:09 +0100 Subject: [PATCH 53/80] Update test for warning -> fatal error change --- Zend/tests/type_declarations/variance/internal_parent.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/tests/type_declarations/variance/internal_parent.phpt b/Zend/tests/type_declarations/variance/internal_parent.phpt index eaef902b668f3..d31dcb17a82b4 100644 --- a/Zend/tests/type_declarations/variance/internal_parent.phpt +++ b/Zend/tests/type_declarations/variance/internal_parent.phpt @@ -9,4 +9,4 @@ class Test extends DateTime { ?> --EXPECTF-- -Warning: Could not check compatibility between Test::createFromFormat($format, $time, ?Wrong $timezone = NULL) and DateTime::createFromFormat($format, $time, ?DateTimeZone $object = NULL), because class Wrong is not available in %s on line %d +Fatal error: Could not check compatibility between Test::createFromFormat($format, $time, ?Wrong $timezone = NULL) and DateTime::createFromFormat(string $format, string $time, ?DateTimeZone $timezone = NULL), because class Wrong is not available in %s on line %d From 494615fcb8c1fb5984e0e7d666e51a2dfc6bee55 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 12:16:43 +0100 Subject: [PATCH 54/80] Fix leak in DateTimeImmutable::modify() --- ext/date/php_date.c | 1 + .../DateTimeImmutable_modify_invalid_format.phpt | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 ext/date/tests/DateTimeImmutable_modify_invalid_format.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 785c1b222e563..bec60aab6d52b 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -3297,6 +3297,7 @@ PHP_METHOD(DateTimeImmutable, modify) date_clone_immutable(object, &new_object); if (!php_date_modify(&new_object, modify, modify_len)) { + zval_ptr_dtor(&new_object); RETURN_FALSE; } diff --git a/ext/date/tests/DateTimeImmutable_modify_invalid_format.phpt b/ext/date/tests/DateTimeImmutable_modify_invalid_format.phpt new file mode 100644 index 0000000000000..3386f725acffa --- /dev/null +++ b/ext/date/tests/DateTimeImmutable_modify_invalid_format.phpt @@ -0,0 +1,12 @@ +--TEST-- +DateTimeImmutable::modify() with invalid format +--FILE-- +modify('')); + +?> +--EXPECTF-- +Warning: DateTimeImmutable::modify(): Failed to parse time string () at position 0 ( in %s on line %d +bool(false) From 8226e704e4e6066a5bd41b57b2934a3371896be2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 29 Jan 2020 18:23:51 +0100 Subject: [PATCH 55/80] Fix #70078: XSL callbacks with nodes as parameter leak memory The fix for bug #49634 solved a double-free by copying the node with `xmlDocCopyNodeList()`, but the copied node is later freed by calling `xmlFreeNode()` instead of `xmlFreeNodeList()`, thus leaking memory. However, there is no need to treat the node as node list, i.e. to copy also the node's siblings; just creating a recursive copy of the node with `xmlDocCopyNode()` is sufficient, while that also avoids the leak. --- NEWS | 3 +++ ext/xsl/tests/bug70078.phpt | 51 +++++++++++++++++++++++++++++++++++++ ext/xsl/xsltprocessor.c | 2 +- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 ext/xsl/tests/bug70078.phpt diff --git a/NEWS b/NEWS index fc8aac06018e3..b5ac3d68781bf 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,9 @@ PHP NEWS - Standard: . Fixed bug #78902 (Memory leak when using stream_filter_append). (liudaixiao) +- XSL: + . Fixed bug #70078 (XSL callbacks with nodes as parameter leak memory). (cmb) + 23 Jan 2020, PHP 7.3.14 - Core diff --git a/ext/xsl/tests/bug70078.phpt b/ext/xsl/tests/bug70078.phpt new file mode 100644 index 0000000000000..41e9485a0f074 --- /dev/null +++ b/ext/xsl/tests/bug70078.phpt @@ -0,0 +1,51 @@ +--TEST-- +Bug #70078 (XSL callbacks with nodes as parameter leak memory) +--SKIPIF-- + +--FILE-- +appendChild($dom->createElement('root')); +for ($i = 0; $i <= 100; $i++) { + $level1Node = $rootNode->appendChild($dom->createElement('level1')); + for ($j = 0; $j <= 100; $j++) { + $level2Node = $level1Node->appendChild($dom->createElement('level2')); + for ($k = 0; $k <= 10; $k++) { + $level3Node = $level2Node->appendChild($dom->createElement('level3', 'test')); + } + } +} + +function testPhpFunction($node) { + return 'test2'; +} + +$xslStr = << + + + + + + + + + + + +EOF; + +$xsl = new \DOMDocument(); +$xsl->loadXML($xslStr); +$xslt = new \XSLTProcessor(); +$xslt->registerPHPFunctions('testPhpFunction'); +$xslt->importStyleSheet($xsl); + +echo $xslt->transformToXML($dom); +?> +--EXPECT-- + +test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2test2 diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index accee6c9aceee..182aab68d6607 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -274,7 +274,7 @@ static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int t node->parent = nsparent; node->ns = curns; } else { - node = xmlDocCopyNodeList(domintern->document->ptr, node); + node = xmlDocCopyNode(node, domintern->document->ptr, 1); } php_dom_create_object(node, &child, domintern); From 01d30f880a0f333650164a20bff52a77af9814d9 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 13:09:15 +0100 Subject: [PATCH 56/80] Fix DatePeriod property handling with indirect modification We do need to implement get_property_ptr_ptr to make arrays work correctly. --- ext/date/php_date.c | 14 ++++++++++---- ext/date/tests/bug65672.phpt | 7 +++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index db04b53c34089..5e70ffc10d3ed 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -5423,15 +5423,21 @@ static zval *date_period_write_property(zval *object, zval *member, zval *value, } zend_string_release(name); - std_object_handlers.write_property(object, member, value, cache_slot); - return value; + return zend_std_write_property(object, member, value, cache_slot); } /* }}} */ /* {{{ date_period_get_property_ptr_ptr */ static zval *date_period_get_property_ptr_ptr(zval *object, zval *member, int type, void **cache_slot) { - /* Fall back to read_property handler. */ - return NULL; + zend_string *name = zval_get_string(member); + if (date_period_is_magic_property(name)) { + zend_throw_error(NULL, "Retrieval of DatePeriod->%s for modification is unsupported", ZSTR_VAL(name)); + zend_string_release(name); + return &EG(error_zval); + } + zend_string_release(name); + + return zend_std_get_property_ptr_ptr(object, member, type, cache_slot); } /* }}} */ diff --git a/ext/date/tests/bug65672.phpt b/ext/date/tests/bug65672.phpt index a84cff69ae9c4..a01287d9b4c04 100644 --- a/ext/date/tests/bug65672.phpt +++ b/ext/date/tests/bug65672.phpt @@ -28,6 +28,9 @@ $period->dynamic2 = []; $period->dynamic2[] = "array"; var_dump($period->dynamic2); +$period->dynamic3[] = "array"; +var_dump($period->dynamic3); + ?> --EXPECT-- string(5) "stuff" @@ -42,3 +45,7 @@ array(1) { [0]=> string(5) "array" } +array(1) { + [0]=> + string(5) "array" +} From be7eab3202567a1acf0158d281362c20d5051767 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 14:23:46 +0100 Subject: [PATCH 57/80] Fix live range calculation for FE_FETCH Op2 is def here, not a use, so treat it accordingly. --- Zend/tests/fe_fetch_op2_live_range.phpt | 12 ++++++++++++ Zend/zend_opcode.c | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/fe_fetch_op2_live_range.phpt diff --git a/Zend/tests/fe_fetch_op2_live_range.phpt b/Zend/tests/fe_fetch_op2_live_range.phpt new file mode 100644 index 0000000000000..c601e43120e02 --- /dev/null +++ b/Zend/tests/fe_fetch_op2_live_range.phpt @@ -0,0 +1,12 @@ +--TEST-- +FE_FETCH op2 is a def and needs special live range handling +--FILE-- + func()[]) {} +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Call to undefined function func() diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index a128f9436ea91..d0d49934fe039 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -817,7 +817,17 @@ static void zend_calc_live_ranges( } if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) { uint32_t var_num = EX_VAR_TO_NUM(opline->op2.var) - var_offset; - if (EXPECTED(last_use[var_num] == (uint32_t) -1)) { + if (UNEXPECTED(opline->opcode == ZEND_FE_FETCH_R + || opline->opcode == ZEND_FE_FETCH_RW)) { + /* OP2 of FE_FETCH is actually a def, not a use. */ + if (last_use[var_num] != (uint32_t) -1) { + if (opnum + 1 != last_use[var_num]) { + emit_live_range( + op_array, var_num, opnum, last_use[var_num], needs_live_range); + } + last_use[var_num] = (uint32_t) -1; + } + } else if (EXPECTED(last_use[var_num] == (uint32_t) -1)) { #if 1 /* OP_DATA uses only op1 operand */ ZEND_ASSERT(opline->opcode != ZEND_OP_DATA); From f70b552326e5242655d6ac2c55ca220e89afef34 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 14:55:58 +0100 Subject: [PATCH 58/80] Fixed bug #79193 --- NEWS | 2 ++ ext/opcache/Optimizer/zend_inference.c | 7 +++++++ ext/opcache/tests/bug79193.phpt | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 ext/opcache/tests/bug79193.phpt diff --git a/NEWS b/NEWS index 2dcfdf9db3b3e..a4ef1ef469b11 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,8 @@ PHP NEWS . Fixed bug #79114 (Eval class during preload causes class to be only half available). (Laruence) . Fixed bug #79128 (Preloading segfaults if preload_user is used). (Nikita) + . Fixed bug #79193 (Incorrect type inference for self::$field =& $field). + (Nikita) - OpenSSL: . Fixed bug #79145 (openssl memory leak). (cmb, Nikita) diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index f89b133b9267a..7accf73a5d4e6 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2999,6 +2999,13 @@ static int zend_update_type_info(const zend_op_array *op_array, UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def); } break; + case ZEND_ASSIGN_STATIC_PROP_REF: + if ((opline+1)->op1_type == IS_CV) { + opline++; + i++; + UPDATE_SSA_TYPE(MAY_BE_REF, ssa_ops[i].op1_def); + } + break; case ZEND_BIND_GLOBAL: tmp = MAY_BE_REF | MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; diff --git a/ext/opcache/tests/bug79193.phpt b/ext/opcache/tests/bug79193.phpt new file mode 100644 index 0000000000000..c500400363a73 --- /dev/null +++ b/ext/opcache/tests/bug79193.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #79193: Incorrect type inference for self::$field =& $field +--FILE-- + +--EXPECT-- +bool(true) From ca8657a2b502791b1ec0587948741098ca82e314 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 15:31:39 +0100 Subject: [PATCH 59/80] Initialize SplFixedArray elements to NULL instead of UNDEF The SplFixedArray API treats all elements as NULL, even if they have not been explicitly initialized. Rather than initializing to UNDEF an treating that specially in various circumstances, directly initialize elements to NULL. This also fixes an assertion failure in the attached test case. --- ext/spl/spl_fixedarray.c | 50 +++++++------------ .../SplFixedArray_indirect_modification.phpt | 14 ++++++ 2 files changed, 33 insertions(+), 31 deletions(-) create mode 100644 ext/spl/tests/SplFixedArray_indirect_modification.phpt diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 0ac8d124f3798..b423774d8e021 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -76,12 +76,19 @@ static inline spl_fixedarray_object *spl_fixed_array_from_obj(zend_object *obj) #define Z_SPLFIXEDARRAY_P(zv) spl_fixed_array_from_obj(Z_OBJ_P((zv))) +static inline void spl_fixedarray_init_elems(spl_fixedarray *array, size_t from, size_t to) { + for (size_t i = from; i < to; i++) { + ZVAL_NULL(&array->elements[i]); + } +} + static void spl_fixedarray_init(spl_fixedarray *array, zend_long size) /* {{{ */ { if (size > 0) { array->size = 0; /* reset size in case ecalloc() fails */ - array->elements = ecalloc(size, sizeof(zval)); + array->elements = safe_emalloc(size, sizeof(zval), 0); array->size = size; + spl_fixedarray_init_elems(array, 0, size); } else { array->elements = NULL; array->size = 0; @@ -116,7 +123,7 @@ static void spl_fixedarray_resize(spl_fixedarray *array, zend_long size) /* {{{ } } else if (size > array->size) { array->elements = safe_erealloc(array->elements, size, sizeof(zval), 0); - memset(array->elements + array->size, '\0', sizeof(zval) * (size - array->size)); + spl_fixedarray_init_elems(array, array->size, size); } else { /* size < array->size */ zend_long i; @@ -161,12 +168,8 @@ static HashTable* spl_fixedarray_object_get_properties(zend_object *obj) /* {{{{ zend_long j = zend_hash_num_elements(ht); for (i = 0; i < intern->array.size; i++) { - if (!Z_ISUNDEF(intern->array.elements[i])) { - zend_hash_index_update(ht, i, &intern->array.elements[i]); - Z_TRY_ADDREF(intern->array.elements[i]); - } else { - zend_hash_index_update(ht, i, &EG(uninitialized_zval)); - } + zend_hash_index_update(ht, i, &intern->array.elements[i]); + Z_TRY_ADDREF(intern->array.elements[i]); } if (j > intern->array.size) { for (i = intern->array.size; i < j; ++i) { @@ -323,8 +326,6 @@ static inline zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_o if (index < 0 || index >= intern->array.size) { zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return NULL; - } else if (Z_ISUNDEF(intern->array.elements[index])) { - return NULL; } else { return &intern->array.elements[index]; } @@ -392,9 +393,7 @@ static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_o zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0); return; } else { - if (!Z_ISUNDEF(intern->array.elements[index])) { - zval_ptr_dtor(&(intern->array.elements[index])); - } + zval_ptr_dtor(&(intern->array.elements[index])); ZVAL_COPY_DEREF(&intern->array.elements[index], value); } } @@ -440,7 +439,7 @@ static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_o return; } else { zval_ptr_dtor(&(intern->array.elements[index])); - ZVAL_UNDEF(&intern->array.elements[index]); + ZVAL_NULL(&intern->array.elements[index]); } } /* }}} */ @@ -459,7 +458,6 @@ static void spl_fixedarray_object_unset_dimension(zend_object *object, zval *off } spl_fixedarray_object_unset_dimension_helper(intern, offset); - } /* }}} */ @@ -477,16 +475,10 @@ static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_obje if (index < 0 || index >= intern->array.size) { retval = 0; } else { - if (Z_ISUNDEF(intern->array.elements[index])) { - retval = 0; - } else if (check_empty) { - if (zend_is_true(&intern->array.elements[index])) { - retval = 1; - } else { - retval = 0; - } - } else { /* != NULL and !check_empty */ - retval = 1; + if (check_empty) { + retval = zend_is_true(&intern->array.elements[index]); + } else { + retval = Z_TYPE(intern->array.elements[index]) != IS_NULL; } } @@ -628,12 +620,8 @@ SPL_METHOD(SplFixedArray, toArray) array_init(return_value); for (; i < intern->array.size; i++) { - if (!Z_ISUNDEF(intern->array.elements[i])) { - zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]); - Z_TRY_ADDREF(intern->array.elements[i]); - } else { - zend_hash_index_update(Z_ARRVAL_P(return_value), i, &EG(uninitialized_zval)); - } + zend_hash_index_update(Z_ARRVAL_P(return_value), i, &intern->array.elements[i]); + Z_TRY_ADDREF(intern->array.elements[i]); } } else { RETURN_EMPTY_ARRAY(); diff --git a/ext/spl/tests/SplFixedArray_indirect_modification.phpt b/ext/spl/tests/SplFixedArray_indirect_modification.phpt new file mode 100644 index 0000000000000..ab85b3a09eec1 --- /dev/null +++ b/ext/spl/tests/SplFixedArray_indirect_modification.phpt @@ -0,0 +1,14 @@ +--TEST-- +SplFixedArray indirect modification notice +--FILE-- + +--EXPECTF-- +Notice: Indirect modification of overloaded element of SplFixedArray has no effect in %s on line %d +object(SplFixedArray)#1 (1) { + [0]=> + NULL +} From f0f5c415a6e0abc40514f97113deb52a343174ee Mon Sep 17 00:00:00 2001 From: Pascal de Bruijn Date: Thu, 30 Jan 2020 13:48:44 +0100 Subject: [PATCH 60/80] fix cross compilation failure due to size_t typecast in define MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following commit introduces a cross-compilation failure: 93c728b77cfb47f5cfdd1863f8982ea59d344205 "Try to control ZEND_MM_ALIGNED_SIZE type" br-arm-full/build/php-7.4.2/Zend/zend_alloc.h:30:38: error: missing binary operator before token "8" ^ br-arm-full/build/php-7.4.2/ext/opcache/ZendAccelerator.c:1380:7: note: in expansion of macro ‘ZEND_MM_ALIGNMENT’ Closes GH-5128. --- Zend/zend_alloc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index c5838f2ac684b..8bb854328dbdd 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -27,12 +27,12 @@ #include "zend.h" #ifndef ZEND_MM_ALIGNMENT -# define ZEND_MM_ALIGNMENT ((size_t) 8) +# define ZEND_MM_ALIGNMENT Z_UL(8) # define ZEND_MM_ALIGNMENT_LOG2 Z_L(3) #elif ZEND_MM_ALIGNMENT < 4 # undef ZEND_MM_ALIGNMENT # undef ZEND_MM_ALIGNMENT_LOG2 -# define ZEND_MM_ALIGNMENT ((size_t) 4) +# define ZEND_MM_ALIGNMENT Z_UL(4) # define ZEND_MM_ALIGNMENT_LOG2 Z_L(2) #endif From 453713868fa6e5bf0785c2f33e0b4415166418e6 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Jan 2020 16:18:02 +0100 Subject: [PATCH 61/80] Revert "Make BG(syslog_device) per request" This reverts commit b0d7b126a29a1972229ac91d6d28f5331912eddb. This change wasn't quite right: I noticed only now that the RSHUTDOWN function is #ifdef PHP_WIN32 and I'm not fully convinced that ifdef can be removed: syslog might also be used by error logging in FPM for example, in which case we probably shouldn't be closing the log here. Generally it's unclear how the openlog() functionality exposed by PHP is supposed to interact with openlog() uses by SAPIs. For now I'll just revert this change and let it leak across requests. --- ext/standard/syslog.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ext/standard/syslog.c b/ext/standard/syslog.c index d5a8fa6e2b418..b07f6d6a51c94 100644 --- a/ext/standard/syslog.c +++ b/ext/standard/syslog.c @@ -91,6 +91,7 @@ PHP_MINIT_FUNCTION(syslog) /* AIX doesn't have LOG_PERROR */ REGISTER_LONG_CONSTANT("LOG_PERROR", LOG_PERROR, CONST_CS | CONST_PERSISTENT); /*log to stderr*/ #endif + BG(syslog_device)=NULL; return SUCCESS; } @@ -107,16 +108,16 @@ PHP_RINIT_FUNCTION(syslog) PHP_RSHUTDOWN_FUNCTION(syslog) { closelog(); - if (BG(syslog_device)) { - efree(BG(syslog_device)); - BG(syslog_device) = NULL; - } return SUCCESS; } #endif PHP_MSHUTDOWN_FUNCTION(syslog) { + if (BG(syslog_device)) { + free(BG(syslog_device)); + BG(syslog_device) = NULL; + } return SUCCESS; } @@ -146,9 +147,9 @@ PHP_FUNCTION(openlog) ZEND_PARSE_PARAMETERS_END(); if (BG(syslog_device)) { - efree(BG(syslog_device)); + free(BG(syslog_device)); } - BG(syslog_device) = estrndup(ident, ident_len); + BG(syslog_device) = zend_strndup(ident, ident_len); if(BG(syslog_device) == NULL) { RETURN_FALSE; } @@ -165,8 +166,8 @@ PHP_FUNCTION(closelog) closelog(); if (BG(syslog_device)) { - efree(BG(syslog_device)); - BG(syslog_device) = NULL; + free(BG(syslog_device)); + BG(syslog_device)=NULL; } RETURN_TRUE; } From 5bf6aedae4556facb8b407426a13c4e8d5399dd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sun, 5 Jan 2020 19:49:34 +0100 Subject: [PATCH 62/80] Promote mysqli warnings to exceptions Closes GH-5058 --- ext/mysqli/mysqli.c | 5 +- ext/mysqli/mysqli_nonapi.c | 22 +- ext/mysqli/mysqli_prop.c | 12 +- ext/mysqli/mysqli_warning.c | 9 +- ext/mysqli/php_mysqli_structs.h | 16 +- ext/mysqli/tests/bug28817.phpt | 10 +- ext/mysqli/tests/bug36420.phpt | 17 +- ext/mysqli/tests/bug36802.phpt | 28 +- ext/mysqli/tests/bug63398.phpt | 16 +- ext/mysqli/tests/bug73462.phpt | 7 +- ext/mysqli/tests/bug75448.phpt | 14 +- ext/mysqli/tests/mysqli_affected_rows.phpt | 8 +- ext/mysqli/tests/mysqli_affected_rows_oo.phpt | 16 +- ext/mysqli/tests/mysqli_autocommit.phpt | 9 +- ext/mysqli/tests/mysqli_autocommit_oo.phpt | 8 +- ext/mysqli/tests/mysqli_change_user.phpt | 8 +- .../tests/mysqli_character_set_name.phpt | 9 +- .../tests/mysqli_character_set_name_oo.phpt | 18 +- ...ysqli_class_mysqli_properties_no_conn.phpt | 480 +++++++++++------- .../mysqli_class_mysqli_result_interface.phpt | 8 +- .../mysqli_class_mysqli_stmt_interface.phpt | 29 +- .../tests/mysqli_class_mysqli_warning.phpt | 10 +- ext/mysqli/tests/mysqli_close.phpt | 9 +- ext/mysqli/tests/mysqli_close_oo.phpt | 16 +- ext/mysqli/tests/mysqli_commit.phpt | 8 +- ext/mysqli/tests/mysqli_commit_oo.phpt | 20 +- ext/mysqli/tests/mysqli_connect_oo.phpt | 24 +- ext/mysqli/tests/mysqli_data_seek.phpt | 10 +- ext/mysqli/tests/mysqli_data_seek_oo.phpt | 21 +- .../mysqli_disable_reads_from_master.phpt | 2 +- ext/mysqli/tests/mysqli_dump_debug_info.phpt | 14 +- .../tests/mysqli_dump_debug_info_oo.phpt | 13 +- .../mysqli_enable_reads_from_master.phpt | 8 +- ext/mysqli/tests/mysqli_errno.phpt | 10 +- ext/mysqli/tests/mysqli_errno_oo.phpt | 10 +- ext/mysqli/tests/mysqli_error.phpt | 11 +- ext/mysqli/tests/mysqli_error_oo.phpt | 11 +- ext/mysqli/tests/mysqli_error_unicode.phpt | 11 +- ext/mysqli/tests/mysqli_fetch_all.phpt | 16 +- ext/mysqli/tests/mysqli_fetch_all_oo.phpt | 10 +- ext/mysqli/tests/mysqli_fetch_array.phpt | 10 +- ext/mysqli/tests/mysqli_fetch_array_oo.phpt | 10 +- ext/mysqli/tests/mysqli_fetch_assoc.phpt | 12 +- ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt | 21 +- ext/mysqli/tests/mysqli_fetch_field.phpt | 10 +- .../tests/mysqli_fetch_field_direct.phpt | 10 +- .../tests/mysqli_fetch_field_direct_oo.phpt | 18 +- ext/mysqli/tests/mysqli_fetch_field_oo.phpt | 18 +- ext/mysqli/tests/mysqli_fetch_fields.phpt | 10 +- ext/mysqli/tests/mysqli_fetch_lengths.phpt | 12 +- ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt | 12 +- ext/mysqli/tests/mysqli_fetch_object.phpt | 9 +- ext/mysqli/tests/mysqli_fetch_object_oo.phpt | 21 +- ext/mysqli/tests/mysqli_fetch_row.phpt | 12 +- ext/mysqli/tests/mysqli_field_count.phpt | 13 +- ext/mysqli/tests/mysqli_field_seek.phpt | 10 +- ext/mysqli/tests/mysqli_field_tell.phpt | 10 +- ext/mysqli/tests/mysqli_free_result.phpt | 24 +- ext/mysqli/tests/mysqli_get_charset.phpt | 11 +- ext/mysqli/tests/mysqli_insert_id.phpt | 11 +- ext/mysqli/tests/mysqli_more_results.phpt | 10 +- ext/mysqli/tests/mysqli_multi_query.phpt | 10 +- ext/mysqli/tests/mysqli_next_result.phpt | 10 +- ext/mysqli/tests/mysqli_num_fields.phpt | 14 +- ext/mysqli/tests/mysqli_num_rows.phpt | 13 +- ext/mysqli/tests/mysqli_options.phpt | 13 +- ext/mysqli/tests/mysqli_pconn_kill.phpt | 7 +- ext/mysqli/tests/mysqli_ping.phpt | 12 +- ext/mysqli/tests/mysqli_query.phpt | 12 +- ext/mysqli/tests/mysqli_query_iterators.phpt | 14 +- ext/mysqli/tests/mysqli_query_unicode.phpt | 10 +- ext/mysqli/tests/mysqli_real_connect.phpt | 10 +- .../tests/mysqli_real_escape_string.phpt | 11 +- .../mysqli_real_escape_string_unicode.phpt | 11 +- ext/mysqli/tests/mysqli_real_query.phpt | 12 +- .../tests/mysqli_result_references.phpt | 1 + ext/mysqli/tests/mysqli_rollback.phpt | 11 +- ext/mysqli/tests/mysqli_select_db.phpt | 11 +- ext/mysqli/tests/mysqli_send_query.phpt | 10 +- ext/mysqli/tests/mysqli_set_charset.phpt | 11 +- ext/mysqli/tests/mysqli_set_opt.phpt | 12 +- ext/mysqli/tests/mysqli_sqlstate.phpt | 10 +- ext/mysqli/tests/mysqli_stat.phpt | 11 +- .../tests/mysqli_stmt_affected_rows.phpt | 10 +- ext/mysqli/tests/mysqli_stmt_attr_get.phpt | 20 +- ext/mysqli/tests/mysqli_stmt_attr_set.phpt | 8 +- ext/mysqli/tests/mysqli_stmt_bind_result.phpt | 10 +- ext/mysqli/tests/mysqli_stmt_close.phpt | 22 +- ext/mysqli/tests/mysqli_stmt_data_seek.phpt | 20 +- ext/mysqli/tests/mysqli_stmt_errno.phpt | 11 +- ext/mysqli/tests/mysqli_stmt_error.phpt | 11 +- ext/mysqli/tests/mysqli_stmt_execute.phpt | 33 +- ext/mysqli/tests/mysqli_stmt_fetch.phpt | 20 +- ext/mysqli/tests/mysqli_stmt_field_count.phpt | 42 +- ext/mysqli/tests/mysqli_stmt_free_result.phpt | 22 +- ext/mysqli/tests/mysqli_stmt_get_result.phpt | 42 +- ext/mysqli/tests/mysqli_stmt_get_result2.phpt | 16 +- .../mysqli_stmt_get_result_metadata.phpt | 30 +- .../tests/mysqli_stmt_get_result_seek.phpt | 43 +- .../tests/mysqli_stmt_get_warnings.phpt | 22 +- ext/mysqli/tests/mysqli_stmt_init.phpt | 21 +- ext/mysqli/tests/mysqli_stmt_insert_id.phpt | 20 +- ext/mysqli/tests/mysqli_stmt_num_rows.phpt | 12 +- ext/mysqli/tests/mysqli_stmt_param_count.phpt | 20 +- ext/mysqli/tests/mysqli_stmt_prepare.phpt | 11 +- ext/mysqli/tests/mysqli_stmt_reset.phpt | 22 +- .../tests/mysqli_stmt_result_metadata.phpt | 22 +- ext/mysqli/tests/mysqli_stmt_sqlstate.phpt | 22 +- .../tests/mysqli_stmt_store_result.phpt | 16 +- ext/mysqli/tests/mysqli_store_result.phpt | 9 +- ext/mysqli/tests/mysqli_thread_id.phpt | 11 +- ext/mysqli/tests/mysqli_use_result.phpt | 10 +- ext/mysqli/tests/mysqli_warning_count.phpt | 9 +- 113 files changed, 1278 insertions(+), 802 deletions(-) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index ba12ea1a80cf6..cbfbb451bc946 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -312,7 +312,7 @@ zval *mysqli_read_property(zend_object *object, zend_string *name, int type, voi } if (hnd) { - if (hnd->read_func(obj, rv, type == BP_VAR_IS) == SUCCESS || type != BP_VAR_IS) { + if (hnd->read_func(obj, rv, type == BP_VAR_IS) == SUCCESS) { retval = rv; } else { retval = &EG(uninitialized_zval); @@ -409,6 +409,7 @@ HashTable *mysqli_object_get_debug_info(zend_object *object, int *is_temp) ZEND_HASH_FOREACH_PTR(props, entry) { zval rv; zval *value; + value = mysqli_read_property(object, entry->name, BP_VAR_IS, 0, &rv); if (value != &EG(uninitialized_zval)) { zend_hash_add(retval, entry->name, value); @@ -470,7 +471,7 @@ static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv) mysqli_object *intern = Z_MYSQLI_P(zv); if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) { /* We know that we have a mysqli object, so this failure should be emitted */ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name)); + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name)); return NULL; } mysql = (MY_MYSQL *)(my_res->ptr); diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index ba725e6c51975..4ba77579da396 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -731,7 +731,7 @@ static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_ar int i = 0, current = 0; if (Z_TYPE_P(in_array) != IS_ARRAY) { - return 0; + return SUCCESS; } *out_array = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(in_array)) + 1, sizeof(MYSQLND *)); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_array), elem) { @@ -744,18 +744,18 @@ static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_ar MYSQLI_RESOURCE *my_res; mysqli_object *intern = Z_MYSQLI_P(elem); if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) { - php_error_docref(NULL, E_WARNING, "[%d] Couldn't fetch %s", i, ZSTR_VAL(intern->zo.ce->name)); - continue; + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name)); + return FAILURE; } mysql = (MY_MYSQL*) my_res->ptr; if (MYSQLI_STATUS_VALID && my_res->status < MYSQLI_STATUS_VALID) { - php_error_docref(NULL, E_WARNING, "Invalid object %d or resource %s", i, ZSTR_VAL(intern->zo.ce->name)); - continue; + zend_throw_error(NULL, "%s object is not fully initialized", ZSTR_VAL(intern->zo.ce->name)); + return FAILURE; } (*out_array)[current++] = mysql->mysql; } } ZEND_HASH_FOREACH_END(); - return 0; + return SUCCESS; } /* }}} */ @@ -859,10 +859,16 @@ PHP_FUNCTION(mysqli_poll) } if (r_array != NULL) { - mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array); + if (mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array) == FAILURE) { + efree(new_r_array); + RETURN_THROWS(); + } } if (e_array != NULL) { - mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array); + if (mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array) == FAILURE) { + efree(new_e_array); + RETURN_THROWS(); + } } ret = mysqlnd_poll(new_r_array, new_e_array, &new_dont_poll_array, sec, usec, &desc_num); diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index 45033057c0fd1..ef564a35d5bca 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -30,9 +30,8 @@ #define CHECK_STATUS(value, quiet) \ if (!obj->ptr || ((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \ if (!quiet) { \ - php_error_docref(NULL, E_WARNING, "Property access is not allowed yet"); \ + zend_throw_error(NULL, "Property access is not allowed yet"); \ } \ - ZVAL_FALSE(retval); \ return FAILURE; \ } \ @@ -40,9 +39,8 @@ MYSQL *p; \ if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \ if (!quiet) { \ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \ + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(obj->zo.ce->name)); \ } \ - ZVAL_FALSE(retval);\ return FAILURE; \ } else { \ CHECK_STATUS(statusval, quiet);\ @@ -53,9 +51,8 @@ if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \ MYSQL_RES *p; \ if (!obj->ptr) { \ if (!quiet) { \ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \ + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(obj->zo.ce->name)); \ } \ - ZVAL_NULL(retval);\ return FAILURE; \ } else { \ CHECK_STATUS(statusval, quiet);\ @@ -66,9 +63,8 @@ if (!obj->ptr) { \ MYSQL_STMT *p; \ if (!obj->ptr) { \ if (!quiet) { \ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \ + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(obj->zo.ce->name)); \ } \ - ZVAL_NULL(retval);\ return FAILURE; \ } else { \ CHECK_STATUS(statusval, quiet); \ diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index 5ba18c4f45dc2..380d2e3fd9232 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -203,9 +203,8 @@ static int mysqli_warning_message(mysqli_object *obj, zval *retval, zend_bool qu if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { if (!quiet) { - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); + zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); } - ZVAL_NULL(retval); return FAILURE; } @@ -224,9 +223,8 @@ static int mysqli_warning_sqlstate(mysqli_object *obj, zval *retval, zend_bool q if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { if (!quiet) { - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); + zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); } - ZVAL_NULL(retval); return FAILURE; } @@ -245,9 +243,8 @@ static int mysqli_warning_errno(mysqli_object *obj, zval *retval, zend_bool quie if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { if (!quiet) { - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); + zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); } - ZVAL_NULL(retval); return FAILURE; } diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h index 249b1b553d83f..02d97b29bcfe9 100644 --- a/ext/mysqli/php_mysqli_structs.h +++ b/ext/mysqli/php_mysqli_structs.h @@ -246,13 +246,13 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul MYSQLI_RESOURCE *my_res; \ mysqli_object *intern = Z_MYSQLI_P(__id); \ if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name));\ - RETURN_FALSE;\ + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name));\ + RETURN_THROWS();\ }\ __ptr = (__type)my_res->ptr; \ if (__check && my_res->status < __check) { \ - php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \ - RETURN_FALSE;\ + zend_throw_error(NULL, "%s object is not fully initialized", ZSTR_VAL(intern->zo.ce->name)); \ + RETURN_THROWS();\ }\ } @@ -260,12 +260,12 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul { \ MYSQLI_RESOURCE *my_res; \ if (!(my_res = (MYSQLI_RESOURCE *)(__obj->ptr))) {\ - php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name));\ - return;\ - }\ + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name));\ + return;\ + }\ __ptr = (__type)my_res->ptr; \ if (__check && my_res->status < __check) { \ - php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \ + zend_throw_error(NULL, "%s object is not fully initialized", ZSTR_VAL(intern->zo.ce->name)); \ return;\ }\ } diff --git a/ext/mysqli/tests/bug28817.phpt b/ext/mysqli/tests/bug28817.phpt index 18370485178d3..011d35e011bab 100644 --- a/ext/mysqli/tests/bug28817.phpt +++ b/ext/mysqli/tests/bug28817.phpt @@ -22,7 +22,11 @@ require_once('skipifconnectfailure.inc'); $mysql = new my_mysql(); var_dump($mysql->p_test); - var_dump($mysql->errno); + try { + $mysql->errno; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $mysql->connect($host, $user, $passwd, $db, $port, $socket); $mysql->select_db("nonexistingdb"); @@ -38,7 +42,5 @@ array(2) { [1]=> %s(3) "bar" } - -Warning: main(): Couldn't fetch my_mysql in %s on line %d -bool(false) +my_mysql object is already closed bool(true) diff --git a/ext/mysqli/tests/bug36420.phpt b/ext/mysqli/tests/bug36420.phpt index 6dd03b37f033b..619c41bd448f3 100644 --- a/ext/mysqli/tests/bug36420.phpt +++ b/ext/mysqli/tests/bug36420.phpt @@ -14,15 +14,22 @@ $mysqli = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $result = $mysqli->query('select 1'); $result->close(); -echo $result->num_rows; +try { + $result->num_rows; +} catch (Error $exception) { + echo $exception->getMessage() . "\n"; +} $mysqli->close(); -echo $result->num_rows; +try { + $result->num_rows; +} catch (Error $exception) { + echo $exception->getMessage() . "\n"; +} echo "Done\n"; ?> --EXPECTF-- -Warning: main(): Couldn't fetch mysqli_result in %s on line %d - -Warning: main(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed +mysqli_result object is already closed Done diff --git a/ext/mysqli/tests/bug36802.phpt b/ext/mysqli/tests/bug36802.phpt index 65e6d9a8ce9f0..387d73338ea04 100644 --- a/ext/mysqli/tests/bug36802.phpt +++ b/ext/mysqli/tests/bug36802.phpt @@ -15,27 +15,35 @@ Bug #36802 (crashes with with mysqli_set_charset()) /* following operations should not work */ if (method_exists($mysql, 'set_charset')) { - $x[0] = @$mysql->set_charset('utf8'); + try { + $mysql->set_charset('utf8'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } else { $x[0] = false; } - $x[1] = @$mysql->query("SELECT 'foo' FROM DUAL"); + + try { + $mysql->query("SELECT 'foo' FROM DUAL"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } /* following operations should work */ - $x[2] = ($mysql->client_version > 0); - $x[3] = $mysql->errno; + $x[1] = ($mysql->client_version > 0); + $x[2] = $mysql->errno; + $mysql->close(); var_dump($x); ?> --EXPECT-- -array(4) { - [0]=> - bool(false) +mysqli object is not fully initialized +mysqli object is not fully initialized +array(2) { [1]=> - bool(false) - [2]=> bool(true) - [3]=> + [2]=> int(0) } diff --git a/ext/mysqli/tests/bug63398.phpt b/ext/mysqli/tests/bug63398.phpt index b6e6c2549dc5f..278c5c4a96ee8 100644 --- a/ext/mysqli/tests/bug63398.phpt +++ b/ext/mysqli/tests/bug63398.phpt @@ -19,18 +19,14 @@ mysqli_close($link); $read = $error = $reject = array(); $read[] = $error[] = $reject[] = $link; -mysqli_poll($read, $error, $reject, 1); +try { + mysqli_poll($read, $error, $reject, 1); +} catch (Error $exception) { + echo $exception->getMessage() . "\n"; +} echo "okey"; ?> --EXPECTF-- -Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d - -Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d - -Warning: mysqli_poll(): No stream arrays were passed in %sbug63398.php on line %d - -Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d - -Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d +mysqli object is already closed okey diff --git a/ext/mysqli/tests/bug73462.phpt b/ext/mysqli/tests/bug73462.phpt index 5fb978feb1395..f82115cf6c998 100644 --- a/ext/mysqli/tests/bug73462.phpt +++ b/ext/mysqli/tests/bug73462.phpt @@ -19,7 +19,11 @@ require_once('skipifconnectfailure.inc'); /* Failed connection to invalid host */ $mysql_2 = @new mysqli(' !!! invalid !!! ', $user, $passwd, $db); - @$mysql_2->close(); + try { + $mysql_2->close(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } /* Re-use persistent connection */ $mysql_3 = new mysqli('p:'.$host, $user, $passwd, $db); @@ -38,4 +42,5 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/bug75448.phpt b/ext/mysqli/tests/bug75448.phpt index d4b1b05f511d7..929b152769cdc 100644 --- a/ext/mysqli/tests/bug75448.phpt +++ b/ext/mysqli/tests/bug75448.phpt @@ -11,9 +11,11 @@ require_once('skipifconnectfailure.inc'); require_once 'connect.inc'; $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_close($link); -$stmt = mysqli_prepare($link, 'SELECT VERSION()'); -var_dump($stmt); -?> ---EXPECTF-- -Warning: mysqli_prepare(): Couldn't fetch mysqli in %s on line %d -bool(false) + +try { + mysqli_prepare($link, 'SELECT VERSION()'); +} catch (Error $exception) { + echo $exception->getMessage() . "\n"; +} +--EXPECT-- +mysqli object is already closed diff --git a/ext/mysqli/tests/mysqli_affected_rows.phpt b/ext/mysqli/tests/mysqli_affected_rows.phpt index 81a7f5b6deef8..c74d0bc0ca4cd 100644 --- a/ext/mysqli/tests/mysqli_affected_rows.phpt +++ b/ext/mysqli/tests/mysqli_affected_rows.phpt @@ -110,8 +110,11 @@ mysqli_affected_rows() mysqli_close($link); - if (false !== ($tmp = @mysqli_affected_rows($link))) - printf("[033] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_affected_rows($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -120,4 +123,5 @@ mysqli_affected_rows() require_once("clean_table.inc"); ?> --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_affected_rows_oo.phpt b/ext/mysqli/tests/mysqli_affected_rows_oo.phpt index 7a6a5be99654b..054971f6ee3ea 100644 --- a/ext/mysqli/tests/mysqli_affected_rows_oo.phpt +++ b/ext/mysqli/tests/mysqli_affected_rows_oo.phpt @@ -11,8 +11,11 @@ mysqli->affected_rows require_once("connect.inc"); $mysqli = new mysqli(); - if (false !== ($tmp = @$mysqli->affected_rows)) - printf("[000a] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $mysqli->affected_rows; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", @@ -101,8 +104,11 @@ mysqli->affected_rows $mysqli->close(); - if (false !== ($tmp = @$mysqli->affected_rows)) - printf("[026] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $mysqli->affected_rows; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -111,4 +117,6 @@ mysqli->affected_rows require_once("clean_table.inc"); ?> --EXPECT-- +Property access is not allowed yet +Property access is not allowed yet done! diff --git a/ext/mysqli/tests/mysqli_autocommit.phpt b/ext/mysqli/tests/mysqli_autocommit.phpt index 99bd7d29c5e17..908cb315c3f0f 100644 --- a/ext/mysqli/tests/mysqli_autocommit.phpt +++ b/ext/mysqli/tests/mysqli_autocommit.phpt @@ -122,14 +122,17 @@ mysqli_autocommit() mysqli_close($link); - if (false !== ($tmp = @mysqli_autocommit($link, false))) - printf("[033] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_autocommit($link, false); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> --CLEAN-- --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_autocommit_oo.phpt b/ext/mysqli/tests/mysqli_autocommit_oo.phpt index 93ab10e605d8a..cca7dab0b5a96 100644 --- a/ext/mysqli/tests/mysqli_autocommit_oo.phpt +++ b/ext/mysqli/tests/mysqli_autocommit_oo.phpt @@ -124,8 +124,11 @@ mysqli->autocommit() $mysqli->close(); - if (false !== ($tmp = @$mysqli->autocommit( false))) - printf("[030] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $mysqli->autocommit(false); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -134,4 +137,5 @@ mysqli->autocommit() require_once("clean_table.inc"); ?> --EXPECT-- +my_mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_change_user.phpt b/ext/mysqli/tests/mysqli_change_user.phpt index bf1515e6457b1..4ad928bb0f0e8 100644 --- a/ext/mysqli/tests/mysqli_change_user.phpt +++ b/ext/mysqli/tests/mysqli_change_user.phpt @@ -87,8 +87,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = @mysqli_change_user($link, $user, $passwd, $db))) - printf("[018] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_change_user($link, $user, $passwd, $db); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[019] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", @@ -127,4 +130,5 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_character_set_name.phpt b/ext/mysqli/tests/mysqli_character_set_name.phpt index 4e7153e5b060b..b50c8414b3644 100644 --- a/ext/mysqli/tests/mysqli_character_set_name.phpt +++ b/ext/mysqli/tests/mysqli_character_set_name.phpt @@ -50,10 +50,13 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = @mysqli_character_set_name($link))) - printf("[013] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_character_set_name($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_character_set_name_oo.phpt b/ext/mysqli/tests/mysqli_character_set_name_oo.phpt index 4b760ec5bb638..b29fb7fc2db3f 100644 --- a/ext/mysqli/tests/mysqli_character_set_name_oo.phpt +++ b/ext/mysqli/tests/mysqli_character_set_name_oo.phpt @@ -54,14 +54,20 @@ mysqli_chararcter_set_name(), mysql_client_encoding() [alias] $mysqli->close(); - if (false !== ($tmp = @$mysqli->character_set_name())) - printf("[013] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $mysqli->character_set_name(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } - /* Make sure that the function alias exists */ - if (false !== ($tmp = @$mysqli->character_set_name())) - printf("[014] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $mysqli->character_set_name(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> --EXPECT-- +my_mysqli object is already closed +my_mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt index b7f227a7c2a88..2d07ef155c7bc 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_properties_no_conn.phpt @@ -16,94 +16,188 @@ require_once('skipifconnectfailure.inc'); $variables = array_keys(get_class_vars(get_class($mysqli))); sort($variables); foreach ($variables as $k => $var) { - printf("%s = '%s'\n", $var, var_export(@$mysqli->$var, true)); + try { + printf("%s = '%s'\n", $var, var_export($mysqli->$var, true)); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } printf("\nObject variables:\n"); $variables = array_keys(get_object_vars($mysqli)); - foreach ($variables as $k => $var) { - printf("%s = '%s'\n", $var, var_export(@$mysqli->$var, true)); + foreach ($variables as $k => $var) { + try { + printf("%s = '%s'\n", $var, var_export($mysqli->$var, true)); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } printf("\nMagic, magic properties:\n"); + try { + mysqli_affected_rows($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->affected_rows; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->client_info; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + printf("mysqli->client_version = '%s'/%s\n", $mysqli->client_version, gettype($mysqli->client_version)); + + try { + mysqli_errno($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->errno; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_error($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->error; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_field_count($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->field_count; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_insert_id($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->insert_id; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_sqlstate($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->sqlstate; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_get_host_info($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->host_info; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_info($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->info; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_thread_id($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->thread_id; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_get_proto_info($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->protocol_version; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_get_server_info($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->server_info; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_get_server_version($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->server_version; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + mysqli_warning_count($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $mysqli->warning_count; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } - assert(@mysqli_affected_rows($mysqli) === @$mysqli->affected_rows); - printf("mysqli->affected_rows = '%s'/%s ('%s'/%s)\n", - @$mysqli->affected_rows, gettype(@$mysqli->affected_rows), - @mysqli_affected_rows($mysqli), gettype(@mysqli_affected_rows($mysqli))); - - assert(@mysqli_get_client_info() === @$mysqli->client_info); - printf("mysqli->client_info = '%s'/%s ('%s'/%s)\n", - @$mysqli->client_info, gettype(@$mysqli->client_info), - @mysqli_get_client_info(), gettype(@mysqli_get_client_info())); - - assert(@mysqli_get_client_version() === @$mysqli->client_version); - printf("mysqli->client_version = '%s'/%s ('%s'/%s)\n", - @$mysqli->client_version, gettype(@$mysqli->client_version), - @mysqli_get_client_version(), gettype(@mysqli_get_client_version())); - - assert(@mysqli_errno($mysqli) === @$mysqli->errno); - printf("mysqli->errno = '%s'/%s ('%s'/%s)\n", - @$mysqli->errno, gettype(@$mysqli->errno), - - @mysqli_errno($mysqli), gettype(@mysqli_errno($mysqli))); - - assert(@mysqli_error($mysqli) === @$mysqli->error); - printf("mysqli->error = '%s'/%s ('%s'/%s)\n", - @$mysqli->error, gettype(@$mysqli->error), - @mysqli_error($mysqli), gettype(@mysqli_error($mysqli))); - - assert(@mysqli_field_count($mysqli) === @$mysqli->field_count); - printf("mysqli->field_count = '%s'/%s ('%s'/%s)\n", - @$mysqli->field_count, gettype(@$mysqli->field_count), - @mysqli_field_count($mysqli), gettype(@mysqli_field_count($mysqli))); - - assert(@mysqli_insert_id($mysqli) === @$mysqli->insert_id); - printf("mysqli->insert_id = '%s'/%s ('%s'/%s)\n", - @$mysqli->insert_id, gettype(@$mysqli->insert_id), - @mysqli_insert_id($mysqli), gettype(@mysqli_insert_id($mysqli))); - - assert(@mysqli_sqlstate($mysqli) === @$mysqli->sqlstate); - printf("mysqli->sqlstate = '%s'/%s ('%s'/%s)\n", - @$mysqli->sqlstate, gettype(@$mysqli->sqlstate), - @mysqli_sqlstate($mysqli), gettype(@mysqli_sqlstate($mysqli))); - - assert(@mysqli_get_host_info($mysqli) === @$mysqli->host_info); - printf("mysqli->host_info = '%s'/%s ('%s'/%s)\n", - @$mysqli->host_info, gettype(@$mysqli->host_info), - @mysqli_get_host_info($mysqli), gettype(@mysqli_get_host_info($mysqli))); - - /* note that the data types are different */ - assert(@mysqli_info($mysqli) == @$mysqli->info); - printf("mysqli->info = '%s'/%s ('%s'/%s)\n", - @$mysqli->info, gettype(@$mysqli->info), - @mysqli_info($mysqli), gettype(@mysqli_info($mysqli))); - - assert(@mysqli_thread_id($mysqli) > @$mysqli->thread_id); - assert(gettype(@$mysqli->thread_id) == gettype(@mysqli_thread_id($mysqli))); - printf("mysqli->thread_id = '%s'/%s ('%s'/%s)\n", - @$mysqli->thread_id, gettype(@$mysqli->thread_id), - @mysqli_thread_id($mysqli), gettype(@mysqli_thread_id($mysqli))); - - assert(@mysqli_get_proto_info($mysqli) === @$mysqli->protocol_version); - printf("mysqli->protocol_version = '%s'/%s ('%s'/%s)\n", - @$mysqli->protocol_version, gettype(@$mysqli->protocol_version), - @mysqli_get_proto_info($mysqli), gettype(@mysqli_get_proto_info($mysqli))); - - assert(@mysqli_get_server_info($mysqli) === @$mysqli->server_info); - printf("mysqli->server_info = '%s'/%s ('%s'/%s)\n", - @$mysqli->server_info, gettype(@$mysqli->server_info), - @mysqli_get_server_info($mysqli), gettype(@mysqli_get_server_info($mysqli))); - - assert(@mysqli_get_server_version($mysqli) === @$mysqli->server_version); - printf("mysqli->server_version = '%s'/%s ('%s'/%s)\n", - @$mysqli->server_version, gettype(@$mysqli->server_version), - @mysqli_get_server_version($mysqli), gettype(@mysqli_get_server_version($mysqli))); - - assert(@mysqli_warning_count($mysqli) === @$mysqli->warning_count); - printf("mysqli->warning_count = '%s'/%s ('%s'/%s)\n", - @$mysqli->warning_count, gettype(@$mysqli->warning_count), - @mysqli_warning_count($mysqli), gettype(@mysqli_warning_count($mysqli))); printf("\nAccess to undefined properties:\n"); printf("mysqli->unknown = '%s'\n", @$mysqli->unknown); @@ -131,9 +225,13 @@ require_once('skipifconnectfailure.inc'); $mysqli = @new mysqli($host, $user, $passwd . "invalid", $db, $port, $socket); dump_properties($mysqli); - printf("With RS\n"); + printf("\nWith RS\n"); $mysqli = @new mysqli($host, $user, $passwd . "invalid", $db, $port, $socket); - $res = @$mysqli->query("SELECT * FROM test"); + try { + $mysqli->query("SELECT * FROM test"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } dump_properties($mysqli); print "done!"; @@ -144,65 +242,74 @@ require_once('skipifconnectfailure.inc'); Without RS Class variables: -affected_rows = 'false' -client_info = 'false' +Property access is not allowed yet +Property access is not allowed yet client_version = '%s' connect_errno = '%s' connect_error = ''%s' -errno = 'false' -error = 'false' -error_list = 'false' -field_count = 'false' -host_info = 'false' -info = 'false' -insert_id = 'false' -protocol_version = 'false' -server_info = 'false' -server_version = 'false' -sqlstate = 'false' -thread_id = 'false' -warning_count = 'false' +mysqli object is already closed +mysqli object is already closed +Property access is not allowed yet +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed Object variables: -affected_rows = 'false' -client_info = 'false' +Property access is not allowed yet +Property access is not allowed yet client_version = '%s' connect_errno = '%s' -connect_error = '%s' -errno = 'false' -error = 'false' -error_list = 'false' -field_count = 'false' -host_info = 'false' -info = 'false' -insert_id = 'false' -server_info = 'false' -server_version = 'false' -sqlstate = 'false' -protocol_version = 'false' -thread_id = 'false' -warning_count = 'false' +connect_error = ''%s' +mysqli object is already closed +mysqli object is already closed +Property access is not allowed yet +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed Magic, magic properties: -mysqli->affected_rows = ''/boolean (''/boolean) - -Warning: assert(): assert(@mysqli_get_client_info() === @$mysqli->client_info) failed in %s on line %d -mysqli->client_info = ''/boolean ('%s'/%s) -mysqli->client_version = '%s'/integer ('%s'/integer) -mysqli->errno = ''/boolean (''/boolean) -mysqli->error = ''/boolean (''/boolean) -mysqli->field_count = ''/boolean (''/boolean) -mysqli->insert_id = ''/boolean (''/boolean) -mysqli->sqlstate = ''/boolean (''/boolean) -mysqli->host_info = ''/boolean (''/boolean) -mysqli->info = ''/boolean (''/boolean) - -Warning: assert(): assert(@mysqli_thread_id($mysqli) > @$mysqli->thread_id) failed in %s on line %d -mysqli->thread_id = ''/boolean (''/boolean) -mysqli->protocol_version = ''/boolean (''/boolean) -mysqli->server_info = ''/boolean (''/boolean) -mysqli->server_version = ''/boolean (''/boolean) -mysqli->warning_count = ''/boolean (''/boolean) +mysqli object is already closed +Property access is not allowed yet +Property access is not allowed yet +mysqli->client_version = '80000'/integer +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed Access to undefined properties: mysqli->unknown = '' @@ -212,68 +319,79 @@ setting mysqli->unknown, @mysqli_unknown = 'friday' Access hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation): mysqli->connect_error = '%s'/%s) mysqli->connect_errno = '%s'/integer ('%s'/integer) + With RS +mysqli object is already closed Class variables: -affected_rows = 'false' -client_info = 'false' +Property access is not allowed yet +Property access is not allowed yet client_version = '%s' connect_errno = '%s' connect_error = '%s' -errno = 'false' -error = 'false' -error_list = 'false' -field_count = 'false' -host_info = 'false' -info = 'false' -insert_id = 'false' -protocol_version = 'false' -server_info = 'false' -server_version = 'false' -sqlstate = 'false' -thread_id = 'false' -warning_count = 'false' +mysqli object is already closed +mysqli object is already closed +Property access is not allowed yet +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed Object variables: -affected_rows = 'false' -client_info = 'false' +Property access is not allowed yet +Property access is not allowed yet client_version = '%s' connect_errno = '%s' connect_error = '%s' -errno = 'false' -error = 'false' -error_list = 'false' -field_count = 'false' -host_info = 'false' -info = 'false' -insert_id = 'false' -server_info = 'false' -server_version = 'false' -sqlstate = 'false' -protocol_version = 'false' -thread_id = 'false' -warning_count = 'false' +mysqli object is already closed +mysqli object is already closed +Property access is not allowed yet +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed Magic, magic properties: -mysqli->affected_rows = ''/boolean (''/boolean) - -Warning: assert(): assert(@mysqli_get_client_info() === @$mysqli->client_info) failed in %s on line %d -mysqli->client_info = ''/boolean ('%s'/%s) -mysqli->client_version = '%s'/integer ('%s'/integer) -mysqli->errno = ''/boolean (''/boolean) -mysqli->error = ''/boolean (''/boolean) -mysqli->field_count = ''/boolean (''/boolean) -mysqli->insert_id = ''/boolean (''/boolean) -mysqli->sqlstate = ''/boolean (''/boolean) -mysqli->host_info = ''/boolean (''/boolean) -mysqli->info = ''/boolean (''/boolean) - -Warning: assert(): assert(@mysqli_thread_id($mysqli) > @$mysqli->thread_id) failed in %s on line %d -mysqli->thread_id = ''/boolean (''/boolean) -mysqli->protocol_version = ''/boolean (''/boolean) -mysqli->server_info = ''/boolean (''/boolean) -mysqli->server_version = ''/boolean (''/boolean) -mysqli->warning_count = ''/boolean (''/boolean) +mysqli object is already closed +Property access is not allowed yet +Property access is not allowed yet +mysqli->client_version = '80000'/integer +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed +mysqli object is already closed Access to undefined properties: mysqli->unknown = '' diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt index b8ab4a4af535d..d16e35fb22b67 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt @@ -113,8 +113,11 @@ require_once('skipifconnectfailure.inc'); if (!is_object($res = new mysqli_result($link))) printf("[001] Expecting object/mysqli_result got %s/%s\n", gettye($res), $res); - if (null !== ($tmp = @$res->num_rows)) - printf("[002] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); + try { + $res->num_rows; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_query($link, "SELECT id FROM test ORDER BY id")) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -177,4 +180,5 @@ Access to undefined properties: mysqli_result->unknown = '' Constructor: +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt index 3e3301361dc9c..134529d35c6df 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_stmt_interface.phpt @@ -81,12 +81,21 @@ Interface of the class mysqli_stmt printf("\nMagic, magic properties:\n"); -assert(mysqli_stmt_affected_rows($stmt) === $stmt->affected_rows); -printf("stmt->affected_rows = '%s'\n", $stmt->affected_rows); +try { + mysqli_stmt_affected_rows($stmt); +} catch (Error $exception) { + echo $exception->getMessage() . "\n"; +} -if (!$stmt->prepare("INSERT INTO test(id, label) VALUES (100, 'z')") || -!$stmt->execute()) -printf("[001] [%d] %s\n", $stmt->errno, $stmt->error); +try { + $stmt->affected_rows; +} catch (Error $exception) { + echo $exception->getMessage() . "\n"; +} + +if (!$stmt->prepare("INSERT INTO test(id, label) VALUES (100, 'z')") || !$stmt->execute()) { + printf("[001] [%d] %s\n", $stmt->errno, $stmt->error); +} assert(mysqli_stmt_affected_rows($stmt) === $stmt->affected_rows); printf("stmt->affected_rows = '%s'\n", $stmt->affected_rows); @@ -157,14 +166,8 @@ sqlstate id Magic, magic properties: - -Warning: mysqli_stmt_affected_rows(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: main(): Property access is not allowed yet in %s on line %d - -Warning: main(): Property access is not allowed yet in %s on line %d -stmt->affected_rows = '' +mysqli_stmt object is not fully initialized +Property access is not allowed yet stmt->affected_rows = '1' stmt->errno = '0' stmt->error = '' diff --git a/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt b/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt index 3700431762ac9..a73ef8ad684f7 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt @@ -100,13 +100,9 @@ Warning: mysqli_warning::mysqli_warning() expects parameter 1 to be object, null Warning: Wrong parameter count for mysqli_warning::mysqli_warning() in %s on line %d -Warning: mysqli_warning::mysqli_warning(): Couldn't fetch mysqli in %s on line %d - -Warning: mysqli_warning::mysqli_warning(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_warning::mysqli_warning(): invalid object or resource mysqli_stmt - in %s on line %d +Warning: mysqli_warning::mysqli_warning(): mysqli object is already closed in %s on line %d +mysqli_stmt object is not fully initialized +mysqli_stmt object is not fully initialized Warning: mysqli_warning::mysqli_warning(): Invalid class argument in /home/nixnutz/php6_mysqlnd/ext/mysqli/tests/mysqli_class_mysqli_warning.php on line 19 diff --git a/ext/mysqli/tests/mysqli_close.phpt b/ext/mysqli/tests/mysqli_close.phpt index 0110847334c77..4532749624a97 100644 --- a/ext/mysqli/tests/mysqli_close.phpt +++ b/ext/mysqli/tests/mysqli_close.phpt @@ -18,10 +18,13 @@ require_once('skipifconnectfailure.inc'); if (true !== $tmp) printf("[005] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - if (false !== ($tmp = @mysqli_query($link, "SELECT 1"))) - printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_query($link, "SELECT 1"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_close_oo.phpt b/ext/mysqli/tests/mysqli_close_oo.phpt index be189ba232376..dc912925d9dc4 100644 --- a/ext/mysqli/tests/mysqli_close_oo.phpt +++ b/ext/mysqli/tests/mysqli_close_oo.phpt @@ -21,13 +21,21 @@ require_once('skipifconnectfailure.inc'); if (true !== $tmp) printf("[003] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - if (false !== ($tmp = @$mysqli->close())) - printf("[004] Expecting false got %s/%s\n", gettype($tmp), $tmp); + try { + $mysqli->close(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } - if (false !== ($tmp = @$mysqli->query("SELECT 1"))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $mysqli->query("SELECT 1"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> --EXPECT-- +my_mysqli object is already closed +my_mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_commit.phpt b/ext/mysqli/tests/mysqli_commit.phpt index c2b46a72941ae..9f1f969f4d593 100644 --- a/ext/mysqli/tests/mysqli_commit.phpt +++ b/ext/mysqli/tests/mysqli_commit.phpt @@ -52,8 +52,11 @@ if (!have_innodb($link)) mysqli_close($link); - if (false !== ($tmp = @mysqli_commit($link))) - printf("[014] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_commit($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -62,4 +65,5 @@ if (!have_innodb($link)) require_once("clean_table.inc"); ?> --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt index 46069fd425f1f..205fbc48ab277 100644 --- a/ext/mysqli/tests/mysqli_commit_oo.phpt +++ b/ext/mysqli/tests/mysqli_commit_oo.phpt @@ -21,9 +21,11 @@ if (!have_innodb($link)) $link = NULL; $mysqli = new mysqli(); - if (false !== ($tmp = @$mysqli->commit())) { - printf("[013] Expecting false got %s/%s\n", gettype($tmp), $tmp); - } + try { + $mysqli->commit(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", @@ -90,20 +92,24 @@ if (!have_innodb($link)) $mysqli->close(); - if (false !== ($tmp = @$mysqli->commit())) { - printf("[017] Expecting false, got %s/%s\n", gettype($tmp), $tmp); - } + try { + $mysqli->commit(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> --CLEAN-- --EXPECTF-- +mysqli object is not fully initialized + Warning: mysqli::commit(): Transaction name truncated. Must be only [0-9A-Za-z\-_=]+ in %s on line %d Warning: mysqli::commit(): Transaction name truncated. Must be only [0-9A-Za-z\-_=]+ in %s on line %d Warning: mysqli::commit(): Transaction name truncated. Must be only [0-9A-Za-z\-_=]+ in %s on line %d +my_mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_connect_oo.phpt b/ext/mysqli/tests/mysqli_connect_oo.phpt index 15520d42b5eea..4a675b587c90e 100644 --- a/ext/mysqli/tests/mysqli_connect_oo.phpt +++ b/ext/mysqli/tests/mysqli_connect_oo.phpt @@ -56,13 +56,14 @@ require_once('skipifconnectfailure.inc'); printf("[012] Failed to create mysqli object\n"); } else { // There shall be NO connection! Using new mysqli(void) shall not use defaults for a connection! - // We had long discussions on this and found that the ext/mysqli API as - // such is broken. As we can't fix it, we document how it has behaved from - // the first day on. And that's: no connection. - if (false !== ($tmp = @$mysqli->query('SELECT 1'))) { - printf("[013] There shall be no connection!\n"); - $mysqli->close(); - } + // We had long discussions on this and found that the ext/mysqli API as + // such is broken. As we can't fix it, we document how it has behaved from + // the first day on. And that's: no connection. + try { + $mysqli->query('SELECT 1'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } if ($IS_MYSQLND) { @@ -75,9 +76,10 @@ require_once('skipifconnectfailure.inc'); // We had long discussions on this and found that the ext/mysqli API as // such is broken. As we can't fix it, we document how it has behaved from // the first day on. And that's: no connection. - if (false !== ($tmp = @$mysqli->query('SELECT 1'))) { - printf("[011] There shall be no connection!\n"); - $mysqli->close(); + try { + $mysqli->query('SELECT 1'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; } } } @@ -148,6 +150,8 @@ require_once('skipifconnectfailure.inc'); ?> --EXPECTF-- Warning: mysqli::__construct(): (%s/%d): Access denied for user '%sunknown%s'@'%s' (using password: %s) in %s on line %d +mysqli object is not fully initialized +mysqli object is not fully initialized ... and now Exceptions Access denied for user '%s'@'%s' (using password: %s) done! diff --git a/ext/mysqli/tests/mysqli_data_seek.phpt b/ext/mysqli/tests/mysqli_data_seek.phpt index 0859ee61d5d2a..b97cf717fa3e5 100644 --- a/ext/mysqli/tests/mysqli_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_data_seek.phpt @@ -44,8 +44,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - if (false !== ($tmp = mysqli_data_seek($res, 1))) - printf("[013] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_data_seek($res, 1); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -57,6 +60,5 @@ require_once('skipifconnectfailure.inc'); ?> --EXPECTF-- Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d - -Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_data_seek_oo.phpt b/ext/mysqli/tests/mysqli_data_seek_oo.phpt index 2c4377d845889..0a2717b16079f 100644 --- a/ext/mysqli/tests/mysqli_data_seek_oo.phpt +++ b/ext/mysqli/tests/mysqli_data_seek_oo.phpt @@ -16,8 +16,12 @@ require_once('skipifconnectfailure.inc'); $host, $user, $db, $port, $socket); $res = new mysqli_result($mysqli); - if (false !== ($tmp = @$res->data_seek(0))) - printf("[002] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + try { + $res->data_seek(0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$res = $mysqli->query('SELECT * FROM test ORDER BY id LIMIT 4', MYSQLI_STORE_RESULT)) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -52,19 +56,22 @@ require_once('skipifconnectfailure.inc'); $res->free_result(); - if (false !== ($tmp = $res->data_seek(1))) - printf("[015] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $res->data_seek(1); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $mysqli->close(); print "done!"; -?> --CLEAN-- --EXPECTF-- -Warning: mysqli_result::data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +mysqli_result object is already closed -Warning: mysqli_result::data_seek(): Couldn't fetch mysqli_result in %s on line %d +Warning: mysqli_result::data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt index 268bd619cbf34..391940b12e7db 100644 --- a/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt +++ b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt @@ -43,5 +43,5 @@ if (!function_exists('mysqli_disable_reads_from_master')) { require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_disable_reads_from_master(): Couldn't fetch mysqli in %s on line %d +Warning: mysqli_disable_reads_from_master(): mysqli object is already closed in %s on line %d done! diff --git a/ext/mysqli/tests/mysqli_dump_debug_info.phpt b/ext/mysqli/tests/mysqli_dump_debug_info.phpt index d9c894dfff995..d7ef81b822ca1 100644 --- a/ext/mysqli/tests/mysqli_dump_debug_info.phpt +++ b/ext/mysqli/tests/mysqli_dump_debug_info.phpt @@ -23,13 +23,13 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_dump_debug_info($link))) - printf("[005] Expecting NULL, got %s/%s, [%d] %s\n", - gettype($tmp), $tmp, - mysqli_errno($link), mysqli_error($link)); + try { + mysqli_dump_debug_info($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> ---EXPECTF-- -Warning: mysqli_dump_debug_info(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt index 58eb63cb2b475..8fb07617b73e5 100644 --- a/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt +++ b/ext/mysqli/tests/mysqli_dump_debug_info_oo.phpt @@ -23,13 +23,14 @@ require_once('skipifconnectfailure.inc'); $mysqli->close(); - if (false !== ($tmp = $mysqli->dump_debug_info())) - printf("[004] Expecting false, got %s/%s, [%d] %s\n", - gettype($tmp), $tmp, - $mysqli->errno, $mysqli->error); + try { + $mysqli->dump_debug_info(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> ---EXPECTF-- -Warning: mysqli::dump_debug_info(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt index 17b4b37529ade..3399f843b19ab 100644 --- a/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt +++ b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt @@ -31,7 +31,11 @@ if (!function_exists('mysqli_enable_reads_from_master')) { if (!is_bool($tmp = mysqli_enable_reads_from_master($link))) printf("[004] Expecting boolean/[true|false] value, got %s/%s\n", gettype($tmp), $tmp); - mysqli_close($link); + try { + mysqli_close($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (NULL !== ($tmp = mysqli_enable_reads_from_master($link))) printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); @@ -39,5 +43,5 @@ if (!function_exists('mysqli_enable_reads_from_master')) { print "done!"; ?> --EXPECTF-- -Warning: mysqli_enable_reads_from_master(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_errno.phpt b/ext/mysqli/tests/mysqli_errno.phpt index f26a30e089dd7..04ab8a4a41260 100644 --- a/ext/mysqli/tests/mysqli_errno.phpt +++ b/ext/mysqli/tests/mysqli_errno.phpt @@ -30,14 +30,16 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_errno($link)); + try { + mysqli_errno($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> --EXPECTF-- int(0) int(%d) - -Warning: mysqli_errno(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_errno_oo.phpt b/ext/mysqli/tests/mysqli_errno_oo.phpt index f2fa2529a1b00..b548575d6dd3e 100644 --- a/ext/mysqli/tests/mysqli_errno_oo.phpt +++ b/ext/mysqli/tests/mysqli_errno_oo.phpt @@ -36,14 +36,16 @@ require_once('skipifconnectfailure.inc'); $mysqli->close(); - var_dump($mysqli->errno); + try { + $mysqli->errno; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> --EXPECTF-- int(0) int(%d) - -Warning: main(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_error.phpt b/ext/mysqli/tests/mysqli_error.phpt index 4154f45f1defe..b7f034f267000 100644 --- a/ext/mysqli/tests/mysqli_error.phpt +++ b/ext/mysqli/tests/mysqli_error.phpt @@ -30,11 +30,14 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_error($link)); + try { + mysqli_error($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> ---EXPECTF-- -Warning: mysqli_error(): Couldn't fetch mysqli in %s on line %d -bool(false) +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_error_oo.phpt b/ext/mysqli/tests/mysqli_error_oo.phpt index d05fd6f383d1c..3f3c673415856 100644 --- a/ext/mysqli/tests/mysqli_error_oo.phpt +++ b/ext/mysqli/tests/mysqli_error_oo.phpt @@ -36,11 +36,14 @@ require_once('skipifconnectfailure.inc'); $mysqli->close(); - var_dump($mysqli->error); + try { + $mysqli->error; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> ---EXPECTF-- -Warning: main(): Couldn't fetch mysqli in %s on line %d -bool(false) +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_error_unicode.phpt b/ext/mysqli/tests/mysqli_error_unicode.phpt index 81279318829b9..ce70c901e1de9 100644 --- a/ext/mysqli/tests/mysqli_error_unicode.phpt +++ b/ext/mysqli/tests/mysqli_error_unicode.phpt @@ -28,13 +28,14 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_error($link)); + try { + mysqli_error($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> --EXPECTF-- string(%d) "Table 'няма_такава_таблица' doesn't exist" - -Warning: mysqli_error(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_all.phpt b/ext/mysqli/tests/mysqli_fetch_all.phpt index 9f18499454fb9..7b8f50a57e772 100644 --- a/ext/mysqli/tests/mysqli_fetch_all.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all.phpt @@ -75,11 +75,8 @@ if (!function_exists('mysqli_fetch_all')) $illegal_mode = mt_rand(-10000, 10000); } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH))); // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes. - $tmp = mysqli_fetch_all($res, $illegal_mode); - if (false !== $tmp) - printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n", - gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + mysqli_fetch_all($res, $illegal_mode); mysqli_free_result($res); function func_mysqli_fetch_all($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) { @@ -287,8 +284,11 @@ if (!function_exists('mysqli_fetch_all')) mysqli_close($link); - if (false !== ($tmp = mysqli_fetch_array($res, MYSQLI_ASSOC))) - printf("[015] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_fetch_array($res, MYSQLI_ASSOC); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[016] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", @@ -309,7 +309,6 @@ if (!function_exists('mysqli_fetch_all')) var_dump($rows); } - print "done!"; ?> --CLEAN-- @@ -446,6 +445,5 @@ array(1) { } Warning: mysqli_fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d - -Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt index 9dac357ae1a23..63c32e32d476d 100644 --- a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt @@ -298,8 +298,11 @@ if (!function_exists('mysqli_fetch_all')) mysqli_close($link); - if (false !== ($tmp = $res->fetch_array(MYSQLI_ASSOC))) - printf("[015] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $res->fetch_array(MYSQLI_ASSOC); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -435,6 +438,5 @@ array(1) { } Warning: mysqli_result::fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d - -Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_array.phpt b/ext/mysqli/tests/mysqli_fetch_array.phpt index 775c6f20c4399..5e423aa2b90a1 100644 --- a/ext/mysqli/tests/mysqli_fetch_array.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array.phpt @@ -279,8 +279,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_fetch_array($res, MYSQLI_ASSOC))) - printf("[015] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_fetch_array($res, MYSQLI_ASSOC); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -361,6 +364,5 @@ array(11) { Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d Warning: mysqli_fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d - -Warning: mysqli_fetch_array(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt index b0e223496056d..b3e8dda9c4626 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt @@ -271,8 +271,11 @@ require_once('skipifconnectfailure.inc'); $mysqli->close(); - if (false !== ($tmp = $res->fetch_array(MYSQLI_ASSOC))) - printf("[015] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $res->fetch_array(MYSQLI_ASSOC); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -357,6 +360,5 @@ array(11) { Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d Warning: mysqli_result::fetch_array(): The result type should be either MYSQLI_NUM, MYSQLI_ASSOC or MYSQLI_BOTH in %s on line %d - -Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc.phpt b/ext/mysqli/tests/mysqli_fetch_assoc.phpt index 3097eb2bc44a4..8bc26fcdbd4b5 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc.phpt @@ -51,8 +51,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - if (false !== ($tmp = mysqli_fetch_assoc($res))) - printf("[008] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_fetch_assoc($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -62,7 +65,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- [005] array(2) { ["id"]=> @@ -105,6 +108,5 @@ array(15) { ["-02"]=> string(1) "f" } - -Warning: mysqli_fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt index db3457a4a0dd9..c1eef6eaf533f 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt @@ -15,9 +15,11 @@ require_once('skipifconnectfailure.inc'); // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test $mysqli = new mysqli(); - $res = @new mysqli_result($mysqli); - if (false !== ($tmp = @$res->fetch_assoc())) - printf("[001] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + new mysqli_result($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } require('table.inc'); if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) @@ -44,8 +46,11 @@ require_once('skipifconnectfailure.inc'); $res->free_result(); - if (false !== ($tmp = $res->fetch_assoc())) - printf("[008] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $res->fetch_assoc(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -55,7 +60,8 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- +mysqli object is not fully initialized [005] array(2) { ["id"]=> @@ -78,6 +84,5 @@ array(5) { ["e"]=> string(1) "1" } - -Warning: mysqli_result::fetch_assoc(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt index 5035cf70d2c2b..7cd3208bc5bcd 100644 --- a/ext/mysqli/tests/mysqli_fetch_field.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field.phpt @@ -50,8 +50,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); // Read http://bugs.php.net/bug.php?id=42344 on defaults! - if (false !== ($tmp = mysqli_fetch_field($res))) - printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_fetch_field($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -136,8 +139,7 @@ object(stdClass)#%d (13) { int(0) } bool(false) - -Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed array(1) { ["_default_test"]=> string(1) "2" diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt index 5acc3b75d4995..5bf15a951e0bc 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt @@ -22,8 +22,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - if (false !== ($tmp = mysqli_fetch_field_direct($res, 0))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_fetch_field_direct($res, 0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -66,6 +69,5 @@ object(stdClass)#%d (13) { Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d bool(false) - -Warning: mysqli_fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt index c1220c783257e..ea4ef9587ae30 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt @@ -11,7 +11,11 @@ require_once('skipifconnectfailure.inc'); require_once("connect.inc"); $mysqli = new mysqli(); - $res = @new mysqli_result($mysqli); + try { + new mysqli_result($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } require('table.inc'); @@ -29,8 +33,11 @@ require_once('skipifconnectfailure.inc'); $res->free_result(); - if (false !== ($tmp = $res->fetch_field_direct(0))) - printf("[007] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $res->fetch_field_direct(0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $mysqli->close(); print "done!"; @@ -40,6 +47,8 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- +mysqli object is not fully initialized + Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d bool(false) object(stdClass)#%d (13) { @@ -73,6 +82,5 @@ object(stdClass)#%d (13) { Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d bool(false) - -Warning: mysqli_result::fetch_field_direct(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt index 35fdbb050e5a2..12400a730d563 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt @@ -12,7 +12,12 @@ require_once('skipifconnectfailure.inc'); // Note: no SQL type tests, internally the same function gets used as for mysqli_fetch_array() which does a lot of SQL type test $mysqli = new mysqli(); - $res = @new mysqli_result($mysqli); + $res = false; + try { + new mysqli_result($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } require('table.inc'); if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) @@ -51,8 +56,11 @@ require_once('skipifconnectfailure.inc'); $res->free_result(); - if (false !== ($tmp = $res->fetch_field())) - printf("[007] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + $res->fetch_field(); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $mysqli->close(); print "done!"; @@ -62,6 +70,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- +mysqli object is not fully initialized object(stdClass)#%d (13) { ["name"]=> string(2) "ID" @@ -119,6 +128,5 @@ object(stdClass)#%d (13) { int(0) } bool(false) - -Warning: mysqli_result::fetch_field(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_fields.phpt b/ext/mysqli/tests/mysqli_fetch_fields.phpt index 6dee8108f9047..3c4eb086b2c89 100644 --- a/ext/mysqli/tests/mysqli_fetch_fields.phpt +++ b/ext/mysqli/tests/mysqli_fetch_fields.phpt @@ -47,8 +47,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - if (false !== ($tmp = mysqli_fetch_fields($res))) - printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_fetch_fields($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -114,6 +117,5 @@ object(stdClass)#%d (13) { ["decimals"]=> int(0) } - -Warning: mysqli_fetch_fields(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_lengths.phpt b/ext/mysqli/tests/mysqli_fetch_lengths.phpt index b407d91894ff5..1e4bf453e6556 100644 --- a/ext/mysqli/tests/mysqli_fetch_lengths.phpt +++ b/ext/mysqli/tests/mysqli_fetch_lengths.phpt @@ -27,7 +27,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - var_dump(mysqli_fetch_lengths($res)); + try { + mysqli_fetch_lengths($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -36,7 +40,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- bool(false) array(2) { [0]=> @@ -45,7 +49,5 @@ array(2) { int(1) } bool(false) - -Warning: mysqli_fetch_lengths(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt index c352bea8a0b52..2e8e2722ee263 100644 --- a/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt @@ -24,7 +24,11 @@ require_once('skipifconnectfailure.inc'); var_dump($res->lengths); $res->free_result(); - var_dump($res->lengths); + try { + $res->lengths; + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $mysqli->close(); print "done!"; ?> @@ -35,7 +39,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- NULL array(2) { [0]=> @@ -44,7 +48,5 @@ array(2) { int(1) } NULL - -Warning: main(): Property access is not allowed yet in %s on line %d -bool(false) +Property access is not allowed yet done! diff --git a/ext/mysqli/tests/mysqli_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt index 3230162ce77b4..9042815dfd781 100644 --- a/ext/mysqli/tests/mysqli_fetch_object.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object.phpt @@ -86,7 +86,11 @@ require_once('skipifconnectfailure.inc'); } mysqli_free_result($res); - var_dump(mysqli_fetch_object($res)); + try { + mysqli_fetch_object($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 5")) printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -140,8 +144,7 @@ Exception: Too few arguments to function mysqli_fetch_object_construct::__constr Exception: Too few arguments to function mysqli_fetch_object_construct::__construct(), 1 passed and exactly 2 expected NULL NULL -[E_WARNING] mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed [0] mysqli_fetch_object() expects parameter 3 to be array, string given in %s on line %d Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d diff --git a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt index a81cb7f80ac3c..54845843cf073 100644 --- a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt @@ -12,9 +12,11 @@ require_once('skipifconnectfailure.inc'); set_error_handler('handle_catchable_fatal'); $mysqli = new mysqli(); - $res = @new mysqli_result($mysqli); - if (false !== ($tmp = @$res->fetch_object())) - printf("[001] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + new mysqli_result($mysqli); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } require('table.inc'); if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) @@ -110,7 +112,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - var_dump(mysqli_fetch_object($res)); + try { + mysqli_fetch_object($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } // Fatal error, script execution will end var_dump($res->fetch_object('this_class_does_not_exist')); @@ -123,16 +129,13 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -[E_WARNING] mysqli_result::__construct(): invalid object or resource mysqli - in %s on line %d -[E_WARNING] mysqli_result::fetch_object(): Couldn't fetch mysqli_result in %s on line %d +mysqli object is not fully initialized [0] mysqli_result::fetch_object() expects parameter 1 to be string, object given in %s on line %d [0] mysqli_result::fetch_object() expects at most 2 parameters, 3 given in %s on line %d [0] mysqli_result::fetch_object() expects parameter 2 to be array, null given in %s on line %d Exception: Too few arguments to function mysqli_fetch_object_construct::__construct(), 1 passed and exactly 2 expected NULL NULL -[E_WARNING] mysqli_fetch_object(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d diff --git a/ext/mysqli/tests/mysqli_fetch_row.phpt b/ext/mysqli/tests/mysqli_fetch_row.phpt index c16ca1da77684..d2ddea6c1a1f7 100644 --- a/ext/mysqli/tests/mysqli_fetch_row.phpt +++ b/ext/mysqli/tests/mysqli_fetch_row.phpt @@ -23,7 +23,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - var_dump(mysqli_fetch_row($res)); + try { + mysqli_fetch_row($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -32,7 +36,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- [004] array(3) { [0]=> @@ -44,7 +48,5 @@ array(3) { } [005] NULL - -Warning: mysqli_fetch_row(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_field_count.phpt b/ext/mysqli/tests/mysqli_field_count.phpt index 18fc3c9ec1e46..d6a7be5fcc433 100644 --- a/ext/mysqli/tests/mysqli_field_count.phpt +++ b/ext/mysqli/tests/mysqli_field_count.phpt @@ -34,21 +34,22 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_field_count($link)); + try { + mysqli_field_count($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; -?> --CLEAN-- ---EXPECTF-- +--EXPECT-- int(0) int(2) int(0) int(0) int(3) - -Warning: mysqli_field_count(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt index 3cd60c7ce9db0..91c4360483296 100644 --- a/ext/mysqli/tests/mysqli_field_seek.phpt +++ b/ext/mysqli/tests/mysqli_field_seek.phpt @@ -101,7 +101,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - var_dump(mysqli_field_seek($res, 0)); + try { + mysqli_field_seek($res, 0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -233,7 +237,5 @@ object(stdClass)#%d (13) { ["decimals"]=> int(0) } - -Warning: mysqli_field_seek(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_field_tell.phpt b/ext/mysqli/tests/mysqli_field_tell.phpt index 0b1d3bd0c1da4..a39e1ff814b69 100644 --- a/ext/mysqli/tests/mysqli_field_tell.phpt +++ b/ext/mysqli/tests/mysqli_field_tell.phpt @@ -34,7 +34,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - var_dump(mysqli_field_tell($res)); + try { + mysqli_field_tell($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -87,7 +91,5 @@ bool(false) int(1) bool(true) int(0) - -Warning: mysqli_field_tell(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_free_result.phpt b/ext/mysqli/tests/mysqli_free_result.phpt index be377a88175d2..c64ec918cc39d 100644 --- a/ext/mysqli/tests/mysqli_free_result.phpt +++ b/ext/mysqli/tests/mysqli_free_result.phpt @@ -16,18 +16,25 @@ require_once('skipifconnectfailure.inc'); } print "a\n"; - var_dump(mysqli_free_result($res)); + var_dump(mysqli_free_result($res)); + print "b\n"; - var_dump(mysqli_free_result($res)); + try { + mysqli_free_result($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) { + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } - if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) { - printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - } print "c\n"; var_dump(mysqli_store_result($link)); var_dump(mysqli_error($link)); print "[005]\n"; - var_dump(mysqli_free_result($res)); + + mysqli_free_result($res); if (!$res = mysqli_query($link, "SELECT id FROM test ORDER BY id LIMIT 1")) { printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -49,14 +56,11 @@ require_once('skipifconnectfailure.inc'); a NULL b - -Warning: mysqli_free_result(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed c bool(false) string(0) "" [005] -NULL d bool(false) string(0) "" diff --git a/ext/mysqli/tests/mysqli_get_charset.phpt b/ext/mysqli/tests/mysqli_get_charset.phpt index cd7cfb3ae400a..80d0300c2b096 100644 --- a/ext/mysqli/tests/mysqli_get_charset.phpt +++ b/ext/mysqli/tests/mysqli_get_charset.phpt @@ -89,8 +89,11 @@ if (!function_exists('mysqli_get_charset')) mysqli_close($link); - if (false !== ($tmp = mysqli_get_charset($link))) - printf("[023] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_get_charset($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -98,6 +101,6 @@ if (!function_exists('mysqli_get_charset')) ---EXPECTF-- -Warning: mysqli_get_charset(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_insert_id.phpt b/ext/mysqli/tests/mysqli_insert_id.phpt index 383ed087b74a8..ba93ba41cadd4 100644 --- a/ext/mysqli/tests/mysqli_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_insert_id.phpt @@ -117,7 +117,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_insert_id($link)); + try { + mysqli_insert_id($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -125,7 +129,6 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_insert_id(): Couldn't fetch mysqli in %s on line %d -bool(false) +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_more_results.phpt b/ext/mysqli/tests/mysqli_more_results.phpt index b9a971c24eb98..5a967c0776294 100644 --- a/ext/mysqli/tests/mysqli_more_results.phpt +++ b/ext/mysqli/tests/mysqli_more_results.phpt @@ -50,7 +50,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_more_results($link)); + try { + mysqli_more_results($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -67,7 +71,5 @@ bool(false) [010] 1 2 - -Warning: mysqli_more_results(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_multi_query.phpt b/ext/mysqli/tests/mysqli_multi_query.phpt index 57235c2b17f09..10f1a62202783 100644 --- a/ext/mysqli/tests/mysqli_multi_query.phpt +++ b/ext/mysqli/tests/mysqli_multi_query.phpt @@ -102,7 +102,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_multi_query($link, "SELECT id, label FROM test")); + try { + mysqli_multi_query($link, "SELECT id, label FROM test"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -115,7 +119,5 @@ require_once('skipifconnectfailure.inc'); [008] 0 [009] [2014] Commands out of sync; you can't run this command now [010] 7 - -Warning: mysqli_multi_query(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_next_result.phpt b/ext/mysqli/tests/mysqli_next_result.phpt index b37d9949fa92e..36ab5959dce06 100644 --- a/ext/mysqli/tests/mysqli_next_result.phpt +++ b/ext/mysqli/tests/mysqli_next_result.phpt @@ -55,7 +55,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_next_result($link)); + try { + mysqli_next_result($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -64,7 +68,5 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- - -Warning: mysqli_next_result(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_num_fields.phpt b/ext/mysqli/tests/mysqli_num_fields.phpt index 1f33b4d2d9fec..610d311db65ee 100644 --- a/ext/mysqli/tests/mysqli_num_fields.phpt +++ b/ext/mysqli/tests/mysqli_num_fields.phpt @@ -26,8 +26,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - if ($test_free && (false !== ($tmp = mysqli_num_fields($res)))) - printf("[%03d] Expecting false, got %s/%s\n", $offset + 2, gettype($tmp), $tmp); + try { + mysqli_num_fields($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } func_test_mysqli_num_fields($link, "SELECT 1 AS a", 1, 5); @@ -43,6 +46,9 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_num_fields(): Couldn't fetch mysqli_result in %s on line %d +--EXPECT-- +mysqli_result object is already closed +mysqli_result object is already closed +mysqli_result object is already closed +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_num_rows.phpt b/ext/mysqli/tests/mysqli_num_rows.phpt index 15d3f90257cb7..f378bdd57e27b 100644 --- a/ext/mysqli/tests/mysqli_num_rows.phpt +++ b/ext/mysqli/tests/mysqli_num_rows.phpt @@ -27,8 +27,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - if ($test_free && (false !== ($tmp = mysqli_num_rows($res)))) - printf("[%03d] Expecting false, got %s/%s\n", $offset + 2, gettype($tmp), $tmp); + try { + mysqli_num_rows($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } } @@ -57,7 +60,6 @@ require_once('skipifconnectfailure.inc'); printf("[031] Expecting int/0, got %s/%d\n", gettype($tmp), $tmp); mysqli_free_result($res); - } else { printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } @@ -70,7 +72,10 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_num_rows(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed +mysqli_result object is already closed +mysqli_result object is already closed +mysqli_result object is already closed run_tests.php don't fool me with your 'ungreedy' expression '.+?'! Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d diff --git a/ext/mysqli/tests/mysqli_options.phpt b/ext/mysqli/tests/mysqli_options.phpt index 7b920b4f4ce05..9894cf5a292ae 100644 --- a/ext/mysqli/tests/mysqli_options.phpt +++ b/ext/mysqli/tests/mysqli_options.phpt @@ -88,8 +88,13 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - echo "Link closed"; - var_dump("MYSQLI_INIT_COMMAND", mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=1')); + echo "Link closed\n"; + try { + mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=1'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + print "done!"; ?> --EXPECTF-- @@ -118,7 +123,5 @@ bool(true) %s(17) "MYSQLI_CLIENT_SSL" bool(false) Link closed -Warning: mysqli_options(): Couldn't fetch mysqli in %s line %d -%s(19) "MYSQLI_INIT_COMMAND" -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_pconn_kill.phpt b/ext/mysqli/tests/mysqli_pconn_kill.phpt index f4be4c7c7bc56..d6fba4d8e3e54 100644 --- a/ext/mysqli/tests/mysqli_pconn_kill.phpt +++ b/ext/mysqli/tests/mysqli_pconn_kill.phpt @@ -62,7 +62,11 @@ mysqli.max_persistent=2 printf("[009] Thread of the regular connection should be still there, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // On PHP side this should do nothing. PHP should not try to close the connection or something. - @mysqli_close($plink); + try { + mysqli_close($plink); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$plink = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[011] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", @@ -92,4 +96,5 @@ mysqli.max_persistent=2 require_once("clean_table.inc"); ?> --EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_ping.phpt b/ext/mysqli/tests/mysqli_ping.phpt index 93deeebfa32d6..aec065c3dee91 100644 --- a/ext/mysqli/tests/mysqli_ping.phpt +++ b/ext/mysqli/tests/mysqli_ping.phpt @@ -25,14 +25,16 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_ping($link))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_ping($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> ---EXPECTF-- +--EXPECT-- bool(true) bool(true) - -Warning: mysqli_ping(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_query.phpt b/ext/mysqli/tests/mysqli_query.phpt index a9502a83e4966..be2f6f75a3459 100644 --- a/ext/mysqli/tests/mysqli_query.phpt +++ b/ext/mysqli/tests/mysqli_query.phpt @@ -90,8 +90,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_query($link, "SELECT id FROM test"))) - printf("[011] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_query($link, "SELECT id FROM test"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -109,7 +112,7 @@ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) mysqli_close($link); ?> ---EXPECTF-- +--EXPECT-- array(1) { ["valid"]=> string(30) "this is sql but with semicolon" @@ -119,6 +122,5 @@ array(1) { string(1) "a" } string(1) "a" - -Warning: mysqli_query(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_query_iterators.phpt b/ext/mysqli/tests/mysqli_query_iterators.phpt index 81ca8c0faeccd..e653291a1bd59 100644 --- a/ext/mysqli/tests/mysqli_query_iterators.phpt +++ b/ext/mysqli/tests/mysqli_query_iterators.phpt @@ -23,13 +23,18 @@ require_once('skipifconnectfailure.inc'); var_dump($row); } echo "======\n"; + foreach ($res as $row) { var_dump($row); } mysqli_free_result($res); - foreach ($res as $row) { - var_dump($row); - } + try { + foreach ($res as $row) { + $row; + } + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } echo "--- Testing USE_RESULT ---\n"; if (!is_object($res = mysqli_query($link, "SELECT id FROM test ORDER BY id", MYSQLI_USE_RESULT))) @@ -118,8 +123,7 @@ array(1) { ["id"]=> string(1) "6" } - -Warning: main(): Couldn't fetch mysqli_result in %s on line %d +mysqli_result object is already closed --- Testing USE_RESULT --- array(1) { ["id"]=> diff --git a/ext/mysqli/tests/mysqli_query_unicode.phpt b/ext/mysqli/tests/mysqli_query_unicode.phpt index f167b4373ad36..53fba7e5a9e32 100644 --- a/ext/mysqli/tests/mysqli_query_unicode.phpt +++ b/ext/mysqli/tests/mysqli_query_unicode.phpt @@ -75,8 +75,11 @@ mysqli_close($link); mysqli_close($link); - if (false !== ($tmp = mysqli_query($link, "SELECT id FROM test"))) - printf("[014] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_query($link, "SELECT id FROM test"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -85,6 +88,5 @@ array(1) { ["правилен"]=> string(%d) "това ескюел, но с точка и запетая" } - -Warning: mysqli_query(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_real_connect.phpt b/ext/mysqli/tests/mysqli_real_connect.phpt index b8ecde90ab2e1..6844db4f1fda1 100644 --- a/ext/mysqli/tests/mysqli_real_connect.phpt +++ b/ext/mysqli/tests/mysqli_real_connect.phpt @@ -140,8 +140,11 @@ mysqli.allow_local_infile=1 @mysqli_close($link); } - if (false !== ($tmp = mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) - printf("[026] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -159,6 +162,5 @@ object(mysqli)#%d (%d) { ["connect_error"]=> NULL } - -Warning: mysqli_real_connect(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string.phpt b/ext/mysqli/tests/mysqli_real_escape_string.phpt index 57ab99eb89b31..9658bfc52d98a 100644 --- a/ext/mysqli/tests/mysqli_real_escape_string.phpt +++ b/ext/mysqli/tests/mysqli_real_escape_string.phpt @@ -32,11 +32,14 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_real_escape_string($link, 'foo'))) - printf("[010] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_real_escape_string($link, 'foo'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> ---EXPECTF-- -Warning: mysqli_real_escape_string(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_real_escape_string_unicode.phpt b/ext/mysqli/tests/mysqli_real_escape_string_unicode.phpt index 3db0ecce62ec5..d27c09359c37a 100644 --- a/ext/mysqli/tests/mysqli_real_escape_string_unicode.phpt +++ b/ext/mysqli/tests/mysqli_real_escape_string_unicode.phpt @@ -62,8 +62,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_real_escape_string($link, 'foo'))) - printf("[018] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_real_escape_string($link, 'foo'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -71,6 +74,6 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_real_escape_string(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_real_query.phpt b/ext/mysqli/tests/mysqli_real_query.phpt index 4515810310795..5528ca63aa267 100644 --- a/ext/mysqli/tests/mysqli_real_query.phpt +++ b/ext/mysqli/tests/mysqli_real_query.phpt @@ -72,8 +72,11 @@ ver_param;')) { mysqli_close($link); - if (false !== ($tmp = mysqli_real_query($link, "SELECT id FROM test"))) - printf("[011] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_real_query($link, "SELECT id FROM test"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -91,11 +94,10 @@ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) mysqli_close($link); ?> ---EXPECTF-- +--EXPECT-- array(1) { ["valid"]=> string(30) "this is sql but with semicolon" } - -Warning: mysqli_real_query(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_result_references.phpt b/ext/mysqli/tests/mysqli_result_references.phpt index d4fe48816a511..738c2b27355ad 100644 --- a/ext/mysqli/tests/mysqli_result_references.phpt +++ b/ext/mysqli/tests/mysqli_result_references.phpt @@ -59,6 +59,7 @@ require_once('skipifconnectfailure.inc'); $references[$idx++] = &$res; mysqli_free_result($res); + debug_zval_dump($references); if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 1")) || diff --git a/ext/mysqli/tests/mysqli_rollback.phpt b/ext/mysqli/tests/mysqli_rollback.phpt index e46ffbc296cb1..be5ac7870a981 100644 --- a/ext/mysqli/tests/mysqli_rollback.phpt +++ b/ext/mysqli/tests/mysqli_rollback.phpt @@ -49,8 +49,11 @@ mysqli_rollback() mysqli_close($link); - if (false !== ($tmp = mysqli_rollback($link))) - printf("[014] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_rollback($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!\n"; ?> @@ -58,6 +61,6 @@ mysqli_rollback() ---EXPECTF-- -Warning: mysqli_rollback(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_select_db.phpt b/ext/mysqli/tests/mysqli_select_db.phpt index e023866c1708e..a3d165bd02b37 100644 --- a/ext/mysqli/tests/mysqli_select_db.phpt +++ b/ext/mysqli/tests/mysqli_select_db.phpt @@ -88,13 +88,16 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_select_db($link, $db))) - printf("[019] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_select_db($link, $db); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!\n"; ?> --CLEAN-- ---EXPECTF-- -Warning: mysqli_select_db(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_send_query.phpt b/ext/mysqli/tests/mysqli_send_query.phpt index d07985c2b7ea2..5cdb0a6b77a9c 100644 --- a/ext/mysqli/tests/mysqli_send_query.phpt +++ b/ext/mysqli/tests/mysqli_send_query.phpt @@ -40,11 +40,13 @@ if (!$TEST_EXPERIMENTAL) mysqli_close($link); - if (NULL !== ($tmp = mysqli_send_query($link, 'SELECT 1'))) - printf("[006] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - + try { + mysqli_send_query($link, 'SELECT 1'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> --EXPECTF-- -Warning: mysqli_send_query(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index 33ebb8347b797..092e17b36cf73 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -104,8 +104,11 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR mysqli_close($link); - if (false !== ($tmp = mysqli_set_charset($link, $new_charset))) - printf("[019] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_set_charset($link, $new_charset); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -113,6 +116,6 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR ---EXPECTF-- -Warning: mysqli_set_charset(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_set_opt.phpt b/ext/mysqli/tests/mysqli_set_opt.phpt index 6769d2c53051d..b368654e598f6 100644 --- a/ext/mysqli/tests/mysqli_set_opt.phpt +++ b/ext/mysqli/tests/mysqli_set_opt.phpt @@ -28,11 +28,15 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=1')); + try { + mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=1'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> ---EXPECTF-- +--EXPECT-- bool(true) bool(true) bool(true) @@ -45,7 +49,5 @@ bool(true) bool(true) bool(true) bool(false) - -Warning: mysqli_set_opt(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_sqlstate.phpt b/ext/mysqli/tests/mysqli_sqlstate.phpt index 55dd115403ea7..1d63e71da2a17 100644 --- a/ext/mysqli/tests/mysqli_sqlstate.phpt +++ b/ext/mysqli/tests/mysqli_sqlstate.phpt @@ -20,7 +20,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_sqlstate($link)); + try { + mysqli_sqlstate($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -32,7 +36,5 @@ require_once('skipifconnectfailure.inc'); %s(5) "00000" %s(5) "42S22" %s(5) "00000" - -Warning: mysqli_sqlstate(): Couldn't fetch mysqli in %s on line %d -bool(false) +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stat.phpt b/ext/mysqli/tests/mysqli_stat.phpt index 71f7af5a5483b..6369a366b3f07 100644 --- a/ext/mysqli/tests/mysqli_stat.phpt +++ b/ext/mysqli/tests/mysqli_stat.phpt @@ -18,11 +18,14 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_stat($link))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stat($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> ---EXPECTF-- -Warning: mysqli_stat(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt b/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt index cfe5d535168c2..2ba36389fde89 100644 --- a/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt +++ b/ext/mysqli/tests/mysqli_stmt_affected_rows.phpt @@ -225,8 +225,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_affected_rows($stmt))) - printf("[047] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_affected_rows($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -238,6 +241,5 @@ require_once('skipifconnectfailure.inc'); ?> --EXPECTF-- [009] [%d] (error message varies with the MySQL Server version, check the error code) - -Warning: mysqli_stmt_affected_rows(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt index f3634a76219b6..60920c246016c 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -25,8 +25,12 @@ require_once('skipifconnectfailure.inc'); $stmt = mysqli_stmt_init($link); mysqli_stmt_prepare($stmt, 'SELECT * FROM test'); - if (false !== ($tmp = @mysqli_stmt_attr_get($stmt, $invalid_attr))) - printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + + try { + mysqli_stmt_attr_get($stmt, $invalid_attr); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } foreach ($valid_attr as $k => $attr) { if (false === ($tmp = mysqli_stmt_attr_get($stmt, $attr))) { @@ -38,10 +42,11 @@ require_once('skipifconnectfailure.inc'); $stmt->close(); foreach ($valid_attr as $k => $attr) { - if (false !== ($tmp = @mysqli_stmt_attr_get($stmt, $attr))) { - printf("[007] Expecting false, got %s/%s for attribute %s/%s\n", - gettype($tmp), $tmp, $k, $attr); - } + try { + mysqli_stmt_attr_get($stmt, $attr); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } } mysqli_close($link); @@ -52,4 +57,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECT-- +mysqli_stmt object is already closed +mysqli_stmt object is already closed +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index 6e5710a0fc641..d87b28e460a40 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -26,8 +26,11 @@ require_once("connect.inc"); $stmt = mysqli_stmt_init($link); - if (false !== ($tmp = @mysqli_stmt_attr_set($stmt, 0, 0))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_attr_set($stmt, 0, 0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } $stmt->prepare("SELECT * FROM test"); @@ -259,4 +262,5 @@ require_once("connect.inc"); require_once("clean_table.inc"); ?> --EXPECT-- +mysqli_stmt object is not fully initialized done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt index c166d91c48c13..40b5baf4ef41c 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -22,8 +22,11 @@ require_once('skipifconnectfailure.inc'); $label = null; $foo = null; - if (false !== ($tmp = mysqli_stmt_bind_result($stmt, $id))) - printf("[003] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_bind_result($stmt, $id); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -300,8 +303,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_bind_result(): invalid object or resource mysqli_stmt - in %s on line %d +mysqli_stmt object is not fully initialized Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_close.phpt b/ext/mysqli/tests/mysqli_stmt_close.phpt index dfeab7075d383..978e4388bb6e0 100644 --- a/ext/mysqli/tests/mysqli_stmt_close.phpt +++ b/ext/mysqli/tests/mysqli_stmt_close.phpt @@ -16,8 +16,11 @@ require_once('skipifconnectfailure.inc'); printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // Yes, amazing, eh? AFAIK a work around of a constructor bug... - if (false !== ($tmp = mysqli_stmt_close($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_close($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -25,8 +28,11 @@ require_once('skipifconnectfailure.inc'); if (true !== ($tmp = mysqli_stmt_close($stmt))) printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - if (false !== ($tmp = mysqli_stmt_close($stmt))) - printf("[007] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_close($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!$stmt = mysqli_stmt_init($link)) printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -74,9 +80,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_close(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_close(): Couldn't fetch mysqli_stmt in %s on line %d +--EXPECT-- +mysqli_stmt object is not fully initialized +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt index 23ecea0be32ed..6658f6e855345 100644 --- a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -15,8 +15,11 @@ require_once('skipifconnectfailure.inc'); if (!$stmt = mysqli_stmt_init($link)) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_data_seek($stmt, 1))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_data_seek($stmt, 1); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -66,8 +69,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_data_seek($stmt, 0))) - printf("[017] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_data_seek($stmt, 0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -77,14 +83,12 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_data_seek(): invalid object or resource mysqli_stmt - in %s on line %d +mysqli_stmt object is not fully initialized int(3) int(1) int(1) Warning: mysqli_stmt_data_seek(): Offset must be positive in %s on line %d int(1) - -Warning: mysqli_stmt_data_seek(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_errno.phpt b/ext/mysqli/tests/mysqli_stmt_errno.phpt index 7b20ea65c6783..79b3ae171dd43 100644 --- a/ext/mysqli/tests/mysqli_stmt_errno.phpt +++ b/ext/mysqli/tests/mysqli_stmt_errno.phpt @@ -44,8 +44,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_errno($stmt))) - printf("[011] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_errno($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -54,6 +57,6 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_errno(): Couldn't fetch mysqli_stmt in %s on line %d +--EXPECT-- +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_error.phpt b/ext/mysqli/tests/mysqli_stmt_error.phpt index 2b7b59a21a5ce..a0c14972478e8 100644 --- a/ext/mysqli/tests/mysqli_stmt_error.phpt +++ b/ext/mysqli/tests/mysqli_stmt_error.phpt @@ -44,8 +44,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_error($stmt))) - printf("[011] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_error($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -54,6 +57,6 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_error(): Couldn't fetch mysqli_stmt in %s on line %d +--EXPECT-- +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_execute.phpt b/ext/mysqli/tests/mysqli_stmt_execute.phpt index fd0fd3c628c25..7a3be215c5fac 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute.phpt @@ -22,15 +22,21 @@ if (mysqli_get_server_version($link) <= 40100) { printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // stmt object status test - if (false !== ($tmp = mysqli_stmt_execute($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_execute($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (mysqli_stmt_prepare($stmt, "SELECT i_do_not_exist_believe_me FROM test ORDER BY id")) printf("[005] Statement should have failed!\n"); // stmt object status test - if (false !== ($tmp = mysqli_stmt_execute($stmt))) - printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_execute($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test ORDER BY id LIMIT 1")) printf("[007] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -117,8 +123,11 @@ if (mysqli_get_server_version($link) <= 40100) { mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_execute($stmt))) - printf("[028] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_execute($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -127,15 +136,11 @@ if (mysqli_get_server_version($link) <= 40100) { ---EXPECTF-- -Warning: mysqli_stmt_execute(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_execute(): invalid object or resource mysqli_stmt - in %s on line %d +--EXPECT-- +mysqli_stmt object is not fully initialized +mysqli_stmt object is not fully initialized bool(true) bool(true) [027] Expecting boolean/false, got boolean/1 - -Warning: mysqli_stmt_execute(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_fetch.phpt b/ext/mysqli/tests/mysqli_stmt_fetch.phpt index 25a1f52eb1046..6f8a3ad725a58 100644 --- a/ext/mysqli/tests/mysqli_stmt_fetch.phpt +++ b/ext/mysqli/tests/mysqli_stmt_fetch.phpt @@ -21,8 +21,11 @@ require_once('skipifconnectfailure.inc'); printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // stmt object status test - if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_fetch($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -64,8 +67,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[016] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_fetch($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -76,9 +82,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt - in %s on line %d +mysqli_stmt object is not fully initialized [014] [%d] Commands out of sync; you can't run this command now - -Warning: mysqli_stmt_fetch(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_field_count.phpt b/ext/mysqli/tests/mysqli_stmt_field_count.phpt index 2fa8a8ac80336..72cb2ecb03831 100644 --- a/ext/mysqli/tests/mysqli_stmt_field_count.phpt +++ b/ext/mysqli/tests/mysqli_stmt_field_count.phpt @@ -13,14 +13,21 @@ require_once('skipifconnectfailure.inc'); require('table.inc'); $stmt = mysqli_stmt_init($link); - if (false !== ($tmp = mysqli_stmt_field_count($stmt))) - printf("[003] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + try { + mysqli_stmt_field_count($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (mysqli_stmt_prepare($stmt, '')) printf("[004] Prepare should fail for an empty statement\n"); - if (false !== ($tmp = mysqli_stmt_field_count($stmt))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_field_count($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, 'SELECT 1')) printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -64,11 +71,17 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (mysqli_stmt_prepare($stmt, 'SELECT id FROM test')) - printf("[020] Prepare should fail, statement has been closed\n"); + try { + mysqli_stmt_prepare($stmt, 'SELECT id FROM test'); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } - if (false !== ($tmp = mysqli_stmt_field_count($stmt))) - printf("[021] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_field_count($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -79,15 +92,10 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_field_count(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_field_count(): invalid object or resource mysqli_stmt - in %s on line %d +mysqli_stmt object is not fully initialized +mysqli_stmt object is not fully initialized Warning: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in %s on line %d - -Warning: mysqli_stmt_prepare(): Couldn't fetch mysqli_stmt in %s on line %d - -Warning: mysqli_stmt_field_count(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_free_result.phpt b/ext/mysqli/tests/mysqli_stmt_free_result.phpt index 9d28d8a116679..02e7352b2881d 100644 --- a/ext/mysqli/tests/mysqli_stmt_free_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_free_result.phpt @@ -21,8 +21,11 @@ require_once('skipifconnectfailure.inc'); printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // stmt object status test - if (false !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_free_result($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -58,8 +61,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_free_result($stmt))) - printf("[015] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_free_result($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -69,9 +75,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_free_result(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_free_result(): Couldn't fetch mysqli_stmt in %s on line %d +--EXPECT-- +mysqli_stmt object is not fully initialized +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_result.phpt b/ext/mysqli/tests/mysqli_stmt_get_result.phpt index 594e112cacc8d..998fa8e0b5ca9 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result.phpt @@ -24,8 +24,11 @@ if (!function_exists('mysqli_stmt_get_result')) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // stmt object status test - if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + try { + mysqli_stmt_fetch($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -49,8 +52,11 @@ if (!function_exists('mysqli_stmt_get_result')) printf("[010] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // stmt object status test - if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[011] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + try { + mysqli_stmt_fetch($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[012] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -72,8 +78,11 @@ if (!function_exists('mysqli_stmt_get_result')) printf("[017] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // stmt object status test - if (false !== ($tmp = mysqli_stmt_get_result($stmt))) - printf("[018] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + try { + mysqli_stmt_get_result($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2")) printf("[019] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -139,8 +148,11 @@ if (!function_exists('mysqli_stmt_get_result')) mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_fetch($stmt))) - printf("[042] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1)); + try { + mysqli_stmt_fetch($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -151,14 +163,9 @@ if (!function_exists('mysqli_stmt_get_result')) require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_get_result(): invalid object or resource mysqli_stmt - in %s on line %d +mysqli_stmt object is not fully initialized +mysqli_stmt object is not fully initialized +mysqli_stmt object is not fully initialized [038] [2014] [Commands out of sync; you can't run this command now] [039] [0] [] array(2) { @@ -173,6 +180,5 @@ array(2) { ["label"]=> %s(1) "b" } - -Warning: mysqli_stmt_fetch(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt index ab261bd82b5d8..f487868996aae 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt @@ -132,18 +132,19 @@ if (!function_exists('mysqli_stmt_get_result')) mysqli_stmt_close($stmt); mysqli_close($link); - if (false !== ($res = mysqli_stmt_get_result($stmt))) { - printf("[026] Expecting false got %s/%s\n", - gettype($res), $res); - } + try { + mysqli_stmt_get_result($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } - print "done!"; + print "done!"; ?> --CLEAN-- ---EXPECTF-- +--EXPECT-- array(2) { ["id"]=> int(1) @@ -159,6 +160,5 @@ array(2) { } NULL [017] [2014] Commands out of sync; you can't run this command now - -Warning: mysqli_stmt_get_result(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt index febc659167110..fd0724ce7983c 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt @@ -193,15 +193,27 @@ if (!function_exists('mysqli_stmt_get_result')) $res->free_result(); mysqli_free_result($res_meta); - var_dump(mysqli_fetch_field($res)); + try { + mysqli_fetch_field($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_stmt_close($stmt); - var_dump(mysqli_fetch_field($res)); + try { + mysqli_fetch_field($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); - var_dump(mysqli_fetch_field($res)); + try { + mysqli_fetch_field($res); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -225,13 +237,7 @@ _id _label _null _label_concat - -Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d -bool(false) - -Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d -bool(false) - -Warning: mysqli_fetch_field(): Couldn't fetch mysqli_result in %s on line %d -bool(false) +mysqli_result object is already closed +mysqli_result object is already closed +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt index c63a91487bc75..a7db91034b191 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt @@ -94,19 +94,31 @@ if (!function_exists('mysqli_stmt_get_result')) mysqli_free_result($res); - if (false !== ($tmp = mysqli_data_seek($res, 0))) - printf("[017] Expecting false got %s/%s\n", gettype($tmp), $tmp); - - if (false !== ($row = $res->fetch_array(MYSQLI_NUM))) - printf("[018] Expecting false got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_data_seek($res, 0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } + + try { + $res->fetch_array(MYSQLI_NUM); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); - if (false !== ($tmp = mysqli_data_seek($res, 0))) - printf("[019] Expecting false got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_data_seek($res, 0); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } - if (false !== ($row = $res->fetch_array(MYSQLI_NUM))) - printf("[020] Expecting false got %s/%s\n", gettype($tmp), $tmp); + try { + $res->fetch_array(MYSQLI_NUM); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -114,12 +126,9 @@ if (!function_exists('mysqli_stmt_get_result')) ---EXPECTF-- -Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d - -Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d - -Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d - -Warning: mysqli_result::fetch_array(): Couldn't fetch mysqli_result in %s on line %d +--EXPECT-- +mysqli_result object is already closed +mysqli_result object is already closed +mysqli_result object is already closed +mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt index 958a27855451f..83f6159540b26 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt @@ -31,8 +31,11 @@ mysqli_query($link, "DROP TABLE IF EXISTS test"); if (!$stmt = mysqli_stmt_init($link)) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_get_warnings($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_get_warnings($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SET sql_mode=''") || !mysqli_stmt_execute($stmt)) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -83,8 +86,11 @@ mysqli_query($link, "DROP TABLE IF EXISTS test"); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_get_warnings($stmt))) - printf("[018] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_get_warnings($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -93,9 +99,7 @@ mysqli_query($link, "DROP TABLE IF EXISTS test"); ---EXPECTF-- -Warning: mysqli_stmt_get_warnings(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_get_warnings(): Couldn't fetch mysqli_stmt in %s on line %d +--EXPECT-- +mysqli_stmt object is not fully initialized +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_init.phpt b/ext/mysqli/tests/mysqli_stmt_init.phpt index c16f708fe65cb..2a692c4000915 100644 --- a/ext/mysqli/tests/mysqli_stmt_init.phpt +++ b/ext/mysqli/tests/mysqli_stmt_init.phpt @@ -23,12 +23,19 @@ require_once('skipifconnectfailure.inc'); if (!is_object($stmt2 = @mysqli_stmt_init($link))) printf("[003a] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - mysqli_stmt_close($stmt); + try { + mysqli_stmt_close($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); - if (false !== ($tmp = mysqli_stmt_init($link))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_init($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -36,9 +43,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_close(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_init(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli_stmt object is not fully initialized +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_insert_id.phpt b/ext/mysqli/tests/mysqli_stmt_insert_id.phpt index fedf3056505bc..e2f8ad1cb2644 100644 --- a/ext/mysqli/tests/mysqli_stmt_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_stmt_insert_id.phpt @@ -13,8 +13,12 @@ require_once('skipifconnectfailure.inc'); require('table.inc'); $stmt = mysqli_stmt_init($link); - if (false !== ($tmp = @mysqli_stmt_insert_id($stmt))) - printf("[003] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + + try { + mysqli_stmt_insert_id($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1") || !mysqli_stmt_execute($stmt)) { @@ -53,7 +57,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - var_dump(mysqli_stmt_insert_id($stmt)); + try { + mysqli_stmt_insert_id($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -61,7 +69,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_insert_id(): Couldn't fetch mysqli_stmt in %s on line %d -bool(false) +--EXPECT-- +mysqli_stmt object is not fully initialized +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_num_rows.phpt b/ext/mysqli/tests/mysqli_stmt_num_rows.phpt index f798e22f716c2..22f707a1053a2 100644 --- a/ext/mysqli/tests/mysqli_stmt_num_rows.phpt +++ b/ext/mysqli/tests/mysqli_stmt_num_rows.phpt @@ -92,8 +92,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_num_rows($stmt))) - printf("[056] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_num_rows($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -102,8 +105,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- run_tests.php don't fool me with your 'ungreedy' expression '.+?'! - -Warning: mysqli_stmt_num_rows(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_param_count.phpt b/ext/mysqli/tests/mysqli_stmt_param_count.phpt index 4176de60c55ab..5fa1b7c3502ba 100644 --- a/ext/mysqli/tests/mysqli_stmt_param_count.phpt +++ b/ext/mysqli/tests/mysqli_stmt_param_count.phpt @@ -15,8 +15,11 @@ require_once('skipifconnectfailure.inc'); if (!$stmt = mysqli_stmt_init($link)) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_param_count($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_param_count($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } function func_test_mysqli_stmt_param_count($stmt, $query, $expected, $offset) { @@ -39,8 +42,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_param_count($stmt))) - printf("[40] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_param_count($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); @@ -51,8 +57,6 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_param_count(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_param_count(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is not fully initialized +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_prepare.phpt b/ext/mysqli/tests/mysqli_stmt_prepare.phpt index 52c7597ef6ff0..be08d957495e4 100644 --- a/ext/mysqli/tests/mysqli_stmt_prepare.phpt +++ b/ext/mysqli/tests/mysqli_stmt_prepare.phpt @@ -29,8 +29,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_prepare($stmt, "SELECT id FROM test"))) - printf("[007] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_prepare($stmt, "SELECT id FROM test"); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -39,6 +42,6 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_prepare(): Couldn't fetch mysqli_stmt in %s on line %d +--EXPECT-- +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_reset.phpt b/ext/mysqli/tests/mysqli_stmt_reset.phpt index 339b885b726bc..654f09c3375df 100644 --- a/ext/mysqli/tests/mysqli_stmt_reset.phpt +++ b/ext/mysqli/tests/mysqli_stmt_reset.phpt @@ -21,8 +21,11 @@ require_once('skipifconnectfailure.inc'); if (!$stmt = mysqli_stmt_init($link)) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_reset($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_reset($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (true !== ($tmp = mysqli_stmt_prepare($stmt, 'SELECT id FROM test'))) printf("[005] Expecting boolean/true, got %s/%s, [%d] %s\n", @@ -84,8 +87,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_reset($stmt))) - printf("[021] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_reset($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -94,10 +100,8 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_reset(): invalid object or resource mysqli_stmt - in %s on line %d +--EXPECT-- +mysqli_stmt object is not fully initialized int(1) - -Warning: mysqli_stmt_reset(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt index adb7f6f72668b..12d240d8b9b5e 100644 --- a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt +++ b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt @@ -15,8 +15,11 @@ require_once('skipifconnectfailure.inc'); if (!$stmt = mysqli_stmt_init($link)) printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_result_metadata($stmt))) - printf("[004] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_result_metadata($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test")) printf("[005] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -73,8 +76,11 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_result_metadata($stmt))) - printf("[017] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_result_metadata($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -84,9 +90,8 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_result_metadata(): invalid object or resource mysqli_stmt - in %s on line %d -object(stdClass)#5 (13) { +mysqli_stmt object is not fully initialized +object(stdClass)#%d (13) { ["name"]=> string(2) "id" ["orgname"]=> @@ -114,6 +119,5 @@ object(stdClass)#5 (13) { ["decimals"]=> int(0) } - -Warning: mysqli_stmt_result_metadata(): Couldn't fetch mysqli_stmt in %s on line %d +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt b/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt index 2740195931b39..d9d3bb1dc08aa 100644 --- a/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt +++ b/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt @@ -15,8 +15,11 @@ require_once('skipifconnectfailure.inc'); if (!$stmt = mysqli_stmt_init($link)) printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_stmt_sqlstate($stmt))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_sqlstate($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "SELECT id FROM test")) printf("[006] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -33,8 +36,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); - if (false !== ($tmp = mysqli_stmt_sqlstate($stmt))) - printf("[010] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_sqlstate($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); print "done!"; @@ -43,9 +49,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_sqlstate(): invalid object or resource mysqli_stmt - in %s on line %d - -Warning: mysqli_stmt_sqlstate(): Couldn't fetch mysqli_stmt in %s on line %d +--EXPECT-- +mysqli_stmt object is not fully initialized +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_store_result.phpt b/ext/mysqli/tests/mysqli_stmt_store_result.phpt index a6634e56f9ff3..dba069223c864 100644 --- a/ext/mysqli/tests/mysqli_stmt_store_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_store_result.phpt @@ -16,8 +16,11 @@ require_once('skipifconnectfailure.inc'); printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); // stmt object status test - if (false !== ($tmp = @mysqli_stmt_store_result($stmt))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_store_result($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (100, 'z')") || !mysqli_stmt_execute($stmt)) @@ -63,8 +66,11 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); mysqli_stmt_close($stmt_buf); - if (false !== ($tmp = @mysqli_stmt_store_result($stmt))) - printf("[017] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_store_result($stmt); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } mysqli_close($link); mysqli_close($link_buf); @@ -75,4 +81,6 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECT-- +mysqli_stmt object is not fully initialized +mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_store_result.phpt b/ext/mysqli/tests/mysqli_store_result.phpt index 5ee8a14f6b818..2d9f504eefd77 100644 --- a/ext/mysqli/tests/mysqli_store_result.phpt +++ b/ext/mysqli/tests/mysqli_store_result.phpt @@ -41,8 +41,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_store_result($link))) - printf("[010] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_store_result($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -51,5 +54,5 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_store_result(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_thread_id.phpt b/ext/mysqli/tests/mysqli_thread_id.phpt index f8e286b54c73e..1349410b09eb9 100644 --- a/ext/mysqli/tests/mysqli_thread_id.phpt +++ b/ext/mysqli/tests/mysqli_thread_id.phpt @@ -21,8 +21,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_thread_id($link))) - printf("[005] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_thread_id($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -30,6 +33,6 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_thread_id(): Couldn't fetch mysqli in %s on line %d +--EXPECT-- +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_use_result.phpt b/ext/mysqli/tests/mysqli_use_result.phpt index 650a130c894d3..26ad3aabb4655 100644 --- a/ext/mysqli/tests/mysqli_use_result.phpt +++ b/ext/mysqli/tests/mysqli_use_result.phpt @@ -41,8 +41,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_use_result($link))) - printf("[010] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_use_result($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -52,6 +55,5 @@ require_once('skipifconnectfailure.inc'); ?> --EXPECTF-- Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d - -Warning: mysqli_use_result(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_warning_count.phpt b/ext/mysqli/tests/mysqli_warning_count.phpt index 5e6a2e238124e..6877843aa3c19 100644 --- a/ext/mysqli/tests/mysqli_warning_count.phpt +++ b/ext/mysqli/tests/mysqli_warning_count.phpt @@ -26,8 +26,11 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (false !== ($tmp = mysqli_warning_count($link))) - printf("[010] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_warning_count($link); + } catch (Error $exception) { + echo $exception->getMessage() . "\n"; + } print "done!"; ?> @@ -36,5 +39,5 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_warning_count(): Couldn't fetch mysqli in %s on line %d +mysqli object is already closed done! From 176ec97a16e2266eee25e7d4fae25cc28c07972b Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Thu, 30 Jan 2020 17:48:20 +0100 Subject: [PATCH 63/80] Add NEWS entry for new ReflectionProperty methods. --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index effc968cf40a6..a0147141c5ddf 100644 --- a/NEWS +++ b/NEWS @@ -81,6 +81,8 @@ PHP NEWS - Reflection: . Fixed bug #78697 (ReflectionClass::implementsInterface - inaccurate error message with traits). (villfa) + . Implement ReflectionProperty::hasDefaultValue and + Reflection::getDefaultValue (beberlei) - Session: . Fixed bug #78624 (session_gc return value for user defined session From db7193f31ea9d176214fc36cde0503864a75ab0d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 31 Jan 2020 10:34:04 +0300 Subject: [PATCH 64/80] Fixed bug #79094 (Crashing when running recursion function) --- Zend/zend_execute.c | 33 +++++++++++++++++++++++++++++++++ Zend/zend_vm_def.h | 6 +++--- Zend/zend_vm_execute.h | 6 +++--- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index ab0d3656ee584..de00080b5a988 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4452,6 +4452,39 @@ static zend_never_inline int ZEND_FASTCALL zend_quick_check_constant( return _zend_quick_get_constant(key, 0, 1 OPLINE_CC EXECUTE_DATA_CC); } /* }}} */ +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) +/* Special versions of functions that sets EX(opline) before calling zend_vm_stack_extend() */ +static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame_ex(uint32_t used_stack, uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) /* {{{ */ +{ + zend_execute_data *call = (zend_execute_data*)EG(vm_stack_top); + + ZEND_ASSERT_VM_STACK_GLOBAL; + + if (UNEXPECTED(used_stack > (size_t)(((char*)EG(vm_stack_end)) - (char*)call))) { + EX(opline) = opline; /* this is the only difference */ + call = (zend_execute_data*)zend_vm_stack_extend(used_stack); + ZEND_ASSERT_VM_STACK_GLOBAL; + zend_vm_init_call_frame(call, call_info | ZEND_CALL_ALLOCATED, func, num_args, object_or_called_scope); + return call; + } else { + EG(vm_stack_top) = (zval*)((char*)call + used_stack); + zend_vm_init_call_frame(call, call_info, func, num_args, object_or_called_scope); + return call; + } +} /* }}} */ + +static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, void *object_or_called_scope) /* {{{ */ +{ + uint32_t used_stack = zend_vm_calc_used_stack(num_args, func); + + return _zend_vm_stack_push_call_frame_ex(used_stack, call_info, + func, num_args, object_or_called_scope); +} /* }}} */ +#else +# define _zend_vm_stack_push_call_frame_ex zend_vm_stack_push_call_frame_ex +# define _zend_vm_stack_push_call_frame zend_vm_stack_push_call_frame +#endif + #ifdef ZEND_VM_TRACE_HANDLERS # include "zend_vm_trace_handlers.h" #elif defined(ZEND_VM_TRACE_MAP) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 61242d6130c5c..1499b4b5ef4b8 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3783,7 +3783,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) } CACHE_PTR(opline->result.num, fbc); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -3946,7 +3946,7 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) CACHE_PTR(opline->result.num, fbc); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -3976,7 +3976,7 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT) CACHE_PTR(opline->result.num, fbc); } - call = zend_vm_stack_push_call_frame_ex( + call = _zend_vm_stack_push_call_frame_ex( opline->op1.num, ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index da4efc5ffbae8..1e5f6455e3a10 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2897,7 +2897,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME } CACHE_PTR(opline->result.num, fbc); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -2984,7 +2984,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N CACHE_PTR(opline->result.num, fbc); } - call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); EX(call) = call; @@ -3014,7 +3014,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO CACHE_PTR(opline->result.num, fbc); } - call = zend_vm_stack_push_call_frame_ex( + call = _zend_vm_stack_push_call_frame_ex( opline->op1.num, ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL); call->prev_execute_data = EX(call); From 7e7a85e881769f3ad47a68dbef0da8c29583286a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 31 Jan 2020 10:39:22 +0300 Subject: [PATCH 65/80] Fixed JIT part for bug #79094 --- ext/opcache/jit/zend_jit_x86.dasc | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index f28c39f8a40ce..44d24e388dc64 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -6593,6 +6593,7 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, con | // EG(vm_stack_top) = (zval*)((char*)call + used_stack); |.cold_code |1: + | SAVE_VALID_OPLINE opline if (func) { | mov FCARG1d, used_stack } From 3af1cee8840a1ccaca90a4392f79510274f84450 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 30 Jan 2020 11:14:53 +0100 Subject: [PATCH 66/80] add ZipArchive::registerProgressCallback and ZipArchive::registerCancelCallback methods --- ext/zip/config.m4 | 16 ++++ ext/zip/php_zip.c | 156 +++++++++++++++++++++++++++++++++ ext/zip/php_zip.h | 6 ++ ext/zip/php_zip.stub.php | 12 +++ ext/zip/php_zip_arginfo.h | 17 ++++ ext/zip/tests/oo_cancel.phpt | 39 +++++++++ ext/zip/tests/oo_progress.phpt | 40 +++++++++ 7 files changed, 286 insertions(+) create mode 100644 ext/zip/tests/oo_cancel.phpt create mode 100644 ext/zip/tests/oo_progress.phpt diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 943852e4e6102..abd84ff51d6ac 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -35,6 +35,22 @@ if test "$PHP_ZIP" != "no"; then $LIBZIP_LIBS ]) + PHP_CHECK_LIBRARY(zip, zip_register_progress_callback_with_state, + [ + AC_DEFINE(HAVE_PROGRESS_CALLBACK, 1, [Libzip >= 1.3.0 with zip_register_progress_callback_with_state function]) + ], [ + ], [ + $LIBZIP_LIBS + ]) + + PHP_CHECK_LIBRARY(zip, zip_register_cancel_callback_with_state, + [ + AC_DEFINE(HAVE_CANCEL_CALLBACK, 1, [Libzip >= 1.6.0 with zip_register_cancel_callback_with_state function]) + ], [ + ], [ + $LIBZIP_LIBS + ]) + AC_DEFINE(HAVE_ZIP,1,[ ]) PHP_ZIP_SOURCES="php_zip.c zip_stream.c" diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 8f16f236c369c..74d992a5f6087 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -933,6 +933,30 @@ static HashTable *php_zip_get_properties(zend_object *object)/* {{{ */ } /* }}} */ +#ifdef HAVE_PROGRESS_CALLBACK +static void _php_zip_progress_callback_free(void *ptr) +{ + ze_zip_object *obj = ptr; + + if (!Z_ISUNDEF(obj->progress_callback)) { + zval_ptr_dtor(&obj->progress_callback); + ZVAL_UNDEF(&obj->progress_callback); + } +} +#endif + +#ifdef HAVE_CANCEL_CALLBACK +static void _php_zip_cancel_callback_free(void *ptr) +{ + ze_zip_object *obj = ptr; + + if (!Z_ISUNDEF(obj->cancel_callback)) { + zval_ptr_dtor(&obj->cancel_callback); + ZVAL_UNDEF(&obj->cancel_callback); + } +} +#endif + static void php_zip_object_free_storage(zend_object *object) /* {{{ */ { ze_zip_object * intern = php_zip_fetch_object(object); @@ -959,6 +983,16 @@ static void php_zip_object_free_storage(zend_object *object) /* {{{ */ efree(intern->buffers); } +#ifdef HAVE_PROGRESS_CALLBACK + /* if not properly called by libzip */ + _php_zip_progress_callback_free(intern); +#endif + +#ifdef HAVE_CANCEL_CALLBACK + /* if not properly called by libzip */ + _php_zip_cancel_callback_free(intern); +#endif + intern->za = NULL; zend_object_std_dtor(&intern->zo); @@ -2774,6 +2808,121 @@ static ZIPARCHIVE_METHOD(getStream) } /* }}} */ +#ifdef HAVE_PROGRESS_CALLBACK +static void _php_zip_progress_callback(zip_t *arch, double state, void *ptr) +{ + zval cb_args[1]; + zval cb_retval; + ze_zip_object *obj = ptr; + + ZVAL_DOUBLE(&cb_args[0], state); + if (call_user_function_ex(EG(function_table), NULL, &obj->progress_callback, &cb_retval, 1, cb_args, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) { + zval_ptr_dtor(&cb_retval); + } +} + +/* {{{ proto bool ZipArchive::registerProgressCallback(double rate, callable callback) +register a progression callback: void callback(double state); */ +static ZIPARCHIVE_METHOD(registerProgressCallback) +{ + struct zip *intern; + zval *self = getThis(); + double rate; + zval *callback; + ze_zip_object *obj; + + if (!self) { + RETURN_FALSE; + } + + ZIP_FROM_OBJECT(intern, self); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "dz", &rate, &callback) == FAILURE) { + return; + } + + /* callable? */ + if (!zend_is_callable(callback, 0, NULL)) { + zend_string *callback_name = zend_get_callable_name(callback); + php_error_docref(NULL, E_WARNING, "Invalid callback '%s'", ZSTR_VAL(callback_name)); + zend_string_release_ex(callback_name, 0); + RETURN_FALSE; + } + + obj = Z_ZIP_P(self); + + /* free if called twice */ + _php_zip_progress_callback_free(obj); + + /* register */ + ZVAL_COPY(&obj->progress_callback, callback); + if (zip_register_progress_callback_with_state(intern, rate, _php_zip_progress_callback, _php_zip_progress_callback_free, obj)) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ +#endif + +#ifdef HAVE_CANCEL_CALLBACK +static int _php_zip_cancel_callback(zip_t *arch, void *ptr) +{ + zval cb_retval; + int retval = 0; + ze_zip_object *obj = ptr; + + if (call_user_function_ex(EG(function_table), NULL, &obj->cancel_callback, &cb_retval, 0, NULL, 0, NULL) == SUCCESS && !Z_ISUNDEF(cb_retval)) { + retval = zval_get_long(&cb_retval); + zval_ptr_dtor(&cb_retval); + } + + return retval; +} + +/* {{{ proto bool ZipArchive::registerCancelCallback(callable callback) +register a progression callback: int callback(double state); */ +static ZIPARCHIVE_METHOD(registerCancelCallback) +{ + struct zip *intern; + zval *self = getThis(); + zval *callback; + ze_zip_object *obj; + + if (!self) { + RETURN_FALSE; + } + + ZIP_FROM_OBJECT(intern, self); + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &callback) == FAILURE) { + return; + } + + /* callable? */ + if (!zend_is_callable(callback, 0, NULL)) { + zend_string *callback_name = zend_get_callable_name(callback); + php_error_docref(NULL, E_WARNING, "Invalid callback '%s'", ZSTR_VAL(callback_name)); + zend_string_release_ex(callback_name, 0); + RETURN_FALSE; + } + + obj = Z_ZIP_P(self); + + /* free if called twice */ + _php_zip_cancel_callback_free(obj); + + /* register */ + ZVAL_COPY(&obj->cancel_callback, callback); + if (zip_register_cancel_callback_with_state(intern, _php_zip_cancel_callback, _php_zip_cancel_callback_free, obj)) { + RETURN_FALSE; + } + + RETURN_TRUE; +} +/* }}} */ +#endif + /* {{{ ze_zip_object_class_functions */ static const zend_function_entry zip_class_functions[] = { ZIPARCHIVE_ME(open, arginfo_class_ZipArchive_open, ZEND_ACC_PUBLIC) @@ -2824,6 +2973,13 @@ static const zend_function_entry zip_class_functions[] = { ZIPARCHIVE_ME(setEncryptionName, arginfo_class_ZipArchive_setEncryptionName, ZEND_ACC_PUBLIC) ZIPARCHIVE_ME(setEncryptionIndex, arginfo_class_ZipArchive_setEncryptionIndex, ZEND_ACC_PUBLIC) #endif +#ifdef HAVE_PROGRESS_CALLBACK + ZIPARCHIVE_ME(registerProgressCallback, arginfo_class_ZipArchive_registerProgressCallback, ZEND_ACC_PUBLIC) +#endif +#ifdef HAVE_CANCEL_CALLBACK + ZIPARCHIVE_ME(registerCancelCallback, arginfo_class_ZipArchive_registerCancelCallback, ZEND_ACC_PUBLIC) +#endif + PHP_FE_END }; /* }}} */ diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index 1eb100d45feb3..b6617e81fb3f1 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -60,6 +60,12 @@ typedef struct _ze_zip_object { int filename_len; int buffers_cnt; zend_object zo; +#ifdef HAVE_PROGRESS_CALLBACK + zval progress_callback; +#endif +#ifdef HAVE_CANCEL_CALLBACK + zval cancel_callback; +#endif } ze_zip_object; static inline ze_zip_object *php_zip_fetch_object(zend_object *obj) { diff --git a/ext/zip/php_zip.stub.php b/ext/zip/php_zip.stub.php index c88d2742eeee8..3e49c46413785 100644 --- a/ext/zip/php_zip.stub.php +++ b/ext/zip/php_zip.stub.php @@ -90,11 +90,13 @@ public function setCommentIndex(int $index, string $comment) {} /** @return null|false */ public function setCommentName(string $name, string $comment) {} +#ifdef HAVE_SET_MTIME /** @return null|false */ public function setMtimeIndex(int $index, int $timestamp, int $flags = 0) {} /** @return null|false */ public function setMtimeName(string $name, int $timestamp, int $flags = 0) {} +#endif /** @return string|false */ public function getCommentIndex(int $index, int $flags = 0) {} @@ -171,4 +173,14 @@ public function setEncryptionName(string $name, int $method, string $password = /** @return bool */ public function setEncryptionIndex(int $index, int $method, string $password = UNKNOWN) {} #endif + +#ifdef HAVE_PROGRESS_CALLBACK + /** @return bool */ + public function registerProgressCallback(float $rate, callable $callback) {} +#endif + +#ifdef HAVE_CANCEL_CALLBACK + /** @return bool */ + public function registerCancelCallback(callable $callback) {} +#endif } diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index 4839eb68b4afe..2f788d8c308de 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -111,17 +111,21 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setCommentName, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, comment, IS_STRING, 0) ZEND_END_ARG_INFO() +#if defined(HAVE_SET_MTIME) ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setMtimeIndex, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) ZEND_END_ARG_INFO() +#endif +#if defined(HAVE_SET_MTIME) ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setMtimeName, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) ZEND_END_ARG_INFO() +#endif ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_getCommentIndex, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, index, IS_LONG, 0) @@ -241,3 +245,16 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_setEncryptionIndex, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 0) ZEND_END_ARG_INFO() #endif + +#if defined(HAVE_PROGRESS_CALLBACK) +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_registerProgressCallback, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, rate, IS_DOUBLE, 0) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(HAVE_CANCEL_CALLBACK) +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_registerCancelCallback, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() +#endif diff --git a/ext/zip/tests/oo_cancel.phpt b/ext/zip/tests/oo_cancel.phpt new file mode 100644 index 0000000000000..c8653ec52ee85 --- /dev/null +++ b/ext/zip/tests/oo_cancel.phpt @@ -0,0 +1,39 @@ +--TEST-- +registerCancelCallback +--SKIPIF-- + +--INI-- +date.timezone=UTC +--FILE-- +open($file, ZIPARCHIVE::CREATE)) { + exit('failed'); +} + +var_dump($zip->registerCancelCallback(function () { + // Always cancel + return -1; +})); +var_dump($zip->addFromString(PHP_BINARY, 'entry #1')); + +var_dump($zip->close()); +@unlink($file); +?> +Done +--EXPECTF-- +bool(true) +bool(true) + +Warning: ZipArchive::close(): Operation cancelled in %s +bool(false) +Done diff --git a/ext/zip/tests/oo_progress.phpt b/ext/zip/tests/oo_progress.phpt new file mode 100644 index 0000000000000..480510d862e4b --- /dev/null +++ b/ext/zip/tests/oo_progress.phpt @@ -0,0 +1,40 @@ +--TEST-- +registerProgressCallback +--SKIPIF-- + +--INI-- +date.timezone=UTC +--FILE-- +open($file, ZIPARCHIVE::CREATE)) { + exit('failed'); +} + +var_dump($zip->registerProgressCallback(0.5, function ($r) { + // Only check start/end as intermediate is not reliable + if ($r == 0.0) echo "start\n"; + if ($r == 1.0) echo "end\n"; +})); +var_dump($zip->addFromString('foo', 'entry #1')); + +var_dump($zip->close()); +unlink($file); +?> +Done +--EXPECTF-- +bool(true) +bool(true) +start +end +bool(true) +Done From b915d68852625b5d67443013f8282764b9cf89f3 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Fri, 31 Jan 2020 09:10:10 +0100 Subject: [PATCH 67/80] Zip: version is now 1.17.0 change for Windows (which have libzip 1.4 by default) update NEWS --- NEWS | 4 +++- ext/zip/config.w32 | 2 +- ext/zip/php_zip.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index a0147141c5ddf..a41a74acc40a0 100644 --- a/NEWS +++ b/NEWS @@ -120,6 +120,8 @@ PHP NEWS - Zip: . Fixed bug #72374 (remove_path strips first char of filename). (tyage) - . Add ZipArchive::setMtimeName and ZipArchive::setMtimeIndex methods + . Add ZipArchive::setMtimeName and ZipArchive::setMtimeIndex methods. (Remi) + . Add ZipArchive::setProgressCallback method (since libzip 1.3.0). (Remi) + . Add ZipArchive::setCancelCallback method (since libzip 1.6.0). (Remi) <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index f27b047b2f49a..ab7742e227f92 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -15,7 +15,7 @@ if (PHP_ZIP != "no") { } AC_DEFINE('HAVE_ZIP', 1); - ADD_FLAG("CFLAGS_ZIP", "/D _WIN32 /D HAVE_SET_MTIME /D HAVE_ENCRYPTION /D HAVE_LIBZIP_VERSION"); + ADD_FLAG("CFLAGS_ZIP", "/D _WIN32 /D HAVE_SET_MTIME /D HAVE_ENCRYPTION /D HAVE_LIBZIP_VERSION /D HAVE_PROGRESS_CALLBACK"); } else { WARNING("zip not enabled; libraries and headers not found"); } diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index b6617e81fb3f1..c0969292a8a31 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -31,7 +31,7 @@ extern zend_module_entry zip_module_entry; #define ZIP_OVERWRITE ZIP_TRUNCATE #endif -#define PHP_ZIP_VERSION "1.16.1" +#define PHP_ZIP_VERSION "1.17.0" #define ZIP_OPENBASEDIR_CHECKPATH(filename) php_check_open_basedir(filename) From 37d0f7d3b3e9d87c4cc2ad1ca5bc26d77f49df38 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 30 Jan 2020 18:09:25 +0100 Subject: [PATCH 68/80] Use "%empty" in the parsers, instead of comments The annotation %empty is properly enforced: warnings when it's missing, and errors when it's inappropriate. Support for %empty was introduced in Bison 3.0. Pass -Wempty-rule to Bison. Closes GH-5134 --- Zend/Makefile.frag | 4 +-- Zend/zend_ini_parser.y | 8 +++--- Zend/zend_language_parser.y | 54 ++++++++++++++++++------------------- build/php.m4 | 1 + ext/json/Makefile.frag | 2 +- ext/json/json_parser.y | 5 ++-- sapi/phpdbg/Makefile.frag | 2 +- sapi/phpdbg/phpdbg_parser.y | 5 ++-- 8 files changed, 42 insertions(+), 39 deletions(-) diff --git a/Zend/Makefile.frag b/Zend/Makefile.frag index c5728af3c1113..2f3c2d948d67d 100644 --- a/Zend/Makefile.frag +++ b/Zend/Makefile.frag @@ -13,7 +13,7 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y # Tweak zendparse to be exported through ZEND_API. This has to be revisited once # bison supports foreign skeletons and that bison version is used. Read # https://git.savannah.gnu.org/cgit/bison.git/tree/data/README.md for more. - @$(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@ + @$(YACC) $(YFLAGS) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@ @$(SED) -e 's,^int zendparse\(.*\),ZEND_API int zendparse\1,g' < $@ \ > $@.tmp && \ mv $@.tmp $@ @@ -27,7 +27,7 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y $(srcdir)/zend_ini_parser.h: $(srcdir)/zend_ini_parser.c $(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y - @$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@ + @$(YACC) $(YFLAGS) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@ $(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l) diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 749f929a9bf1b..9e350664ba1fb 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -317,7 +317,7 @@ static void zval_ini_dtor(zval *zv) statement_list: statement_list statement - | /* empty */ + | %empty ; statement: @@ -351,7 +351,7 @@ statement: section_string_or_value: var_string_list_section { $$ = $1; } - | /* empty */ { zend_ini_init_string(&$$); } + | %empty { zend_ini_init_string(&$$); } ; string_or_value: @@ -364,13 +364,13 @@ string_or_value: option_offset: var_string_list { $$ = $1; } - | /* empty */ { zend_ini_init_string(&$$); } + | %empty { zend_ini_init_string(&$$); } ; encapsed_list: encapsed_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); } | encapsed_list TC_QUOTED_STRING { zend_ini_add_string(&$$, &$1, &$2); zend_string_free(Z_STR($2)); } - | /* empty */ { zend_ini_init_string(&$$); } + | %empty { zend_ini_init_string(&$$); } ; var_string_list_section: diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 5f4d6a7540ad3..4fe6f77bb1662 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -297,7 +297,7 @@ identifier: top_statement_list: top_statement_list top_statement { $$ = zend_ast_list_add($1, $2); } - | /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } + | %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } ; namespace_name: @@ -357,7 +357,7 @@ mixed_group_use_declaration: ; possible_comma: - /* empty */ + %empty | ',' ; @@ -407,7 +407,7 @@ const_list: inner_statement_list: inner_statement_list inner_statement { $$ = zend_ast_list_add($1, $2); } - | /* empty */ + | %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } ; @@ -463,7 +463,7 @@ statement: ; catch_list: - /* empty */ + %empty { $$ = zend_ast_create_list(0, ZEND_AST_CATCH_LIST); } | catch_list T_CATCH '(' catch_name_list T_VARIABLE ')' '{' inner_statement_list '}' { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_CATCH, $4, $5, $8)); } @@ -475,7 +475,7 @@ catch_name_list: ; finally_statement: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | T_FINALLY '{' inner_statement_list '}' { $$ = $3; } ; @@ -496,12 +496,12 @@ function_declaration_statement: ; is_reference: - /* empty */ { $$ = 0; } + %empty { $$ = 0; } | '&' { $$ = ZEND_PARAM_REF; } ; is_variadic: - /* empty */ { $$ = 0; } + %empty { $$ = 0; } | T_ELLIPSIS { $$ = ZEND_PARAM_VARIADIC; } ; @@ -538,17 +538,17 @@ interface_declaration_statement: ; extends_from: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | T_EXTENDS class_name { $$ = $2; } ; interface_extends_list: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | T_EXTENDS class_name_list { $$ = $2; } ; implements_list: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | T_IMPLEMENTS class_name_list { $$ = $2; } ; @@ -582,7 +582,7 @@ switch_case_list: ; case_list: - /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); } + %empty { $$ = zend_ast_create_list(0, ZEND_AST_SWITCH_LIST); } | case_list T_CASE expr case_separator inner_statement_list { $$ = zend_ast_list_add($1, zend_ast_create(ZEND_AST_SWITCH_CASE, $3, $5)); } | case_list T_DEFAULT case_separator inner_statement_list @@ -634,7 +634,7 @@ alt_if_stmt: parameter_list: non_empty_parameter_list { $$ = $1; } - | /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_PARAM_LIST); } + | %empty { $$ = zend_ast_create_list(0, ZEND_AST_PARAM_LIST); } ; @@ -654,7 +654,7 @@ parameter: optional_type: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | type_expr { $$ = $1; } ; @@ -676,7 +676,7 @@ union_type: ; return_type: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | ':' type_expr { $$ = $2; } ; @@ -722,7 +722,7 @@ static_var: class_statement_list: class_statement_list class_statement { $$ = zend_ast_list_add($1, $2); } - | /* empty */ + | %empty { $$ = zend_ast_create_list(0, ZEND_AST_STMT_LIST); } ; @@ -802,7 +802,7 @@ variable_modifiers: ; method_modifiers: - /* empty */ { $$ = ZEND_ACC_PUBLIC; } + %empty { $$ = ZEND_ACC_PUBLIC; } | non_empty_member_modifiers { $$ = $1; if (!($$ & ZEND_ACC_PPP_MASK)) { $$ |= ZEND_ACC_PUBLIC; } } ; @@ -856,7 +856,7 @@ echo_expr: ; for_exprs: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | non_empty_for_exprs { $$ = $1; } ; @@ -1026,24 +1026,24 @@ function: ; backup_doc_comment: - /* empty */ { $$ = CG(doc_comment); CG(doc_comment) = NULL; } + %empty { $$ = CG(doc_comment); CG(doc_comment) = NULL; } ; backup_fn_flags: - %prec PREC_ARROW_FUNCTION /* empty */ { $$ = CG(extra_fn_flags); CG(extra_fn_flags) = 0; } + %prec PREC_ARROW_FUNCTION %empty { $$ = CG(extra_fn_flags); CG(extra_fn_flags) = 0; } ; backup_lex_pos: - /* empty */ { $$ = LANG_SCNG(yy_text); } + %empty { $$ = LANG_SCNG(yy_text); } ; returns_ref: - /* empty */ { $$ = 0; } + %empty { $$ = 0; } | '&' { $$ = ZEND_ACC_RETURN_REFERENCE; } ; lexical_vars: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | T_USE '(' lexical_var_list ')' { $$ = $3; } ; @@ -1081,12 +1081,12 @@ class_name_reference: ; exit_expr: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | '(' optional_expr ')' { $$ = $2; } ; backticks_expr: - /* empty */ + %empty { $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); } | T_ENCAPSED_AND_WHITESPACE { $$ = $1; } | encaps_list { $$ = $1; } @@ -1094,7 +1094,7 @@ backticks_expr: ctor_arguments: - /* empty */ { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } + %empty { $$ = zend_ast_create_list(0, ZEND_AST_ARG_LIST); } | argument_list { $$ = $1; } ; @@ -1134,7 +1134,7 @@ constant: ; optional_expr: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | expr { $$ = $1; } ; @@ -1223,7 +1223,7 @@ array_pair_list: ; possible_array_pair: - /* empty */ { $$ = NULL; } + %empty { $$ = NULL; } | array_pair { $$ = $1; } ; diff --git a/build/php.m4 b/build/php.m4 index 8f7971fda8a56..87527f43813cf 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -1815,6 +1815,7 @@ AC_DEFUN([PHP_PROG_BISON], [ done if test "$php_bison_check" != "invalid"; then + AC_SUBST([YFLAGS], [-Wempty-rule]) AC_MSG_RESULT([$php_bison_version (ok)]) else AC_MSG_RESULT([$php_bison_version]) diff --git a/ext/json/Makefile.frag b/ext/json/Makefile.frag index 8719b6607fdcd..f5fe3c3306598 100644 --- a/ext/json/Makefile.frag +++ b/ext/json/Makefile.frag @@ -2,4 +2,4 @@ $(srcdir)/json_scanner.c: $(srcdir)/json_scanner.re @$(RE2C) $(RE2C_FLAGS) -t $(srcdir)/php_json_scanner_defs.h --no-generation-date -bci -o $@ $(srcdir)/json_scanner.re $(srcdir)/json_parser.tab.c: $(srcdir)/json_parser.y - @$(YACC) --defines -l $(srcdir)/json_parser.y -o $@ + @$(YACC) $(YFLAGS) --defines -l $(srcdir)/json_parser.y -o $@ diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index ec5e4e81cfa7f..833a772807c31 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -1,3 +1,4 @@ +%require "3.0" %code top { /* +----------------------------------------------------------------------+ @@ -118,7 +119,7 @@ object_end: ; members: - /* empty */ + %empty { if ((parser->scanner.options & PHP_JSON_OBJECT_AS_ARRAY) && parser->methods.object_create == php_json_parser_object_create) { ZVAL_EMPTY_ARRAY(&$$); @@ -182,7 +183,7 @@ array_end: ; elements: - /* empty */ + %empty { if (parser->methods.array_create == php_json_parser_array_create) { ZVAL_EMPTY_ARRAY(&$$); diff --git a/sapi/phpdbg/Makefile.frag b/sapi/phpdbg/Makefile.frag index 65377e608a676..448cc3676b6a1 100644 --- a/sapi/phpdbg/Makefile.frag +++ b/sapi/phpdbg/Makefile.frag @@ -18,7 +18,7 @@ $(srcdir)/phpdbg_lexer.c: $(srcdir)/phpdbg_lexer.l $(srcdir)/phpdbg_parser.h: $(srcdir)/phpdbg_parser.c $(srcdir)/phpdbg_parser.c: $(srcdir)/phpdbg_parser.y - @$(YACC) -p phpdbg_ -v -d $(srcdir)/phpdbg_parser.y -o $@ + @$(YACC) $(YFLAGS) -p phpdbg_ -v -d $(srcdir)/phpdbg_parser.y -o $@ install-phpdbg: $(BUILD_BINARY) @echo "Installing phpdbg binary: $(INSTALL_ROOT)$(bindir)/" diff --git a/sapi/phpdbg/phpdbg_parser.y b/sapi/phpdbg/phpdbg_parser.y index 3031ce5a80774..1384abe6fb78e 100644 --- a/sapi/phpdbg/phpdbg_parser.y +++ b/sapi/phpdbg/phpdbg_parser.y @@ -1,3 +1,4 @@ +%require "3.0" %{ /* @@ -65,7 +66,7 @@ typedef void* yyscan_t; input : command { $$ = $1; } | input T_SEPARATOR command { phpdbg_stack_separate($1.top); $$ = $3; } - | /* empty */ + | %empty ; command @@ -143,7 +144,7 @@ parameter req_id : T_REQ_ID { PHPDBG_G(req_id) = $1.num; } - | /* empty */ + | %empty ; full_expression From ef1e4891b47949c8dc0f9482eef9454a0ecdfa1d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 31 Jan 2020 10:21:37 +0100 Subject: [PATCH 69/80] Fix bug #76047 Unlink the current stack frame before freeing CVs or extra args. This means it will no longer show up in back traces that are generated during CV destruction. We already did this prior to destructing the object/closure, presumably for the same reason. --- NEWS | 2 ++ Zend/tests/bug52361.phpt | 5 ++- Zend/tests/bug76047.phpt | 68 ++++++++++++++++++++++++++++++++++++++++ Zend/zend_vm_def.h | 6 ++-- Zend/zend_vm_execute.h | 12 +++---- 5 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 Zend/tests/bug76047.phpt diff --git a/NEWS b/NEWS index b5ac3d68781bf..be9592d19353e 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS supported). (Nikita) . Fixed bug ##79146 (cscript can fail to run on some systems). (clarodeus) . Fixed bug #78323 (Code 0 is returned on invalid options). (Ivan Mikheykin) + . Fixed bug #76047 (Use-after-free when accessing already destructed + backtrace arguments). (Nikita) - CURL: . Fixed bug #79078 (Hypothetical use-after-free in curl_multi_add_handle()). diff --git a/Zend/tests/bug52361.phpt b/Zend/tests/bug52361.phpt index 74ed8a8d173b3..5ffe569e4a615 100644 --- a/Zend/tests/bug52361.phpt +++ b/Zend/tests/bug52361.phpt @@ -25,9 +25,8 @@ try { --EXPECTF-- 1. Exception: aaa in %sbug52361.php:5 Stack trace: -#0 %sbug52361.php(13): aaa->__destruct() -#1 %sbug52361.php(16): bbb() -#2 {main} +#0 %sbug52361.php(16): aaa->__destruct() +#1 {main} 2. Exception: bbb in %sbug52361.php:13 Stack trace: #0 %sbug52361.php(16): bbb() diff --git a/Zend/tests/bug76047.phpt b/Zend/tests/bug76047.phpt new file mode 100644 index 0000000000000..f0f743ee3d686 --- /dev/null +++ b/Zend/tests/bug76047.phpt @@ -0,0 +1,68 @@ +--TEST-- +Bug #76047: Use-after-free when accessing already destructed backtrace arguments +--FILE-- +a); + $backtrace = (new Exception)->getTrace(); + var_dump($backtrace); + } +} + +function test($arg) { + $arg = str_shuffle(str_repeat('A', 79)); + $vuln = new Vuln(); + $vuln->a = $arg; +} + +function test2($arg) { + $$arg = 1; // Trigger symbol table + $arg = str_shuffle(str_repeat('A', 79)); + $vuln = new Vuln(); + $vuln->a = $arg; +} + +test('x'); +test2('x'); + +?> +--EXPECTF-- +array(1) { + [0]=> + array(6) { + ["file"]=> + string(%d) "%s" + ["line"]=> + int(%d) + ["function"]=> + string(10) "__destruct" + ["class"]=> + string(4) "Vuln" + ["type"]=> + string(2) "->" + ["args"]=> + array(0) { + } + } +} +array(1) { + [0]=> + array(6) { + ["file"]=> + string(%d) "%s" + ["line"]=> + int(%d) + ["function"]=> + string(10) "__destruct" + ["class"]=> + string(4) "Vuln" + ["type"]=> + string(2) "->" + ["args"]=> + array(0) { + } + } +} diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 62a9ad8bed817..fbd79019e7629 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2398,9 +2398,9 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) uint32_t call_info = EX_CALL_INFO(); if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); - EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { zend_object *object = Z_OBJ(execute_data->This); #if 0 @@ -2426,12 +2426,12 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) LOAD_NEXT_OPLINE(); ZEND_VM_LEAVE(); } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } - EG(current_execute_data) = EX(prev_execute_data); /* Free extra args before releasing the closure, * as that may free the op_array. */ @@ -2481,6 +2481,7 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) ZEND_VM_LEAVE(); } else { if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { @@ -2488,7 +2489,6 @@ ZEND_VM_HOT_HELPER(zend_leave_helper, ANY, ANY) } zend_vm_stack_free_extra_args_ex(call_info, execute_data); } - EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e893e35b6d53f..33518478c32e9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -507,9 +507,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ uint32_t call_info = EX_CALL_INFO(); if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); - EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { zend_object *object = Z_OBJ(execute_data->This); #if 0 @@ -535,12 +535,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ LOAD_NEXT_OPLINE(); ZEND_VM_LEAVE(); } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } - EG(current_execute_data) = EX(prev_execute_data); /* Free extra args before releasing the closure, * as that may free the op_array. */ @@ -590,6 +590,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ ZEND_VM_LEAVE(); } else { if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { @@ -597,7 +598,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_ } zend_vm_stack_free_extra_args_ex(call_info, execute_data); } - EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } @@ -55379,9 +55379,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) uint32_t call_info = EX_CALL_INFO(); if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); - EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { zend_object *object = Z_OBJ(execute_data->This); #if 0 @@ -55407,12 +55407,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) LOAD_NEXT_OPLINE(); ZEND_VM_LEAVE(); } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } - EG(current_execute_data) = EX(prev_execute_data); /* Free extra args before releasing the closure, * as that may free the op_array. */ @@ -55462,6 +55462,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_VM_LEAVE(); } else { if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); i_free_compiled_variables(execute_data); if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS))) { if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { @@ -55469,7 +55470,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) } zend_vm_stack_free_extra_args_ex(call_info, execute_data); } - EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } From d8a1e3dab0e10ddc8990fec5f6dcc0f0fd4778c0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 31 Jan 2020 10:35:46 +0100 Subject: [PATCH 70/80] Fix JIT as well --- ext/opcache/jit/zend_jit_x86.dasc | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 44d24e388dc64..fd75d67929528 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -7957,6 +7957,10 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze |=>jit_return_label: + | // EG(current_execute_data) = EX(prev_execute_data); + | mov r0, EX->prev_execute_data + | MEM_OP2_1_ZTS mov, aword, executor_globals, current_execute_data, r0, r2 + // i_free_compiled_variables(execute_data); if (!zend_jit_free_compiled_variables(Dst, opline, op_array, ssa)) { return 0; @@ -7969,9 +7973,6 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze if ((op_array->scope && !(op_array->fn_flags & ZEND_ACC_STATIC)) || (op_array->fn_flags & ZEND_ACC_CLOSURE)) { - | // EG(current_execute_data) = EX(prev_execute_data); - | mov r0, EX->prev_execute_data - | MEM_OP2_1_ZTS mov, aword, executor_globals, current_execute_data, r0, r2 if (op_array->fn_flags & ZEND_ACC_CLOSURE) { | // OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); | mov r0, EX->func @@ -7987,18 +7988,11 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze | OBJ_RELEASE r0, ecx, >4 } |4: - | // EG(vm_stack_top) = (zval*)execute_data; - | MEM_OP2_1_ZTS mov, aword, executor_globals, vm_stack_top, FP, r0 - | // execute_data = EX(prev_execute_data); - | mov FP, EX->prev_execute_data - } else { - | // EG(vm_stack_top) = (zval*)execute_data; - | MEM_OP2_1_ZTS mov, aword, executor_globals, vm_stack_top, FP, r0 - | // execute_data = EX(prev_execute_data); - | mov FP, EX->prev_execute_data - | // EG(current_execute_data) = execute_data - | MEM_OP2_1_ZTS mov, aword, executor_globals, current_execute_data, FP, r0 } + | // EG(vm_stack_top) = (zval*)execute_data; + | MEM_OP2_1_ZTS mov, aword, executor_globals, vm_stack_top, FP, r0 + | // execute_data = EX(prev_execute_data); + | mov FP, EX->prev_execute_data | // if (EG(exception)) | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 | LOAD_OPLINE From 08d2d9257dfa4b08a5972461f8bdbc03b81301a8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 31 Jan 2020 13:27:35 +0300 Subject: [PATCH 71/80] Export zend_dump_op() and add ZEND_DUMP_NUMERIC_OPLINES flag to print oplines as "dddd" instead of "Ld+" --- ext/opcache/Optimizer/zend_dump.c | 73 +++++++++++++++++++++++-------- ext/opcache/Optimizer/zend_dump.h | 3 +- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/ext/opcache/Optimizer/zend_dump.c b/ext/opcache/Optimizer/zend_dump.c index 515532b3b4537..59288fabddabd 100644 --- a/ext/opcache/Optimizer/zend_dump.c +++ b/ext/opcache/Optimizer/zend_dump.c @@ -402,23 +402,17 @@ static void zend_dump_range_constraint(const zend_op_array *op_array, const zend } } -static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const void *data) +void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const void *data) { const char *name = zend_get_opcode_name(opline->opcode); uint32_t flags = zend_get_opcode_flags(opline->opcode); uint32_t n = 0; - int len = 0; const zend_ssa *ssa = NULL; if (dump_flags & ZEND_DUMP_SSA) { ssa = (const zend_ssa*)data; } - if (!b) { - len = fprintf(stderr, "L%u (%u):", (uint32_t)(opline - op_array->opcodes), opline->lineno); - } - fprintf(stderr, "%*c", 12-len, ' '); - if (!ssa || !ssa->ops || ssa->ops[opline - op_array->opcodes].result_use < 0) { if (opline->result_type & (IS_CV|IS_VAR|IS_TMP_VAR)) { if (ssa && ssa->ops && ssa->ops[opline - op_array->opcodes].result_def >= 0) { @@ -611,7 +605,9 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block * } else { uint32_t op1_flags = ZEND_VM_OP1_FLAGS(flags); if (ZEND_VM_OP_JMP_ADDR == (op1_flags & ZEND_VM_OP_MASK)) { - if (b) { + if (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) { + fprintf(stderr, " %04u", (uint32_t)(OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes)); + } else if (b) { fprintf(stderr, " BB%d", b->successors[n++]); } else { fprintf(stderr, " L%u", (uint32_t)(OP_JMP_ADDR(opline, opline->op1) - op_array->opcodes)); @@ -634,7 +630,9 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block * } else { fprintf(stderr, " " ZEND_LONG_FMT ":", num_key); } - if (b) { + if (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) { + fprintf(stderr, " %04u,", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv))); + } else if (b) { fprintf(stderr, " BB%d,", b->successors[n++]); } else { fprintf(stderr, " L%u,", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, Z_LVAL_P(zv))); @@ -669,7 +667,9 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block * uint32_t op2_flags = ZEND_VM_OP2_FLAGS(flags); if (ZEND_VM_OP_JMP_ADDR == (op2_flags & ZEND_VM_OP_MASK)) { if (opline->opcode != ZEND_CATCH || !(opline->extended_value & ZEND_LAST_CATCH)) { - if (b) { + if (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) { + fprintf(stderr, " %04u", (uint32_t)(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes)); + } else if (b) { fprintf(stderr, " BB%d", b->successors[n++]); } else { fprintf(stderr, " L%u", (uint32_t)(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes)); @@ -681,7 +681,9 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block * } if (ZEND_VM_EXT_JMP_ADDR == (flags & ZEND_VM_EXT_MASK)) { - if (b) { + if (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) { + fprintf(stderr, " %04u", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); + } else if (b) { fprintf(stderr, " BB%d", b->successors[n++]); } else { fprintf(stderr, " L%u", (uint32_t)ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value)); @@ -716,6 +718,20 @@ static void zend_dump_op(const zend_op_array *op_array, const zend_basic_block * } } } +} + +static void zend_dump_op_line(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const void *data) +{ + int len = 0; + + if (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) { + len = fprintf(stderr, "%04u:", (uint32_t)(opline - op_array->opcodes)); + } else if (!b) { + len = fprintf(stderr, "L%u (%u):", (uint32_t)(opline - op_array->opcodes), opline->lineno); + } + fprintf(stderr, "%*c", 12-len, ' '); + + zend_dump_op(op_array, b, opline, dump_flags, data); fprintf(stderr, "\n"); } @@ -997,7 +1013,7 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons opline = op_array->opcodes + b->start; end = opline + b->len; while (opline < end) { - zend_dump_op(op_array, b, opline, dump_flags, data); + zend_dump_op_line(op_array, b, opline, dump_flags, data); opline++; } } @@ -1005,7 +1021,10 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) { fprintf(stderr, "LIVE RANGES:\n"); for (i = 0; i < op_array->last_live_range; i++) { - fprintf(stderr, " %u: L%u - L%u ", + fprintf(stderr, + (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) ? + " %u: %04u - %04u " : + " %u: L%u - L%u ", EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK), op_array->live_range[i].start, op_array->live_range[i].end); @@ -1058,13 +1077,16 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons const zend_op *end = opline + op_array->last; while (opline < end) { - zend_dump_op(op_array, NULL, opline, dump_flags, data); + zend_dump_op_line(op_array, NULL, opline, dump_flags, data); opline++; } if (op_array->last_live_range && (dump_flags & ZEND_DUMP_LIVE_RANGES)) { fprintf(stderr, "LIVE RANGES:\n"); for (i = 0; i < op_array->last_live_range; i++) { - fprintf(stderr, " %u: L%u - L%u ", + fprintf(stderr, + (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) ? + " %u: %04u - %04u " : + " %u: L%u - L%u ", EX_VAR_TO_NUM(op_array->live_range[i].var & ~ZEND_LIVE_MASK), op_array->live_range[i].start, op_array->live_range[i].end); @@ -1090,22 +1112,35 @@ void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, cons if (op_array->last_try_catch) { fprintf(stderr, "EXCEPTION TABLE:\n"); for (i = 0; i < op_array->last_try_catch; i++) { - fprintf(stderr, " L%u", + fprintf(stderr, + (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) ? + " %04u" : + " L%u", op_array->try_catch_array[i].try_op); + if (op_array->try_catch_array[i].catch_op) { - fprintf(stderr, ", L%u", + fprintf(stderr, + (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) ? + ", %04u" : + ", L%u", op_array->try_catch_array[i].catch_op); } else { fprintf(stderr, ", -"); } if (op_array->try_catch_array[i].finally_op) { - fprintf(stderr, ", L%u", + fprintf(stderr, + (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) ? + ", %04u" : + ", L%u", op_array->try_catch_array[i].finally_op); } else { fprintf(stderr, ", -"); } if (op_array->try_catch_array[i].finally_end) { - fprintf(stderr, ", L%u\n", + fprintf(stderr, + (dump_flags & ZEND_DUMP_NUMERIC_OPLINES) ? + ", %04u" : + ", L%u\n", op_array->try_catch_array[i].finally_end); } else { fprintf(stderr, ", -\n"); diff --git a/ext/opcache/Optimizer/zend_dump.h b/ext/opcache/Optimizer/zend_dump.h index 820f3daf193ce..5f1968fd23852 100644 --- a/ext/opcache/Optimizer/zend_dump.h +++ b/ext/opcache/Optimizer/zend_dump.h @@ -27,11 +27,12 @@ #define ZEND_DUMP_CFG (1<<2) #define ZEND_DUMP_SSA (1<<3) #define ZEND_DUMP_LIVE_RANGES (1<<4) -#define ZEND_DUMP_RT_CONSTANTS ZEND_RT_CONSTANTS +#define ZEND_DUMP_NUMERIC_OPLINES (1<<5) BEGIN_EXTERN_C() void zend_dump_op_array(const zend_op_array *op_array, uint32_t dump_flags, const char *msg, const void *data); +void zend_dump_op(const zend_op_array *op_array, const zend_basic_block *b, const zend_op *opline, uint32_t dump_flags, const void *data); void zend_dump_dominators(const zend_op_array *op_array, const zend_cfg *cfg); void zend_dump_dfg(const zend_op_array *op_array, const zend_cfg *cfg, const zend_dfg *dfg); void zend_dump_phi_placement(const zend_op_array *op_array, const zend_ssa *ssa); From 6b862e82d9363c2b25ebb762cee7bf8efd3c5bc7 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 31 Jan 2020 14:50:41 +0300 Subject: [PATCH 72/80] These EG(current_execute_data) = EX(prev_execute_data) assignments are useless now --- ext/opcache/jit/zend_jit_vm_helpers.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 346d50ec59f45..9862fd1b421ee 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -48,7 +48,6 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(uint32_t if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { zend_clean_and_cache_symbol_table(EX(symbol_table)); } - EG(current_execute_data) = EX(prev_execute_data); zend_vm_stack_free_extra_args_ex(call_info, execute_data); if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { @@ -88,7 +87,6 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_top_func_helper(uint32_t ca } zend_vm_stack_free_extra_args_ex(call_info, execute_data); } - EG(current_execute_data) = EX(prev_execute_data); if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); } From 2b279b428fb31f7b66555f9be7baac110730112e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 31 Jan 2020 16:01:09 +0300 Subject: [PATCH 73/80] We don't need "safe" destruction anymore --- Zend/zend_execute.c | 10 +--------- Zend/zend_execute.h | 18 ++---------------- ext/opcache/jit/zend_jit_x86.dasc | 4 ++-- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index b1bc3234eab89..9203fa6eb567a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3373,15 +3373,7 @@ static zend_always_inline void i_free_compiled_variables(zend_execute_data *exec zval *cv = EX_VAR_NUM(0); int count = EX(func)->op_array.last_var; while (EXPECTED(count != 0)) { - if (Z_REFCOUNTED_P(cv)) { - zend_refcounted *r = Z_COUNTED_P(cv); - if (!GC_DELREF(r)) { - ZVAL_NULL(cv); - rc_dtor_func(r); - } else { - gc_check_possible_root(r); - } - } + i_zval_ptr_dtor(cv); cv++; count--; } diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index e2782e2127c56..745830652a292 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -230,15 +230,7 @@ static zend_always_inline void zend_vm_stack_free_extra_args_ex(uint32_t call_in uint32_t count = ZEND_CALL_NUM_ARGS(call) - call->func->op_array.num_args; zval *p = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T); do { - if (Z_REFCOUNTED_P(p)) { - zend_refcounted *r = Z_COUNTED_P(p); - if (!GC_DELREF(r)) { - ZVAL_NULL(p); - rc_dtor_func(r); - } else { - gc_check_possible_root(r); - } - } + i_zval_ptr_dtor(p); p++; } while (--count); } @@ -257,13 +249,7 @@ static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call) zval *p = ZEND_CALL_ARG(call, 1); do { - if (Z_REFCOUNTED_P(p)) { - zend_refcounted *r = Z_COUNTED_P(p); - if (!GC_DELREF(r)) { - ZVAL_NULL(p); - rc_dtor_func(r); - } - } + zval_ptr_dtor_nogc(p); p++; } while (--num_args); } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index fd75d67929528..b8e91f3846dab 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -7207,7 +7207,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend if (func) { for (i = 0; i < call_info->num_args; i++ ) { uint32_t offset = (uint32_t)(uintptr_t)ZEND_CALL_VAR_NUM(NULL, i); - | ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_RX, offset), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, 0, 1, 1, opline + | ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_RX, offset), MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN, 0, 1, 0, opline } } else { | mov FCARG1a, RX @@ -7939,7 +7939,7 @@ static int zend_jit_free_compiled_variables(dasm_State **Dst, const zend_op *opl if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { uint32_t offset = (uint32_t)(uintptr_t)ZEND_CALL_VAR_NUM(NULL, i); - | ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_FP, offset), info, 1, 1, 1, opline + | ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_FP, offset), info, 1, 1, 0, opline } } return 1; From ee87e86d0afcecd8f604229e810e0e2df22bdeeb Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Wed, 29 Jan 2020 14:54:19 +0000 Subject: [PATCH 74/80] inline by hand to avoid uninitialized variable warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When compiling with "-Wall -Werror" gcc emits two errors: ../src/pcre2_jit_neon_inc.h:211:8: error: ‘cmp1b’ is used uninitialized in this function [-Werror=uninitialized] 211 | data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../src/pcre2_jit_neon_inc.h:212:9: error: ‘cmp2b’ is used uninitialized in this function [-Werror=uninitialized] 212 | data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The compiler emits the error message before inlining. Because the warning is based on an intra-procedural data flow analysis, the compiler does not see that cmp1b and cmp2b are not used when they are not initialized. Here is the code of that function, cmp2 is only used when ctype is compare_match2 or compare_match1i, and not when ctype is compare_match1: static inline vect_t fast_forward_char_pair_compare(compare_type ctype, vect_t dst, vect_t cmp1, vect_t cmp2) { if (ctype == compare_match2) { vect_t tmp = dst; dst = VCEQQ(dst, cmp1); tmp = VCEQQ(tmp, cmp2); dst = VORRQ(dst, tmp); return dst; } if (ctype == compare_match1i) dst = VORRQ(dst, cmp2); dst = VCEQQ(dst, cmp1); return dst; } The patch inlines by hand the case of compare_match1 such that the code avoids referring to cmp1b and cmp2b. Tested on aarch64-linux with `make check`. --- ext/pcre/pcre2lib/pcre2_jit_neon_inc.h | 34 +++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h index aec48219eafa2..0265f36a0b309 100644 --- a/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h +++ b/ext/pcre/pcre2lib/pcre2_jit_neon_inc.h @@ -109,7 +109,7 @@ vect_t vmask = VDUPQ(mask); #if defined(FFCPS) compare_type compare1_type = compare_match1; compare_type compare2_type = compare_match1; -vect_t cmp1a = vdupq_n_u8(0), cmp1b = vdupq_n_u8(0), cmp2a = vdupq_n_u8(0), cmp2b = vdupq_n_u8(0); +vect_t cmp1a, cmp1b, cmp2a, cmp2b; const sljit_u32 diff = IN_UCHARS(offs1 - offs2); PCRE2_UCHAR char1a = ic.c.c1; PCRE2_UCHAR char2a = ic.c.c3; @@ -117,11 +117,16 @@ PCRE2_UCHAR char2a = ic.c.c3; # ifdef FFCPS_CHAR1A2A cmp1a = VDUPQ(char1a); cmp2a = VDUPQ(char2a); +cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ +cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ # else PCRE2_UCHAR char1b = ic.c.c2; PCRE2_UCHAR char2b = ic.c.c4; if (char1a == char1b) + { cmp1a = VDUPQ(char1a); + cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ + } else { sljit_u32 bit1 = char1a ^ char1b; @@ -140,7 +145,10 @@ else } if (char2a == char2b) + { cmp2a = VDUPQ(char2a); + cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */ + } else { sljit_u32 bit2 = char2a ^ char2b; @@ -207,9 +215,17 @@ if (p1 < str_ptr) } else data2 = shift_left_n_lanes(data, offs1 - offs2); - -data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); -data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); + +if (compare1_type == compare_match1) + data = VCEQQ(data, cmp1a); +else + data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); + +if (compare2_type == compare_match1) + data2 = VCEQQ(data2, cmp2a); +else + data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); + vect_t eq = VANDQ(data, data2); #endif @@ -275,8 +291,14 @@ while (str_ptr < str_end) data = VCEQQ(data, cmp1a); data2 = VCEQQ(data2, cmp2a); # else - data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); - data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); + if (compare1_type == compare_match1) + data = VCEQQ(data, cmp1a); + else + data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); + if (compare2_type == compare_match1) + data2 = VCEQQ(data2, cmp2a); + else + data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); # endif eq = VANDQ(data, data2); From 8b36be268d2ac2ab77162ed540db6aab9c819a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 31 Jan 2020 17:20:00 +0100 Subject: [PATCH 75/80] Fix indentation and whitespaces in tests In preparation for GH-5074 --- ext/ctype/tests/ctype_space_variation1.phpt | 4 +- ...t_format_simple_types_numeric_strings.phpt | 44 +++++++-------- .../ReflectionClass_getDocComment_001.phpt | 8 +-- ext/simplexml/tests/bug38354.phpt | 6 +- ext/standard/tests/file/flock_variation.phpt | 4 +- ext/standard/tests/file/fpassthru_basic.phpt | 30 +++++----- .../tests/general_functions/print_r.phpt | 28 ++++----- .../general_functions/print_r_64bit.phpt | 16 +++--- .../tests/general_functions/var_dump.phpt | 18 +++--- .../general_functions/var_dump_64bit.phpt | 14 ++--- ext/standard/tests/strings/bug21453.phpt | 10 ++-- ext/standard/tests/strings/str_ireplace.phpt | 12 ++-- .../tests/strings/str_replace_variation2.phpt | Bin 12653 -> 12610 bytes .../tests/strings/str_word_count.phpt | 10 ++-- .../tests/strings/strncasecmp_variation9.phpt | 4 +- ext/standard/tests/strings/strstr.phpt | Bin 9540 -> 9512 bytes .../strings/vfprintf_variation4_64bit.phpt | 53 +++++++++--------- .../strings/vprintf_variation4_64bit.phpt | 48 ++++++++-------- .../tests/token_get_all_variation18.phpt | 18 +++--- .../tests/token_get_all_variation19.phpt | 18 +++--- 20 files changed, 174 insertions(+), 171 deletions(-) diff --git a/ext/ctype/tests/ctype_space_variation1.phpt b/ext/ctype/tests/ctype_space_variation1.phpt index 73da03ad3d59b..d3920b69c2d5d 100644 --- a/ext/ctype/tests/ctype_space_variation1.phpt +++ b/ext/ctype/tests/ctype_space_variation1.phpt @@ -31,7 +31,7 @@ class classA // heredoc string $heredoc = <<format(array( @@ -41,14 +41,14 @@ var_dump($mf->format(array( ?> --EXPECTF-- string(%d) " - none 1336317965.5 str - number 1,336,317,965.5 - number integer 1,336,317,965 - number currency $1,336,317,965.50 - number percent 133,631,796,550% - date May %d, 2012 - time %d:%d:05 PM - spellout one billion three hundred thirty-six million three hundred seventeen thousand nine hundred sixty-five point five - ordinal 1,336,317,966th - duration 371,199:26:06 - " + none 1336317965.5 str + number 1,336,317,965.5 + number integer 1,336,317,965 + number currency $1,336,317,965.50 + number percent 133,631,796,550% + date May %d, 2012 + time %d:%d:05 PM + spellout one billion three hundred thirty-six million three hundred seventeen thousand nine hundred sixty-five point five + ordinal 1,336,317,966th + duration 371,199:26:06 +" diff --git a/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt index 9171a8dd2562d..d4f3ed27f2566 100644 --- a/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt +++ b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt @@ -10,9 +10,9 @@ opcache.save_comments=1 /** - My + My Doc - * Comment + * Comment for A * */ @@ -60,9 +60,9 @@ foreach ($classes as $class) { string(%d) "/** - My + My Doc - * Comment + * Comment for A * */" diff --git a/ext/simplexml/tests/bug38354.phpt b/ext/simplexml/tests/bug38354.phpt index 7bd18fe649dc0..c1147c5d09a26 100644 --- a/ext/simplexml/tests/bug38354.phpt +++ b/ext/simplexml/tests/bug38354.phpt @@ -7,7 +7,7 @@ Bug #38354 (Unwanted reformatting of XML when using AsXML) $xml = simplexml_load_string( ' - Item Two + Item Two ' ); @@ -18,9 +18,9 @@ foreach ($xml->xpath("//*") as $element) { echo "Done\n"; ?> --EXPECT-- -string(101) " +string(104) " - Item Two + Item Two " string(62) "Item Two" diff --git a/ext/standard/tests/file/flock_variation.phpt b/ext/standard/tests/file/flock_variation.phpt index 49c4a53a3d574..a912fce3c9cc8 100644 --- a/ext/standard/tests/file/flock_variation.phpt +++ b/ext/standard/tests/file/flock_variation.phpt @@ -9,7 +9,7 @@ Description: PHP supports a portable way of locking complete files */ echo "*** Testing flock() fun with the various operation and - wouldblock values ***\n"; + wouldblock values ***\n"; $file = preg_replace("~\.phpt?$~", null, __FILE__); $fp = fopen($file, "w"); @@ -67,7 +67,7 @@ echo "\n*** Done ***\n"; ?> --EXPECT-- *** Testing flock() fun with the various operation and - wouldblock values *** + wouldblock values *** --- Outer iteration 0 --- bool(true) -- Inner iteration 0 in 0 -- diff --git a/ext/standard/tests/file/fpassthru_basic.phpt b/ext/standard/tests/file/fpassthru_basic.phpt index 93767143683a3..f453a484f9541 100644 --- a/ext/standard/tests/file/fpassthru_basic.phpt +++ b/ext/standard/tests/file/fpassthru_basic.phpt @@ -11,7 +11,7 @@ Description: Reads to EOF on the given file pointer from the current position $file_name = __DIR__."/passthru.tmp"; $write_handle = fopen($file_name, "w"); -$string = "Hello, world\n, abcdefg\tadsdsfdf\n8u2394723947\t$%$%#$%#$%#^#%^ +$string = "Hello, world\n, abcdefg\tadsdsfdf\n8u2394723947\t$%$%#$%#$%#^#%^ Hello, world\n, abcdefg\tadsdsfdf\n8u2394723947\t$%$%#$%#$%#^#%^\n"; if(substr(PHP_OS, 0, 3) == "WIN") { $string = str_replace("\r",'', $string); @@ -68,60 +68,60 @@ unlink(__DIR__."/passthru.tmp"); -- Before seek operation -- Hello, world , abcdefg adsdsfdf -8u2394723947 $%$%#$%#$%#^#%^ +8u2394723947 $%$%#$%#$%#^#%^ Hello, world , abcdefg adsdsfdf 8u2394723947 $%$%#$%#$%#^#%^ -int(133) +int(132) -- After seeking position to 0 -- Hello, world , abcdefg adsdsfdf -8u2394723947 $%$%#$%#$%#^#%^ +8u2394723947 $%$%#$%#$%#^#%^ Hello, world , abcdefg adsdsfdf 8u2394723947 $%$%#$%#$%#^#%^ -int(133) +int(132) -- After seeking position to 3 -- lo, world , abcdefg adsdsfdf -8u2394723947 $%$%#$%#$%#^#%^ +8u2394723947 $%$%#$%#$%#^#%^ Hello, world , abcdefg adsdsfdf 8u2394723947 $%$%#$%#$%#^#%^ -int(130) +int(129) -- After seeking position to 13 -- , abcdefg adsdsfdf -8u2394723947 $%$%#$%#$%#^#%^ +8u2394723947 $%$%#$%#$%#^#%^ Hello, world , abcdefg adsdsfdf 8u2394723947 $%$%#$%#$%#^#%^ -int(120) +int(119) -- After seeking position to 14 -- abcdefg adsdsfdf -8u2394723947 $%$%#$%#$%#^#%^ +8u2394723947 $%$%#$%#$%#^#%^ Hello, world , abcdefg adsdsfdf 8u2394723947 $%$%#$%#$%#^#%^ -int(119) +int(118) -- After seeking position to 23 -- adsdsfdf -8u2394723947 $%$%#$%#$%#^#%^ +8u2394723947 $%$%#$%#$%#^#%^ Hello, world , abcdefg adsdsfdf 8u2394723947 $%$%#$%#$%#^#%^ -int(110) +int(109) -- After seeking position to 34 -- -2394723947 $%$%#$%#$%#^#%^ +2394723947 $%$%#$%#$%#^#%^ Hello, world , abcdefg adsdsfdf 8u2394723947 $%$%#$%#$%#^#%^ -int(99) +int(98) -- After seeking position to 1000 -- int(0) diff --git a/ext/standard/tests/general_functions/print_r.phpt b/ext/standard/tests/general_functions/print_r.phpt index f0afa642890c3..3f24a5bc9d44d 100644 --- a/ext/standard/tests/general_functions/print_r.phpt +++ b/ext/standard/tests/general_functions/print_r.phpt @@ -101,7 +101,7 @@ $strings = array ( 'PHP', "abcd\x0n1234\x0005678\x0000efgh\xijkl", // strings with hexadecimal NULL "abcd\0efgh\0ijkl\x00mnop\x000qrst\00uvwx\0000yz", // strings with octal NULL - "1234\t\n5678\n\t9100\rabcda" // strings with escape characters + "1234\t\n5678\n\t9100\"abcda" // strings with escape characters ); /* calling check_printr() to display contents of strings using print_r() */ check_printr($strings); @@ -240,8 +240,8 @@ $resources = array ( using print_r() */ check_printr($resources); -echo "\n*** Testing print_r() on different combinations of scalar - and non-scalar variables ***\n"; +echo "\n*** Testing print_r() on different combinations of scalar + and non-scalar variables ***\n"; /* a variable which is unset */ $unset_var = 10.5; unset($unset_var); @@ -604,13 +604,13 @@ abcdefghijklmnop0qrstuvwx0yz -- Iteration 14 -- 1234 5678 - 9100 abcda + 9100"abcda 1234 5678 - 9100 abcda + 9100"abcda 1234 5678 - 9100 abcda + 9100"abcda *** Testing print_r() on boolean variables *** -- Iteration 1 -- @@ -1462,15 +1462,15 @@ object_class Object *** Testing print_r() on resources *** -- Iteration 1 -- -Resource id #%d -Resource id #%d -Resource id #%d +Resource id #5 +Resource id #5 +Resource id #5 -- Iteration 2 -- -Resource id #%d -Resource id #%d -Resource id #%d -*** Testing print_r() on different combinations of scalar - and non-scalar variables *** +Resource id #6 +Resource id #6 +Resource id #6 +*** Testing print_r() on different combinations of scalar + and non-scalar variables *** -- Iteration 1 -- Array diff --git a/ext/standard/tests/general_functions/print_r_64bit.phpt b/ext/standard/tests/general_functions/print_r_64bit.phpt index 17b829231f6c8..a0e9e148c68ea 100644 --- a/ext/standard/tests/general_functions/print_r_64bit.phpt +++ b/ext/standard/tests/general_functions/print_r_64bit.phpt @@ -105,7 +105,7 @@ $strings = array ( 'PHP', "abcd\x0n1234\x0005678\x0000efgh\xijkl", // strings with hexadecimal NULL "abcd\0efgh\0ijkl\x00mnop\x000qrst\00uvwx\0000yz", // strings with octal NULL - "1234\t\n5678\n\t9100\rabcda" // strings with escape characters + "1234\t\n5678\n\t9100\"abcda" // strings with escape characters ); /* calling check_printr() to display contents of strings using print_r() */ check_printr($strings); @@ -244,8 +244,8 @@ $resources = array ( using print_r() */ check_printr($resources); -echo "\n*** Testing print_r() on different combinations of scalar - and non-scalar variables ***\n"; +echo "\n*** Testing print_r() on different combinations of scalar + and non-scalar variables ***\n"; /* a variable which is unset */ $unset_var = 10.5; unset($unset_var); @@ -608,13 +608,13 @@ abcdefghijklmnop0qrstuvwx0yz -- Iteration 14 -- 1234 5678 - 9100 abcda + 9100"abcda 1234 5678 - 9100 abcda + 9100"abcda 1234 5678 - 9100 abcda + 9100"abcda *** Testing print_r() on boolean variables *** -- Iteration 1 -- @@ -1473,8 +1473,8 @@ Resource id #5 Resource id #6 Resource id #6 Resource id #6 -*** Testing print_r() on different combinations of scalar - and non-scalar variables *** +*** Testing print_r() on different combinations of scalar + and non-scalar variables *** -- Iteration 1 -- Array diff --git a/ext/standard/tests/general_functions/var_dump.phpt b/ext/standard/tests/general_functions/var_dump.phpt index 08807191cbb3f..889b2b1fc2bde 100644 --- a/ext/standard/tests/general_functions/var_dump.phpt +++ b/ext/standard/tests/general_functions/var_dump.phpt @@ -239,8 +239,8 @@ $resources = array ( using var_dump() */ check_vardump($resources); -echo "\n*** Testing var_dump() on different combinations of scalar - and non-scalar variables ***\n"; +echo "\n*** Testing var_dump() on different combinations of scalar + and non-scalar variables ***\n"; /* a variable which is unset */ $unset_var = 10.5; unset($unset_var); @@ -448,9 +448,10 @@ string(29) "abcdn12340567800efgh\xijkl" -- Iteration 13 -- string(34) "abcdefghijklmnop0qrstuvwx0yz" -- Iteration 14 -- -string(22) "1234 +string(22) "1234 5678 - 9100 abcda" + 9100 +abcda" *** Testing var_dump() on boolean variables *** -- Iteration 1 -- @@ -836,8 +837,8 @@ resource(%d) of type (stream) -- Iteration 2 -- resource(%d) of type (stream) -*** Testing var_dump() on different combinations of scalar - and non-scalar variables *** +*** Testing var_dump() on different combinations of scalar + and non-scalar variables *** -- Iteration 1 -- array(3) { [0]=> @@ -1102,9 +1103,10 @@ array(14) { [12]=> string(34) "abcdefghijklmnop0qrstuvwx0yz" [13]=> - string(22) "1234 + string(22) "1234 5678 - 9100 abcda" + 9100 +abcda" } array(15) { [0]=> diff --git a/ext/standard/tests/general_functions/var_dump_64bit.phpt b/ext/standard/tests/general_functions/var_dump_64bit.phpt index 630b1ee8b3168..0600775f589c8 100644 --- a/ext/standard/tests/general_functions/var_dump_64bit.phpt +++ b/ext/standard/tests/general_functions/var_dump_64bit.phpt @@ -99,7 +99,7 @@ $strings = array ( 'PHP', "abcd\x0n1234\x0005678\x0000efgh\xijkl", // strings with hexadecimal NULL "abcd\0efgh\0ijkl\x00mnop\x000qrst\00uvwx\0000yz", // strings with octal NULL - "1234\t\n5678\n\t9100\rabcda" // strings with escape characters + "1234\t\n5678\n\t9100\"abcda" // strings with escape characters ); /* calling check_vardump() to display contents of strings using var_dump() */ @@ -239,8 +239,8 @@ $resources = array ( using var_dump() */ check_vardump($resources); -echo "\n*** Testing var_dump() on different combinations of scalar - and non-scalar variables ***\n"; +echo "\n*** Testing var_dump() on different combinations of scalar + and non-scalar variables ***\n"; /* a variable which is unset */ $unset_var = 10.5; unset($unset_var); @@ -450,7 +450,7 @@ string(34) "abcdefghijklmnop0qrstuvwx0yz" -- Iteration 14 -- string(22) "1234 5678 - 9100 abcda" + 9100"abcda" *** Testing var_dump() on boolean variables *** -- Iteration 1 -- @@ -836,8 +836,8 @@ resource(5) of type (stream) -- Iteration 2 -- resource(6) of type (stream) -*** Testing var_dump() on different combinations of scalar - and non-scalar variables *** +*** Testing var_dump() on different combinations of scalar + and non-scalar variables *** -- Iteration 1 -- array(3) { [0]=> @@ -1104,7 +1104,7 @@ array(14) { [13]=> string(22) "1234 5678 - 9100 abcda" + 9100"abcda" } array(15) { [0]=> diff --git a/ext/standard/tests/strings/bug21453.phpt b/ext/standard/tests/strings/bug21453.phpt index 61547c48f36fb..cf563dfaf3153 100644 --- a/ext/standard/tests/strings/bug21453.phpt +++ b/ext/standard/tests/strings/bug21453.phpt @@ -4,15 +4,15 @@ Bug #21453 (handling of non-encoded <) - first cell before < first cell after - second cell before < second cell after + first cell before < first cell after + second cell before < second cell after "; - var_dump(strip_tags($test)); +var_dump(strip_tags($test)); ?> --EXPECTF-- string(8%d) " - first cell before < first cell after - second cell before < second cell after + first cell before < first cell after + second cell before < second cell after " diff --git a/ext/standard/tests/strings/str_ireplace.phpt b/ext/standard/tests/strings/str_ireplace.phpt index 71a9d1e12791a..a5a35769e47df 100644 --- a/ext/standard/tests/strings/str_ireplace.phpt +++ b/ext/standard/tests/strings/str_ireplace.phpt @@ -36,8 +36,8 @@ var_dump(str_ireplace(array("t"=>"tt", "y"=>"y"), array("a"=>"aaa", "b"=>"bbb"), /* separate testcase for str_ireplace() off-by-one */ $Data = "Change tracking and management software designed to watch - for abnormal system behavior.\nSuggest features, report bugs, or ask - questions here."; + for abnormal system behavior.\nSuggest features, report bugs, or ask + questions here."; var_dump($Data = str_ireplace("\r\n", "
", $Data)); var_dump($Data = str_ireplace("\n", "
", $Data)); @@ -82,9 +82,9 @@ array(2) { ["test"]=> string(36) "aabbbbbbaabbbasdabbbbbbahsdbbbbbbbbb" } -string(143) "Change tracking and management software designed to watch - for abnormal system behavior. +string(149) "Change tracking and management software designed to watch + for abnormal system behavior. Suggest features, report bugs, or ask - questions here." -string(152) "Change tracking and management software designed to watch
for abnormal system behavior.
Suggest features, report bugs, or ask
questions here." + questions here." +string(158) "Change tracking and management software designed to watch
for abnormal system behavior.
Suggest features, report bugs, or ask
questions here." Done diff --git a/ext/standard/tests/strings/str_replace_variation2.phpt b/ext/standard/tests/strings/str_replace_variation2.phpt index 79d50d40ffe8388b176046b16859d229c30069f6..ecda3e3920fef4243c014f1fa4b023743404855b 100644 GIT binary patch delta 648 zcmaExbSP;96Vv2IW%tcqOgotw%_a+KSWUKLvzlDVwgZJ%I$4Ipc`_qU9;=&wsGkc^ zOU-0|PG?2~u#R{9jzE!=$#Q%Wle@V<>f$EraEpRf?c>I#>K6~DXf&e*&@`FJ)A(Y+ zIt%zQ)ksWUBj7xFm59M)1u==q`}tTW+Xxzh?N-p0nEXo61xb!)a+8o2*d$G17c`gp ziNs76&@h;MOT-tfVu`2=(7!K5+b0)_9f7kNC)-P)yTMOHa&nENGo#Vu1Cp1SxHu;_ zYKlx=CzTF#yrQo7WL;?&pcE(=*GPkmPMI7h6Epd}fcs=dSqrdL+hkpUe9y_wa%Mn& z?d0!r&PejLlg$-Ce2K}E6w<-+<%%H7b}KdmdGeFvl$HV=ZaUdQ*#pQwfFhGL*O#ZCx0*)h48WEn{ssr*s h%47xI7%bM5>cIlSj*WftZ#}2UcKS!KsQYbD1OP>0*kb?y delta 751 zcmX?<^fqY&6BDDtb9Kfay6f9@kfyOVLEXm=_XarTGz~<&3 z>gNK|T{GF6(|Ph-5rfGNI&zZ_Na%shOqra=6%AJ|Fj<{j6f9mdc?UOk)e@6G^Wc)v z<8x-TocvK;W^x~2EYzHIeq5>-2{=zqP>`7XLEm(;k)R>eJwJ3LCf^ryfy&rSE*H`Q z%N)S!c8ST6A}*7k3K&d2E8+`QS37ySs53B7Zi}{q`4W?>#MYqkGbigy;Br-#qzh2> zddbVI;GmnNRSWdeLT>TN;?gdY73J+G&yx0pI#obbVsgBU3!@1zwB07ZlCgj~V7{y~ zSj=OxwwxJIEK%+Nikd{Z+R3sCAT@~!bzu40$uWw~jK-4}C^m!5ke|%2mNa>Zk~7e2 zrjuoqJ)o){Dr2hBR7DqCiX*7jsJnn=6f}IG=DpMa1r?fS1%ck0rsd3N28>D7$^W$i z!A`1~d`8;^7!-m!5GSTg{-G0t!y+F&P*6EdzNF{GuD}Hj$H^Btk|u)!Y>Ga_5$LH< JV)6xpA^<^R@~{8^ diff --git a/ext/standard/tests/strings/str_word_count.phpt b/ext/standard/tests/strings/str_word_count.phpt index 480ee5b64a625..fda1678daa63f 100644 --- a/ext/standard/tests/strings/str_word_count.phpt +++ b/ext/standard/tests/strings/str_word_count.phpt @@ -2,7 +2,7 @@ str_word_count() --FILE-- string(6) "you're" - [27]=> + [25]=> string(7) "looking" - [44]=> + [42]=> string(4) "good" - [49]=> + [47]=> string(5) "today" } int(6) @@ -91,7 +91,7 @@ Invalid format value 3 Invalid format value 123 Invalid format value -1 Invalid format value 999999999 -string(55) "Hello friend, you're +string(53) "Hello friend, you're looking good today!" int(5) int(6) diff --git a/ext/standard/tests/strings/strncasecmp_variation9.phpt b/ext/standard/tests/strings/strncasecmp_variation9.phpt index 9841bb4e473b0..caa2deccf282b 100644 --- a/ext/standard/tests/strings/strncasecmp_variation9.phpt +++ b/ext/standard/tests/strings/strncasecmp_variation9.phpt @@ -22,7 +22,7 @@ EOD; $identifier_str1 = <<a%NzCB_YS3pipL|hJ46Kz)h*!`MC|^-orGTtPX|lHv zFP8~W2Chws&jQI*GqcGDg^j^xycFVPMDTot`4BvQLqqI(#6|d!ywnfmnM|H1q7F9i zg$N(3G0wAcFX;I3Ekh?~?_DrND;BNbs>3fCThJ?7#y361=RYV0##aHNhfpCHTb5 qfJ%~*Q(`JGgVRJ(m(38Q0TcsDle;95UG-H`4;~t#n;WE#Z~*`{zLZM< delta 590 zcmZ4Cb;N6fH#4Kcycp1$m2Z+0Y1$>!I3?>OmfZ0lutps_H`O+o|y1HD& zB}JKe=^92BnhHt`1`7GfC5bs)Aj6aH!pmX;vM^rU93muWilo*YRgMqYgXYGQ_lsIW&5;)4VKp@X8RRG;4;9N3 z<7Grva|4C1#BXGPWRnFVT9hX55a(k71v$R75wYNFCt< E0G+9vTmS$7 diff --git a/ext/standard/tests/strings/vfprintf_variation4_64bit.phpt b/ext/standard/tests/strings/vfprintf_variation4_64bit.phpt index fea15a9552f57..c03e38e40cd84 100644 --- a/ext/standard/tests/strings/vfprintf_variation4_64bit.phpt +++ b/ext/standard/tests/strings/vfprintf_variation4_64bit.phpt @@ -20,11 +20,11 @@ echo "*** Testing vfprintf() : int formats and non-integer values ***\n"; // defining array of int formats $formats = - '%d %+d %-d - %ld %Ld %4d %-4d - %10.4d %-10.4d %.4d %04.4d - %\'#2d %\'2d %\'$2d %\'_2d - %3$d %4$d %1$d %2$d'; + '%d %+d %-d + %ld %Ld %4d %-4d + %10.4d %-10.4d %.4d %04.4d + %\'#2d %\'2d %\'$2d %\'_2d + %3$d %4$d %1$d %2$d'; // Arrays of non int values for the format defined in $format. // Each sub array contains non int values which correspond to each format in $format @@ -35,7 +35,8 @@ $args_array = array( 123456.234, 123456.234, -1234.6789, +1234.6789, 2e10, +2e5, 4e3, 22e+6, 12345.780, 12.000000011111, -12.00000111111, -123456.234, - 3.33, +4.44, 1.11,-2.22 ), + 3.33, +4.44, 1.11,-2.22 + ), // array of strings array(" ", ' ', 'hello', @@ -86,26 +87,26 @@ unlink($data_file); *** Testing vfprintf() : int formats and non-integer values *** -- Iteration 1 -- -2 +0 10 - 123456 d -1234 1234 - 20000000000 200000 4000 22000000 - 12345 12 -12 -123456 - 10 123456 2 0 +2 +0 10 + 123456 d -1234 1234 + 20000000000 200000 4000 22000000 + 12345 12 -12 -123456 + 10 123456 2 0 -- Iteration 2 -- -0 +0 0 - 123 d -123 123 - 0 0 123456 0000 - 1234 0 $0 _0 - 0 123 0 0 +0 +0 0 + 123 d -123 123 + 0 0 123456 0000 + 1234 0 $0 _0 + 0 123 0 0 -- Iteration 3 -- -1 +1 1 - 1 d 1 1 - 1 1 1 0001 - #1 1 $1 _1 - 1 1 1 1 +1 +1 1 + 1 d 1 1 + 1 1 1 0001 + #1 1 $1 _1 + 1 1 1 1 -- Iteration 4 -- -1 +1 0 - 1 d 0 1 - 1 0 1 0000 - #0 1 $1 _0 - 0 1 1 1 +1 +1 0 + 1 d 0 1 + 1 0 1 0000 + #0 1 $1 _0 + 0 1 1 1 diff --git a/ext/standard/tests/strings/vprintf_variation4_64bit.phpt b/ext/standard/tests/strings/vprintf_variation4_64bit.phpt index 9172644dd141e..0e5f4d6d6dcd6 100644 --- a/ext/standard/tests/strings/vprintf_variation4_64bit.phpt +++ b/ext/standard/tests/strings/vprintf_variation4_64bit.phpt @@ -21,10 +21,10 @@ echo "*** Testing vprintf() : int formats and non-integer values ***\n"; // defining array of int formats $formats = '%d %+d %-d - %ld %Ld %4d %-4d - %10.4d %-10.4d %.4d %04.4d - %\'#2d %\'2d %\'$2d %\'_2d - %3$d %4$d %1$d %2$d'; + %ld %Ld %4d %-4d + %10.4d %-10.4d %.4d %04.4d + %\'#2d %\'2d %\'$2d %\'_2d + %3$d %4$d %1$d %2$d'; // Arrays of non int values for the format defined in $format. // Each sub array contains non int values which correspond to each format in $format @@ -77,32 +77,32 @@ foreach($args_array as $args) { -- Iteration 1 -- 2 +0 10 - 123456 d -1234 1234 - 20000000000 200000 4000 22000000 - 12345 12 -12 -123456 - 10 123456 2 0 -int(112) + 123456 d -1234 1234 + 20000000000 200000 4000 22000000 + 12345 12 -12 -123456 + 10 123456 2 0 +int(116) -- Iteration 2 -- 0 +0 0 - 123 d -123 123 - 0 0 123456 0000 - 1234 0 $0 _0 - 0 123 0 0 -int(92) + 123 d -123 123 + 0 0 123456 0000 + 1234 0 $0 _0 + 0 123 0 0 +int(96) -- Iteration 3 -- 1 +1 1 - 1 d 1 1 - 1 1 1 0001 - #1 1 $1 _1 - 1 1 1 1 -int(81) + 1 d 1 1 + 1 1 1 0001 + #1 1 $1 _1 + 1 1 1 1 +int(85) -- Iteration 4 -- 1 +1 0 - 1 d 0 1 - 1 0 1 0000 - #0 1 $1 _0 - 0 1 1 1 -int(81) + 1 d 0 1 + 1 0 1 0000 + #0 1 $1 _0 + 0 1 1 1 +int(85) diff --git a/ext/tokenizer/tests/token_get_all_variation18.phpt b/ext/tokenizer/tests/token_get_all_variation18.phpt index 7535d15b1148f..b057856950964 100644 --- a/ext/tokenizer/tests/token_get_all_variation18.phpt +++ b/ext/tokenizer/tests/token_get_all_variation18.phpt @@ -19,12 +19,12 @@ echo "*** Testing token_get_all() : 'source' string with HTML tags ***\n"; $source = ' - Testing HTML + Testing HTML " -'; var_dump( token_get_all($source)); @@ -38,10 +38,10 @@ array(9) { [0]=> int(%d) [1]=> - string(48) " + string(50) " - Testing HTML + Testing HTML " @@ -54,7 +54,8 @@ array(9) { [0]=> int(%d) [1]=> - string(6) " int(8) } @@ -63,10 +64,9 @@ array(9) { [0]=> int(%d) [1]=> - string(3) " - " + string(4) " " [2]=> - int(8) + int(9) } [3]=> array(3) { diff --git a/ext/tokenizer/tests/token_get_all_variation19.phpt b/ext/tokenizer/tests/token_get_all_variation19.phpt index 6f4f7b68b3471..a853dd2e2fc5e 100644 --- a/ext/tokenizer/tests/token_get_all_variation19.phpt +++ b/ext/tokenizer/tests/token_get_all_variation19.phpt @@ -16,16 +16,16 @@ comment */ // a class class TestClass { - public function foo() { - echo "Called foo()\n"; - } + public function foo() { + echo "Called foo()\n"; + } } $a = new TestClass(); $a->foo(); for ($i = 0; $i < 10; $i++) { - echo "Loop iteration $i\n"; + echo "Loop iteration $i\n"; } ?>'; @@ -54,7 +54,7 @@ eval($script); ?> --EXPECT-- -string(259) " +string(274) " // A php script to test token_get_all() @@ -64,16 +64,16 @@ comment */ // a class class TestClass { - public function foo() { - echo "Called foo()\n"; - } + public function foo() { + echo "Called foo()\n"; + } } $a = new TestClass(); $a->foo(); for ($i = 0; $i < 10; $i++) { - echo "Loop iteration $i\n"; + echo "Loop iteration $i\n"; } " From 19222b8581057c05b2516421b6d71144544898a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 31 Jan 2020 18:36:43 +0100 Subject: [PATCH 76/80] Fix var_dump test --- ext/standard/tests/general_functions/var_dump.phpt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/ext/standard/tests/general_functions/var_dump.phpt b/ext/standard/tests/general_functions/var_dump.phpt index 889b2b1fc2bde..476620ff267dc 100644 --- a/ext/standard/tests/general_functions/var_dump.phpt +++ b/ext/standard/tests/general_functions/var_dump.phpt @@ -99,7 +99,7 @@ $strings = array ( 'PHP', "abcd\x0n1234\x0005678\x0000efgh\xijkl", // strings with hexadecimal NULL "abcd\0efgh\0ijkl\x00mnop\x000qrst\00uvwx\0000yz", // strings with octal NULL - "1234\t\n5678\n\t9100\rabcda" // strings with escape characters + "1234\t\n5678\n\t9100\"abcda" // strings with escape characters ); /* calling check_vardump() to display contents of strings using var_dump() */ @@ -448,10 +448,9 @@ string(29) "abcdn12340567800efgh\xijkl" -- Iteration 13 -- string(34) "abcdefghijklmnop0qrstuvwx0yz" -- Iteration 14 -- -string(22) "1234 +string(22) "1234 5678 - 9100 -abcda" + 9100"abcda" *** Testing var_dump() on boolean variables *** -- Iteration 1 -- @@ -1103,10 +1102,9 @@ array(14) { [12]=> string(34) "abcdefghijklmnop0qrstuvwx0yz" [13]=> - string(22) "1234 + string(22) "1234 5678 - 9100 -abcda" + 9100"abcda" } array(15) { [0]=> From b97c9dc72a642bd0fe2e4f59fbb9c0c818addefa Mon Sep 17 00:00:00 2001 From: Pieter Hordijk Date: Fri, 31 Jan 2020 17:46:43 +0300 Subject: [PATCH 77/80] Added opcache extension to inis Extensions are not loaded by default (commented out) Closes GH-5136 --- php.ini-development | 2 ++ php.ini-production | 2 ++ 2 files changed, 4 insertions(+) diff --git a/php.ini-development b/php.ini-development index b01e88eb940b1..f69f06aa3d6f6 100644 --- a/php.ini-development +++ b/php.ini-development @@ -934,6 +934,8 @@ default_socket_timeout = 60 ;extension=xmlrpc ;extension=xsl +;zend_extension=opcache + ;;;;;;;;;;;;;;;;;;; ; Module Settings ; ;;;;;;;;;;;;;;;;;;; diff --git a/php.ini-production b/php.ini-production index 22acf05e6b865..306d0aefa0a10 100644 --- a/php.ini-production +++ b/php.ini-production @@ -936,6 +936,8 @@ default_socket_timeout = 60 ;extension=xmlrpc ;extension=xsl +;zend_extension=opcache + ;;;;;;;;;;;;;;;;;;; ; Module Settings ; ;;;;;;;;;;;;;;;;;;; From 2127a37b833a863e28a4692e7394613b89c89290 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 1 Feb 2020 07:03:13 +0100 Subject: [PATCH 78/80] Bison: enable all the warnings and fix them First, fix 5547d361208d90e12d53bb62bb2ffbbff9b93ca0: the definition of YFLAGS was not passed into the Makefile: AC_SUBST does not suffice, we need PHP_SUBST_OLD. While at it, allow to pass variable and value at the same time. Then pass -Wall to bison, rather than only -Wempty-rules. Use %precedence where associativity is useless. Remove useless %precedence. GH-5138 --- Zend/zend_ini_parser.y | 2 +- Zend/zend_language_parser.y | 2 +- build/php.m4 | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 9e350664ba1fb..6b69aec7d9136 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -309,7 +309,7 @@ static void zval_ini_dtor(zval *zv) %token END_OF_LINE %token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}' %left '|' '&' '^' -%right '~' '!' +%precedence '~' '!' %destructor { zval_ini_dtor(&$$); } TC_RAW TC_CONSTANT TC_NUMBER TC_STRING TC_WHITESPACE TC_LABEL TC_OFFSET TC_VARNAME BOOL_TRUE BOOL_FALSE NULL_NULL cfg_var_ref constant_literal constant_string encapsed_list expr option_offset section_string_or_value string_or_value var_string_list var_string_list_section diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 4fe6f77bb1662..2f7b772c8b8fc 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -79,7 +79,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %precedence T_INSTANCEOF %precedence '~' T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@' %right T_POW -%precedence T_NEW T_CLONE +%precedence T_CLONE /* Resolve danging else conflict */ %precedence T_NOELSE diff --git a/build/php.m4 b/build/php.m4 index 87527f43813cf..8cdfb4da518c1 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -81,7 +81,7 @@ AC_DEFUN([PHP_DEFINE],[ dnl dnl PHP_SUBST(varname) dnl -dnl Adds variable with it's value into Makefile, e.g.: +dnl Adds variable with its value into Makefile, e.g.: dnl CC = gcc dnl AC_DEFUN([PHP_SUBST],[ @@ -89,14 +89,14 @@ AC_DEFUN([PHP_SUBST],[ ]) dnl -dnl PHP_SUBST_OLD(varname) +dnl PHP_SUBST_OLD(varname, [VALUE]) dnl dnl Same as PHP_SUBST() but also substitutes all @VARNAME@ instances in every dnl file passed to AC_OUTPUT. dnl AC_DEFUN([PHP_SUBST_OLD],[ - PHP_SUBST($1) - AC_SUBST($1) + AC_SUBST($@) + PHP_SUBST([$1]) ]) dnl @@ -1815,7 +1815,7 @@ AC_DEFUN([PHP_PROG_BISON], [ done if test "$php_bison_check" != "invalid"; then - AC_SUBST([YFLAGS], [-Wempty-rule]) + PHP_SUBST_OLD([YFLAGS], [-Wall]) AC_MSG_RESULT([$php_bison_version (ok)]) else AC_MSG_RESULT([$php_bison_version]) From 4cbffd89d9e82d81a26746aadca27ad061cab43a Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 1 Feb 2020 07:07:28 +0100 Subject: [PATCH 79/80] Clean up the generation of the parsers Prefer '%define api.value.type' to '#define YYSTYPE', so that Bison know the type. Use '%code requires' to declare what is needed to define the api.value.type (that code is output in the generated header before the generated definition of YYSTYPE). Prefer '%define api.prefix' inside the grammar file to '-p' outside, as anyway the functions defined in the file actually use this prefix. Prefer `%param` to both `%parse-param` and `%lex-param`. Closes GH-5138 --- Zend/Makefile.frag | 4 ++-- Zend/zend_ini_parser.y | 4 ++-- Zend/zend_language_parser.y | 15 +++++++-------- ext/json/json_parser.y | 5 ++--- sapi/phpdbg/Makefile.frag | 2 +- sapi/phpdbg/phpdbg_cmd.h | 4 ---- sapi/phpdbg/phpdbg_parser.y | 25 ++++++++++++------------- win32/build/Makefile | 6 +++--- 8 files changed, 29 insertions(+), 36 deletions(-) diff --git a/Zend/Makefile.frag b/Zend/Makefile.frag index 2f3c2d948d67d..4160fe2b5ec45 100644 --- a/Zend/Makefile.frag +++ b/Zend/Makefile.frag @@ -13,7 +13,7 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y # Tweak zendparse to be exported through ZEND_API. This has to be revisited once # bison supports foreign skeletons and that bison version is used. Read # https://git.savannah.gnu.org/cgit/bison.git/tree/data/README.md for more. - @$(YACC) $(YFLAGS) -p zend -v -d $(srcdir)/zend_language_parser.y -o $@ + @$(YACC) $(YFLAGS) -v -d $(srcdir)/zend_language_parser.y -o $@ @$(SED) -e 's,^int zendparse\(.*\),ZEND_API int zendparse\1,g' < $@ \ > $@.tmp && \ mv $@.tmp $@ @@ -27,7 +27,7 @@ $(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y $(srcdir)/zend_ini_parser.h: $(srcdir)/zend_ini_parser.c $(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y - @$(YACC) $(YFLAGS) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@ + $(YACC) $(YFLAGS) -v -d $(srcdir)/zend_ini_parser.y -o $@ $(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l) diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 6b69aec7d9136..a204496a357be 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -32,8 +32,6 @@ #include "win32/syslog.h" #endif -#define YYSTYPE zval - int ini_parse(void); #define ZEND_INI_PARSER_CB (CG(ini_parser_param))->ini_parser_cb @@ -289,7 +287,9 @@ static void zval_ini_dtor(zval *zv) %} %expect 0 +%define api.prefix {ini_} %define api.pure full +%define api.value.type {zval} %define parse.error verbose %token TC_SECTION diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 2f7b772c8b8fc..078c863c4ee6f 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -1,5 +1,4 @@ %require "3.0" -%{ /* +----------------------------------------------------------------------+ | Zend Engine | @@ -20,7 +19,7 @@ +----------------------------------------------------------------------+ */ -#include "zend_compile.h" +%code top { #include "zend.h" #include "zend_list.h" #include "zend_globals.h" @@ -33,22 +32,22 @@ #define yytnamerr zend_yytnamerr static YYSIZE_T zend_yytnamerr(char*, const char*); -#define YYSTYPE zend_parser_stack_elem - #ifdef _MSC_VER #define YYMALLOC malloc #define YYFREE free #endif +} -%} +%code requires { +#include "zend_compile.h" +} +%define api.prefix {zend} %define api.pure full +%define api.value.type {zend_parser_stack_elem} %define parse.error verbose %expect 0 -%code requires { -} - %destructor { zend_ast_destroy($$); } %destructor { if ($$) zend_string_release_ex($$, 0); } diff --git a/ext/json/json_parser.y b/ext/json/json_parser.y index 833a772807c31..4705e498a6173 100644 --- a/ext/json/json_parser.y +++ b/ext/json/json_parser.y @@ -41,10 +41,9 @@ int json_yydebug = 1; } -%define api.pure full %define api.prefix {php_json_yy} -%lex-param { php_json_parser *parser } -%parse-param { php_json_parser *parser } +%define api.pure full +%param { php_json_parser *parser } %union { zval value; diff --git a/sapi/phpdbg/Makefile.frag b/sapi/phpdbg/Makefile.frag index 448cc3676b6a1..1572bfd9f078e 100644 --- a/sapi/phpdbg/Makefile.frag +++ b/sapi/phpdbg/Makefile.frag @@ -18,7 +18,7 @@ $(srcdir)/phpdbg_lexer.c: $(srcdir)/phpdbg_lexer.l $(srcdir)/phpdbg_parser.h: $(srcdir)/phpdbg_parser.c $(srcdir)/phpdbg_parser.c: $(srcdir)/phpdbg_parser.y - @$(YACC) $(YFLAGS) -p phpdbg_ -v -d $(srcdir)/phpdbg_parser.y -o $@ + @$(YACC) $(YFLAGS) -v -d $(srcdir)/phpdbg_parser.y -o $@ install-phpdbg: $(BUILD_BINARY) @echo "Installing phpdbg binary: $(INSTALL_ROOT)$(bindir)/" diff --git a/sapi/phpdbg/phpdbg_cmd.h b/sapi/phpdbg/phpdbg_cmd.h index 56c8681c59792..dd80e61db3a0b 100644 --- a/sapi/phpdbg/phpdbg_cmd.h +++ b/sapi/phpdbg/phpdbg_cmd.h @@ -81,10 +81,6 @@ struct _phpdbg_param { (v)->top = NULL; \ } while(0) -#ifndef YYSTYPE -#define YYSTYPE phpdbg_param_t -#endif - #define PHPDBG_ASYNC_SAFE 1 typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*); diff --git a/sapi/phpdbg/phpdbg_parser.y b/sapi/phpdbg/phpdbg_parser.y index 1384abe6fb78e..f776586810994 100644 --- a/sapi/phpdbg/phpdbg_parser.y +++ b/sapi/phpdbg/phpdbg_parser.y @@ -1,19 +1,24 @@ %require "3.0" -%{ - /* * phpdbg_parser.y * (from php-src root) */ +%code requires { #include "phpdbg.h" +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif +} + +%code { + #include "phpdbg_cmd.h" #include "phpdbg_utils.h" #include "phpdbg_cmd.h" #include "phpdbg_prompt.h" -#define YYSTYPE phpdbg_param_t - #include "phpdbg_parser.h" #include "phpdbg_lexer.h" @@ -27,19 +32,13 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg) #define YYFREE free #endif -%} +} +%define api.prefix {phpdbg_} %define api.pure full +%define api.value.type {phpdbg_param_t} %define parse.error verbose -%code requires { -#include "phpdbg.h" -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif -} - %token T_EVAL "eval" %token T_RUN "run" %token T_SHELL "shell" diff --git a/win32/build/Makefile b/win32/build/Makefile index a6b54c07ff3d9..d0315f41c4be6 100644 --- a/win32/build/Makefile +++ b/win32/build/Makefile @@ -75,16 +75,16 @@ $(BUILD_DIR)\$(PHPDLL).def: $(PHP_DLL_DEF_SOURCES) type $(PHP_DLL_DEF_SOURCES) > $(BUILD_DIR)\$(PHPDLL).def Zend\zend_ini_parser.c Zend\zend_ini_parser.h: Zend\zend_ini_parser.y - $(BISON) --output=Zend/zend_ini_parser.c -v -d -p ini_ Zend/zend_ini_parser.y + $(BISON) --output=Zend/zend_ini_parser.c -v -d Zend/zend_ini_parser.y Zend\zend_language_parser.c Zend\zend_language_parser.h: Zend\zend_language_parser.y - $(BISON) --output=Zend/zend_language_parser.c -v -d -p zend Zend/zend_language_parser.y + $(BISON) --output=Zend/zend_language_parser.c -v -d Zend/zend_language_parser.y @if "$(SED)" neq "" $(SED) -i "s,^int zendparse\(.*\),ZEND_API int zendparse\1,g" Zend/zend_language_parser.c @if "$(SED)" neq "" $(SED) -i "s,^int zendparse\(.*\),ZEND_API int zendparse\1,g" Zend/zend_language_parser.h @if "$(SED)" neq "" $(SED) -i "s,^#ifndef YYTOKENTYPE,#include \"zend.h\"\n#ifndef YYTOKENTYPE,g" Zend/zend_language_parser.h sapi\phpdbg\phpdbg_parser.c sapi\phpdbg\phpdbg_parser.h: sapi\phpdbg\phpdbg_parser.y - $(BISON) --output=sapi/phpdbg/phpdbg_parser.c -v -d -p phpdbg_ sapi/phpdbg/phpdbg_parser.y + $(BISON) --output=sapi/phpdbg/phpdbg_parser.c -v -d sapi/phpdbg/phpdbg_parser.y !if $(RE2C) != "" Zend\zend_ini_scanner.c: Zend\zend_ini_scanner.l From 096c2ff40cadf75c0295d81b54b372168f36700d Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Fri, 24 Jan 2020 20:58:39 -0500 Subject: [PATCH 80/80] [POC] Support calling functions from constant expressions I can think of two main approaches to adding function call support to PHP. This implements the latter. 1. Only allow functions that are actually deterministic and don't depend on ini settings to be used in constant declarations. For example, allow `\count()`, `\strlen()`, `\array_merge()`, and `\in_array()`, but possibly don't allow functions such as `strtolower()` (different in Turkish locale), sprintf() (Depends on `ini_get('precision')`, but so does `(string)EXPR`), `json_encode()` (The `json` extension can be disabled), or calls which aren't unambiguously resolved with `\` or `use function`. 2. Allow any function (user-defined or internal) to be called, leave it to coding practice guidelines to assert that constants are only used in safe ways. ------- - This POC can handle fully qualified, namespace relative, and not-FQ calls. - Argument unpacking is supported - It turns out parameter defaults evaluate some constants every time, depending on whether the PHP value is immutable. Possible solutions: 1. Permanently resolve parameter defaults for expressions containing function calls, which can be more expensive than evaluating a regular constant AST. 2. Permanently resolve expressions in parameter defaults 3. Don't start allowing calls in parameter defaults - This handles recursive definitions. It throws if a function call being evaluated ends up reaching the same call. - Static calls with known classes (other than static::) are probably easy to implement. - This also constrains function return values to be valid constants, (i.e. they can be the same values that define() would accept) and throws an error otherwise. In the future, `const X = [my_call()->x];` may be possible. - Variables aren't supported, because they depend on the declaration's scope, which may cease to exist. - TODO: Forbid backtick string syntax for shell_exec, which gets converted to a ZEND_AST_CALL node. ------- It turns out that function calls can already be invoked when evaluating a constant, e.g. from php's error handler. So it seems viable for PHP's engine to support regular calls, which this POC attempts to do. (Imagine an error handler defining SOME_DYNAMIC_CONST123 to be a dynamic value if a notice is emitted) for the expression `const X = [[]['undefined_index'], SOME_DYNAMIC_CONST123][1];` --- Zend/tests/call_in_const/class_const01.phpt | 15 ++ Zend/tests/call_in_const/class_const02.phpt | 37 ++++ Zend/tests/call_in_const/global_const01.phpt | 10 + Zend/tests/call_in_const/global_const02.phpt | 14 ++ Zend/tests/call_in_const/param_defaults.phpt | 24 +++ Zend/tests/call_in_const/param_ref.phpt | 25 +++ .../call_in_const/property_default01.phpt | 36 ++++ Zend/tests/call_in_const/recursion.phpt | 40 ++++ .../tests/call_in_const/static_default01.phpt | 14 ++ .../tests/call_in_const/static_default02.phpt | 20 ++ .../tests/call_in_const/static_default03.phpt | 19 ++ Zend/tests/call_in_const/too_few.phpt | 22 +++ Zend/tests/call_in_const/varargs.phpt | 14 ++ Zend/zend.c | 7 +- Zend/zend_ast.c | 187 ++++++++++++++++++ Zend/zend_builtin_functions.c | 2 +- Zend/zend_builtin_functions.h | 1 + Zend/zend_compile.c | 25 ++- Zend/zend_globals.h | 1 + 19 files changed, 510 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/call_in_const/class_const01.phpt create mode 100644 Zend/tests/call_in_const/class_const02.phpt create mode 100644 Zend/tests/call_in_const/global_const01.phpt create mode 100644 Zend/tests/call_in_const/global_const02.phpt create mode 100644 Zend/tests/call_in_const/param_defaults.phpt create mode 100644 Zend/tests/call_in_const/param_ref.phpt create mode 100644 Zend/tests/call_in_const/property_default01.phpt create mode 100644 Zend/tests/call_in_const/recursion.phpt create mode 100644 Zend/tests/call_in_const/static_default01.phpt create mode 100644 Zend/tests/call_in_const/static_default02.phpt create mode 100644 Zend/tests/call_in_const/static_default03.phpt create mode 100644 Zend/tests/call_in_const/too_few.phpt create mode 100644 Zend/tests/call_in_const/varargs.phpt diff --git a/Zend/tests/call_in_const/class_const01.phpt b/Zend/tests/call_in_const/class_const01.phpt new file mode 100644 index 0000000000000..4d46f3a15f064 --- /dev/null +++ b/Zend/tests/call_in_const/class_const01.phpt @@ -0,0 +1,15 @@ +--TEST-- +Can call internal functions from class constants +--FILE-- + +--EXPECT-- +X is Hello, World diff --git a/Zend/tests/call_in_const/class_const02.phpt b/Zend/tests/call_in_const/class_const02.phpt new file mode 100644 index 0000000000000..53caf366bc7a2 --- /dev/null +++ b/Zend/tests/call_in_const/class_const02.phpt @@ -0,0 +1,37 @@ +--TEST-- +Can call internal functions from class constants +--FILE-- + $value) { + $result["prefix_$k"] = $value; + } + return $result; +} +class Example { + const X = [ + 'key1' => 'value1', + 'key2' => 'value2', + ]; + const Y = array_flip(self::X); + const Z = normalize_keys(self::Y); +} +var_export(Example::Z); +var_export(Example::Z); +var_export(Example::Y); +?> +--EXPECT-- +Normalizing the keys +array ( + 'prefix_value1' => 'key1', + 'prefix_value2' => 'key2', +)array ( + 'prefix_value1' => 'key1', + 'prefix_value2' => 'key2', +)array ( + 'value1' => 'key1', + 'value2' => 'key2', +) diff --git a/Zend/tests/call_in_const/global_const01.phpt b/Zend/tests/call_in_const/global_const01.phpt new file mode 100644 index 0000000000000..11e3653ab9596 --- /dev/null +++ b/Zend/tests/call_in_const/global_const01.phpt @@ -0,0 +1,10 @@ +--TEST-- +Can call internal functions from global constants +--FILE-- + +--EXPECT-- +NIL is NULL diff --git a/Zend/tests/call_in_const/global_const02.phpt b/Zend/tests/call_in_const/global_const02.phpt new file mode 100644 index 0000000000000..f72aa7f665ea3 --- /dev/null +++ b/Zend/tests/call_in_const/global_const02.phpt @@ -0,0 +1,14 @@ +--TEST-- +Cannot declare constants with function calls that contain objects +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Calls in constants may only evaluate to scalar values, arrays or resources in %s:5 +Stack trace: +#0 {main} + thrown in %s on line 5 diff --git a/Zend/tests/call_in_const/param_defaults.phpt b/Zend/tests/call_in_const/param_defaults.phpt new file mode 100644 index 0000000000000..974ea652bfa12 --- /dev/null +++ b/Zend/tests/call_in_const/param_defaults.phpt @@ -0,0 +1,24 @@ +--TEST-- +Can call internal functions from parameter default +--FILE-- + +--EXPECT-- +Evaluating default +x is Dynamic default +x is 2 +Evaluating default +x is Dynamic default \ No newline at end of file diff --git a/Zend/tests/call_in_const/param_ref.phpt b/Zend/tests/call_in_const/param_ref.phpt new file mode 100644 index 0000000000000..ba317c5e977fb --- /dev/null +++ b/Zend/tests/call_in_const/param_ref.phpt @@ -0,0 +1,25 @@ +--TEST-- +Warn when calling function expecting a reference as an argument +--INI-- +error_reporting=E_ALL +--FILE-- + +--EXPECT-- +Start +log_call(true) +log_call(array ( + 0 => 1, + 1 => 2, +)) +true +array ( + 0 => 1, + 1 => 2, +) +true +New value diff --git a/Zend/tests/call_in_const/recursion.phpt b/Zend/tests/call_in_const/recursion.phpt new file mode 100644 index 0000000000000..3806b13b96143 --- /dev/null +++ b/Zend/tests/call_in_const/recursion.phpt @@ -0,0 +1,40 @@ +--TEST-- +Recursion in calls in class constants causes an error +--FILE-- +getMessage()); +} +try { + echo "Recursion::X=" . Recursion::X . "\n"; +} catch (Error $e) { + printf("Second call caught %s: %s\n", get_class($e), $e->getMessage()); +} +try { + echo "Recursion::MISSING=" . Recursion::MISSING; +} catch (Error $e) { + printf("Caught %s: %s\n", get_class($e), $e->getMessage()); +} +try { + echo "Recursion::MISSING=" . Recursion::MISSING; +} catch (Error $e) { + printf("Second call caught %s: %s\n", get_class($e), $e->getMessage()); +} +?> +--EXPECT-- +Computing X + 1 +Caught Error: Unrecoverable error calling x_plus_1() in recursive constant definition +Computing X + 1 +Second call caught Error: Unrecoverable error calling x_plus_1() in recursive constant definition +Caught Error: Undefined constant 'MISSING_GLOBAL' +Second call caught Error: Undefined constant 'MISSING_GLOBAL' \ No newline at end of file diff --git a/Zend/tests/call_in_const/static_default01.phpt b/Zend/tests/call_in_const/static_default01.phpt new file mode 100644 index 0000000000000..d354e72ee98ef --- /dev/null +++ b/Zend/tests/call_in_const/static_default01.phpt @@ -0,0 +1,14 @@ +--TEST-- +Can call internal functions from defaults of static variables +--FILE-- + +--EXPECT-- +Hello, World! +Hello, World! diff --git a/Zend/tests/call_in_const/static_default02.phpt b/Zend/tests/call_in_const/static_default02.phpt new file mode 100644 index 0000000000000..15e8cb70ab133 --- /dev/null +++ b/Zend/tests/call_in_const/static_default02.phpt @@ -0,0 +1,20 @@ +--TEST-- +Can call user-defined functions from defaults of static variables +--FILE-- + +--EXPECT-- +log_call('Hello, World') +Hello, World +Hello, World diff --git a/Zend/tests/call_in_const/static_default03.phpt b/Zend/tests/call_in_const/static_default03.phpt new file mode 100644 index 0000000000000..06b034a9e7674 --- /dev/null +++ b/Zend/tests/call_in_const/static_default03.phpt @@ -0,0 +1,19 @@ +--TEST-- +Can call internal functions from defaults of static variables +--FILE-- +getMessage(), $e->getLine()); + } +} +?> +--EXPECT-- +Caught Error: Call to undefined function missing_sprintf() at line 3 +Caught Error: Call to undefined function missing_sprintf() at line 3 diff --git a/Zend/tests/call_in_const/too_few.phpt b/Zend/tests/call_in_const/too_few.phpt new file mode 100644 index 0000000000000..3e544e1a2f8cc --- /dev/null +++ b/Zend/tests/call_in_const/too_few.phpt @@ -0,0 +1,22 @@ +--TEST-- +ArgumentCountError thrown if constant contains call with too few arguments +--FILE-- +getMessage(), $e->getLine()); + } +} +?> +--EXPECT-- +Caught sprintf() expects at least 1 parameter, 0 given on line 6 +Caught sprintf() expects at least 1 parameter, 0 given on line 6 diff --git a/Zend/tests/call_in_const/varargs.phpt b/Zend/tests/call_in_const/varargs.phpt new file mode 100644 index 0000000000000..45b6fde2a874b --- /dev/null +++ b/Zend/tests/call_in_const/varargs.phpt @@ -0,0 +1,14 @@ +--TEST-- +Allow varargs in calls in constants +--INI-- +error_reporting=E_ALL +--FILE-- +child[0]; + if (func_name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(func_name_ast)) != IS_STRING) { + /* Impossible */ + zend_throw_error(NULL, "Unsupported constant expression for function call name"); + return FAILURE; + } + func_name = zend_ast_get_zval(func_name_ast); + fname = Z_STR_P(func_name); + arg_list_ast = zend_ast_get_list(ast->child[1]); + arg_count = arg_list_ast->children; + capacity = arg_count; + args = emalloc(capacity * sizeof(zval)); + + for (i = 0; i < arg_list_ast->children; i++) { + zend_ast *elem = arg_list_ast->child[i]; + // fprintf(stderr, "elem->kind=%d\n", (int)elem->kind); + if (elem->kind == ZEND_AST_UNPACK) { + HashTable *ht; + zval expr; + zval *val; + zend_string *key; + /* evaluate expr of ...expr */ + if (UNEXPECTED(zend_ast_evaluate(&expr, elem->child[0], scope) != SUCCESS)) { + goto call_failure; + } + if (UNEXPECTED(Z_TYPE(expr) != IS_ARRAY)) { + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked"); + zval_ptr_dtor(&expr); + goto call_failure; + } + ht = Z_ARRVAL(expr); + if (zend_hash_num_elements(ht) > 1) { + capacity += zend_hash_num_elements(ht) - 1; + args = erealloc(args, capacity * sizeof(zval)); + } + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if (key) { + zend_throw_error(NULL, "Cannot unpack array with string keys"); + zval_ptr_dtor(&expr); + goto call_failure; + } else { + ZVAL_COPY(&args[param_count], val); + param_count++; + } + } ZEND_HASH_FOREACH_END(); + zval_ptr_dtor(&expr); + continue; + } + // XXX what is the scope + if (UNEXPECTED(zend_ast_evaluate(&args[param_count], elem, scope) != SUCCESS)) { +call_failure: + for (j = 0; j < param_count; j++) { + zval_ptr_dtor_nogc(&args[j]); + } + efree(args); + return FAILURE; + } + param_count++; + } + /* Based on INIT_FCALL - TODO: Any issues with the backtrace varying based on when this gets used? */ + fname_lower = zend_string_tolower(fname); + // fprintf(stderr, "Looking up '%s' attr=%d\n", ZSTR_VAL(fname), (int)func_name_ast->attr); + func = zend_hash_find(EG(function_table), fname_lower); + if (func == NULL && func_name_ast->attr == ZEND_NAME_NOT_FQ) { + /* If NS\fn_name() couldn't be found, try fn_name() */ + const char *after_ns = zend_memrchr(ZSTR_VAL(fname_lower), '\\', ZSTR_LEN(fname_lower)); + if (after_ns) { + after_ns += 1; + zend_string *old_fname_lower = fname_lower; + fname_lower = zend_string_init(after_ns, (ZSTR_VAL(old_fname_lower) + ZSTR_LEN(old_fname_lower)) - after_ns, 0); + zend_string_release(old_fname_lower); + + // fprintf(stderr, "Looking up '%s' as fallback\n", ZSTR_VAL(fname_lower)); + func = zend_hash_find(EG(function_table), fname_lower); + // fprintf(stderr, "Found %llx\n", (long long)func); + } + } + // fprintf(stderr, "Going to call %s()\n", ZSTR_VAL(fname)); + if (UNEXPECTED(func == NULL)) { + zend_throw_error(NULL, "Call to undefined function %s()", ZSTR_VAL(fname)); + zend_string_release(fname_lower); + ret = FAILURE; + } else { + zval result_copy; + ZVAL_NULL(&result_copy); + /* TODO: Handle case where pointers are longer than zend_ulong */ + /* NOTE: This uses a hash table because cannot and shouldn't modify the bytes of ast when opcache is enabled - the memory is protected */ + if (zend_hash_index_add_ptr(CG(active_calls_in_constants), (zend_ulong) ast, ast) == NULL) { + zend_string_release(fname_lower); + /* XXX should there be a way to recover from this error? */ + /* XXX PHP converts constants with errors to null? */ + zend_throw_error(NULL, "Unrecoverable error calling %s() in recursive constant definition", ZSTR_VAL(fname)); + ret = FAILURE; + } else { + zval resolved_func_name_zv; + ZVAL_STR(&resolved_func_name_zv, fname_lower); + ret = call_user_function(CG(function_table), NULL, &resolved_func_name_zv, &result_copy, param_count, args); + zval_ptr_dtor(&resolved_func_name_zv); + if (EG(exception)) { + ret = FAILURE; + } + zend_hash_index_del(CG(active_calls_in_constants), (zend_ulong) ast); + } + + if (ret != FAILURE) { + switch (Z_TYPE(result_copy)) { + case IS_LONG: + case IS_DOUBLE: + case IS_STRING: + case IS_FALSE: + case IS_TRUE: + case IS_NULL: + case IS_RESOURCE: + *result = result_copy; + break; + case IS_ARRAY: + if (Z_REFCOUNTED_P(&result_copy)) { + if (!validate_constant_array_or_throw(Z_ARRVAL(result_copy))) { + ret = FAILURE; + } else { + /* Recursively copy arrays and replace references with values */ + copy_constant_array(result, &result_copy); + zval_ptr_dtor(&result_copy); + } + } else { + *result = result_copy; + } + break; + default: + zend_throw_error(NULL, "Calls in constants may only evaluate to scalar values, arrays or resources"); + ret = FAILURE; + break; + } + } + if (ret == FAILURE) { + zval_ptr_dtor_nogc(&result_copy); + } + } + for (j = 0; j < param_count; j++) { + zval_ptr_dtor_nogc(&args[j]); + } + efree(args); + // FIXME validate that the result is a constant AST and throw if it isn't. + break; + } default: zend_throw_error(NULL, "Unsupported constant expression"); ret = FAILURE; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 80651a880e606..4fdb2540ebd25 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -590,7 +590,7 @@ static int validate_constant_array(HashTable *ht) /* {{{ */ } /* }}} */ -static void copy_constant_array(zval *dst, zval *src) /* {{{ */ +void copy_constant_array(zval *dst, zval *src) /* {{{ */ { zend_string *key; zend_ulong idx; diff --git a/Zend/zend_builtin_functions.h b/Zend/zend_builtin_functions.h index cfc347ed41ffc..8bcc23a0f69b8 100644 --- a/Zend/zend_builtin_functions.h +++ b/Zend/zend_builtin_functions.h @@ -21,6 +21,7 @@ #define ZEND_BUILTIN_FUNCTIONS_H int zend_startup_builtin_functions(void); +void copy_constant_array(zval *dst, zval *src); BEGIN_EXTERN_C() ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int options, int limit); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2295b55e39a0c..9cc84dea61ce6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8521,7 +8521,9 @@ void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */ } if (!zend_is_allowed_in_const_expr(ast->kind)) { - zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations"); + if (ast->kind != ZEND_AST_ARG_LIST && ast->kind != ZEND_AST_CALL) { + zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations"); + } } switch (ast->kind) { @@ -8537,6 +8539,27 @@ void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */ case ZEND_AST_MAGIC_CONST: zend_compile_const_expr_magic_const(ast_ptr); break; + case ZEND_AST_CALL: + { + zend_bool is_fully_qualified; + zval *original_zv; + zend_string *original_name; + zend_string *resolved_name; + zend_ast *func_name_ast = ast->child[0]; + if (func_name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(func_name_ast)) != IS_STRING) { + zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid name for function call"); + } + original_zv = zend_ast_get_zval(func_name_ast); + original_name = Z_STR_P(original_zv); + resolved_name = zend_resolve_function_name(original_name, func_name_ast->attr, &is_fully_qualified); + // fprintf(stderr, "original_name=%s resolved_name=%s attr=%d is_fully_qualified=%d\n", ZSTR_VAL(original_name), ZSTR_VAL(resolved_name), (int)ast->child[0]->attr, (int)is_fully_qualified); + Z_STR_P(original_zv) = resolved_name; + zend_string_release(original_name); + func_name_ast->attr = is_fully_qualified ? ZEND_NAME_FQ : ZEND_NAME_NOT_FQ; + + zend_ast_apply(ast->child[1], zend_compile_const_expr); + break; + } default: zend_ast_apply(ast, zend_compile_const_expr); break; diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 2dc769a5efe17..5dbd5ba4250ec 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -129,6 +129,7 @@ struct _zend_compiler_globals { HashTable *delayed_autoloads; uint32_t rtd_key_counter; + HashTable *active_calls_in_constants; /* avoid recursive function calls */ };