From 5ec8b65acbea4dbc239d88a9c51be38b2254d542 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Thu, 27 Sep 2018 09:34:53 +0200 Subject: [PATCH 01/50] Fixed return types for getReorderingMode() and getReorderingOptions(). --- ext/intl/bidi/bidi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 5d9d696ad1d48..e4ac71142c901 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -185,7 +185,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getReorderingMode) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_BOOL(ubidi_getReorderingMode(objval->bidi)); + RETURN_LONG(ubidi_getReorderingMode(objval->bidi)); } /* }}} */ @@ -212,7 +212,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getReorderingOptions) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_BOOL(ubidi_getReorderingOptions(objval->bidi)); + RETURN_LONG(ubidi_getReorderingOptions(objval->bidi)); } /* }}} */ From 873fb9de49e7c54a7263f96554901d1c3e8aafa3 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Thu, 27 Sep 2018 09:41:22 +0200 Subject: [PATCH 02/50] Added embeddingLevels to IntlBidi::setPara() --- ext/intl/bidi/bidi.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index e4ac71142c901..b050b8ded47f3 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -29,6 +29,7 @@ static zend_object_handlers bidi_object_handlers; typedef struct _php_intl_bidi_object { UBiDi *bidi; + UBiDiLevel *embeddingLevels; UChar *prologue, *text, *epilogue; intl_error error; zend_object std; @@ -99,6 +100,8 @@ static PHP_METHOD(IntlBidi, __construct) { } } + objval->embeddingLevels = NULL; + error = U_ZERO_ERROR; objval->bidi = ubidi_openSized(maxLength, maxRunCount, &error); if (U_FAILURE(error)) { @@ -284,20 +287,22 @@ static PHP_METHOD(IntlBidi, setContext) { /* }}} */ #endif /* ICU >= 4.8 */ -/* {{{ proto self IntlBidi::setPara(string $paragraph[, int $paraLevel = IntlBidi::DEFAULT_LTR]) */ +/* {{{ proto self IntlBidi::setPara(string $paragraph[, int $paraLevel = IntlBidi::DEFAULT_LTR[, string $embeddingLevels]]) */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_setpara_arginfo, ZEND_RETURN_VALUE, 1, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, paragraph, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, paraLevel, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, embeddingLevels, IS_STRING, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, setPara) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); zend_string *para; + zend_string *embeddingLevels = NULL; UChar *upara = NULL; int32_t upara_len = 0; zend_long paraLevel = UBIDI_DEFAULT_LTR; UErrorCode error; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S|l", ¶, ¶Level) == FAILURE) { + if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S|l", ¶, ¶Level, &embeddingLevels) == FAILURE) { return; } @@ -308,9 +313,21 @@ static PHP_METHOD(IntlBidi, setPara) { goto setPara_cleanup; } + // TODO: maybe check for the length of the embeddingLevels. + if (embeddingLevels != NULL && ZSTR_LEN(embeddingLevels) > 0) { + if (objval->embeddingLevels != NULL) { + objval->embeddingLevels = (UBiDiLevel*)erealloc(objval->embeddingLevels, ZSTR_LEN(embeddingLevels)); + } else { + objval->embeddingLevels = (UBiDiLevel*)emalloc(ZSTR_LEN(embeddingLevels)); + } + memcpy(objval->embeddingLevels, ZSTR_VAL(embeddingLevels), ZSTR_LEN(embeddingLevels)); + } else { + efree(objval->embeddingLevels); + objval->embeddingLevels = NULL; + } + error = U_ZERO_ERROR; - /* TODO: embeddingLevels */ - ubidi_setPara(objval->bidi, upara, upara_len, (UBiDiLevel)paraLevel, NULL, &error); + ubidi_setPara(objval->bidi, upara, upara_len, (UBiDiLevel)paraLevel, objval->embeddingLevels, &error); if (U_FAILURE(error)) { THROW_UFAILURE(objval, "setPara", error); goto setPara_cleanup; @@ -851,6 +868,7 @@ static void bidi_object_dtor(zend_object *obj) { if (objval->prologue) { efree(objval->prologue); } if (objval->text) { efree(objval->text); } if (objval->epilogue) { efree(objval->epilogue); } + if (objval->embeddingLevels) { efree(objval->embeddingLevels); } intl_error_reset(&(objval->error)); } From 6e423b82b3f5629be1ed5e5473dda2d6fa3f827e Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Thu, 27 Sep 2018 15:18:21 +0200 Subject: [PATCH 03/50] Fixed IntlBidi::getReordered() --- ext/intl/bidi/bidi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index b050b8ded47f3..a1bdcd84200b8 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -777,8 +777,11 @@ static PHP_METHOD(IntlBidi, getReordered) { if (options & UBIDI_INSERT_LRM_FOR_NUMERIC) { error = U_ZERO_ERROR; - utext_len = ubidi_getLength(objval->bidi) + (2 * ubidi_countRuns(objval->bidi, &error)); - THROW_UFAILURE(objval, "getReordered", error); + utext_len = ubidi_getLength(objval->bidi) + 2 * ubidi_countRuns(objval->bidi, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(objval, "getReordered", error); + return; + } } else if (options & UBIDI_REMOVE_BIDI_CONTROLS) { utext_len = ubidi_getLength(objval->bidi); } else { From e6c2f6b5664e6a5be37db5757b06c11e1cfe6b71 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Thu, 27 Sep 2018 15:18:44 +0200 Subject: [PATCH 04/50] Added tests. --- .../IntlBidi/IntlBidi___construct_basic.phpt | 14 ++ ext/intl/tests/IntlBidi/IntlBidi_basic.phpt | 78 ++++++++ ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt | 77 ++++++++ .../IntlBidi/IntlBidi_getReordered_basic.phpt | 72 +++++++ .../IntlBidi_getReordered_basic1.phpt | 72 +++++++ .../IntlBidi_getReordered_basic2.phpt | 73 +++++++ .../IntlBidi_getReordered_basic3.phpt | 105 ++++++++++ .../IntlBidi_getReordered_basic4.phpt | 105 ++++++++++ .../IntlBidi_getReordered_variant.phpt | 19 ++ .../IntlBidi_getReordered_variant2.phpt | 17 ++ .../IntlBidi_getReorderingMode_basic.phpt | 22 +++ .../IntlBidi_getReorderingOptions_basic.phpt | 22 +++ .../IntlBidi_getResultLength_basic.phpt | 34 ++++ .../IntlBidi_getResultLength_variant.phpt | 34 ++++ .../IntlBidi/IntlBidi_isInverse_basic.phpt | 31 +++ .../IntlBidi_isOrderParagraphsLTR_basic.phpt | 22 +++ .../IntlBidi_orderParagraphsLTR_basic.phpt | 100 ++++++++++ .../tests/IntlBidi/IntlBidi_ut_common.inc | 181 ++++++++++++++++++ 18 files changed, 1078 insertions(+) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic1.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic2.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic3.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReorderingMode_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReorderingOptions_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_isInverse_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_isOrderParagraphsLTR_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_orderParagraphsLTR_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_ut_common.inc diff --git a/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt new file mode 100644 index 0000000000000..d2b1f547b1526 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt @@ -0,0 +1,14 @@ +--TEST-- +Regression test for the UBA implementation. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- + +==DONE== +--EXPECT-- +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_basic.phpt new file mode 100644 index 0000000000000..05f433ff9cca5 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_basic.phpt @@ -0,0 +1,78 @@ +--TEST-- +Regression test for the UBA implementation. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +setInverse(true); + + $levels = str_repeat("\0", IntlBidi::MAX_EXPLICIT_LEVEL); + for ($i = 0; $i < 10; $i++) { + $levels[$i] = chr($i + 1); + } + + $bidi->setPara($srcUt8, \IntlBidi::DEFAULT_LTR, $levels); + $result = u8ToPseudo($bidi->getReordered(\IntlBidi::OUTPUT_REVERSE)); + var_dump($result); +} +?> +==DONE== +--EXPECT-- +string(17) ")K.C.&(KC)dda(led" +string(19) ")BVDL(ddaQDVT) (led" +string(21) "R.S.)T)U.&(PQ)dda(led" +string(22) "L.V.) L.V.&(LV)dda(led" +string(26) "rbbayad DPDHRVR R 0 yad" +string(27) "rbbayad DPHPDHDA H 1 yad" +string(28) "rbbayad DPBLENDA L 2 yad" +string(26) "rbbayad DPJQVM J 3 yad" +string(29) "rbbayad DPIQNF I 4 yad" +string(25) "rbbayad DPMEG M 5 yad" +string(10) "DPMEGolleh" +string(9) "WXY olleh" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt new file mode 100644 index 0000000000000..cd80023501d71 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt @@ -0,0 +1,77 @@ +--TEST-- +Regression test for the UBA implementation. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +setInverse(true); + $levels = str_repeat("\0", IntlBidi::MAX_EXPLICIT_LEVEL); + for ($i = 0; $i < 10; $i++) { + $levels[$i] = chr($i + 1); + } + $bidi->setPara($srcUt8, \IntlBidi::DEFAULT_LTR, $levels); + $result = u8ToPseudo($bidi->getReordered(\IntlBidi::DO_MIRRORING | \IntlBidi::REMOVE_BIDI_CONTROLS)); + var_dump($result); +} +?> +==DONE== +--EXPECT-- +string(16) "del(add(CK(.C.K)" +string(19) "del( (TVDQadd(LDVB)" +string(20) "del(add(QP(.U(T(.S.R" +string(21) "del(add(VL(.V.L (.V.L" +string(26) "day 0 R RVRHDPD dayabbr" +string(27) "day 1 H ADHDPHPD dayabbr" +string(28) "day 2 L ADNELBPD dayabbr" +string(26) "day 3 J MVQJPD dayabbr" +string(29) "day 4 I FNQIPD dayabbr" +string(25) "day 5 M GEMPD dayabbr" +string(10) "helloGEMPD" +string(9) "hello YXW" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic.phpt new file mode 100644 index 0000000000000..25f3e2d614f1d --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic.phpt @@ -0,0 +1,72 @@ +--TEST-- +Regression test for the UBA implementation. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +setPara($srcUt8, \IntlBidi::DEFAULT_LTR); + $result = u8ToPseudo($bidi->getReordered(\IntlBidi::DO_MIRRORING)); + var_dump($result); +} +?> +==DONE== +--EXPECT-- +string(17) "del(CK)add(&.C.K)" +string(19) "del(TVDQ) add(LDVB)" +string(21) "del(QP)add(S.R.)&.U(T" +string(22) "del(VL)add(V.L.) &.V.L" +string(26) "day 0 RVRHDPD R dayabbr" +string(27) "day 1 ADHDPHPD H dayabbr" +string(28) "day 2 ADNELBPD L dayabbr" +string(26) "day 3 MVQJPD J dayabbr" +string(29) "day 4 FNQIPD I dayabbr" +string(25) "day 5 GEMPD M dayabbr" +string(10) "helloGEMPD" +string(9) "hello YXW" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic1.phpt new file mode 100644 index 0000000000000..7b35343682549 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic1.phpt @@ -0,0 +1,72 @@ +--TEST-- +Regression test for the UBA implementation. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +setPara($srcUt8, \IntlBidi::DEFAULT_LTR); + $result = u8ToPseudo($bidi->getReordered(\IntlBidi::DO_MIRRORING | \IntlBidi::OUTPUT_REVERSE)); + var_dump($result); +} +?> +==DONE== +--EXPECT-- +string(17) ")K.C.&(dda)KC(led" +string(19) ")BVDL(dda )QDVT(led" +string(21) "T(U.&).R.S(dda)PQ(led" +string(22) "L.V.& ).L.V(dda)LV(led" +string(26) "rbbayad R DPDHRVR 0 yad" +string(27) "rbbayad H DPHPDHDA 1 yad" +string(28) "rbbayad L DPBLENDA 2 yad" +string(26) "rbbayad J DPJQVM 3 yad" +string(29) "rbbayad I DPIQNF 4 yad" +string(25) "rbbayad M DPMEG 5 yad" +string(10) "DPMEGolleh" +string(9) "WXY olleh" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic2.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic2.phpt new file mode 100644 index 0000000000000..d5845b06dd3c0 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic2.phpt @@ -0,0 +1,73 @@ +--TEST-- +Regression test for the UBA implementation. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +setInverse(true); + $bidi->setPara($srcUt8, \IntlBidi::DEFAULT_LTR); + $result = u8ToPseudo($bidi->getReordered(\IntlBidi::OUTPUT_REVERSE | \IntlBidi::INSERT_LRM_FOR_NUMERIC)); + var_dump($result); +} +?> +==DONE== +--EXPECT-- +string(22) "@)@K.C.&@(dda)@KC@(led" +string(24) "@)@BVDL@(dda )@QDVT@(led" +string(24) "R.S.)T)U.&@(dda)@PQ@(led" +string(25) "L.V.) L.V.&@(dda)@LV@(led" +string(28) "rbbayad @R DPDHRVR@ 0 yad" +string(29) "rbbayad @H DPHPDHDA@ 1 yad" +string(30) "rbbayad @L DPBLENDA@ 2 yad" +string(28) "rbbayad @J DPJQVM@ 3 yad" +string(31) "rbbayad @I DPIQNF@ 4 yad" +string(27) "rbbayad @M DPMEG@ 5 yad" +string(10) "DPMEGolleh" +string(10) "WXY@ olleh" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic3.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic3.phpt new file mode 100644 index 0000000000000..eaa9b7aab88e4 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic3.phpt @@ -0,0 +1,105 @@ +--TEST-- +Regression test for variants to the UBA. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +67->', + '-=%$123/ *', + 'abc->12..>JKL', + 'JKL->12..>abc', + '123->abc', + '123->JKL', + '*>12.>34->JKL', + '*>67.>89->JKL', + '* /abc-=$%123', + '* /$%def-=123', + '-=GHI* /123%$', + '-=%$JKL* /123', + 'ab =#CD *?450', + 'ab 234 896 de', + 'abc-=%$LMN* /123', + '123->JKL&MN&P', + '123' +]; + +$bidi = new IntlBidi(); + +$bidi->setReorderingMode(IntlBidi::REORDER_RUNS_ONLY); +$bidi->setReorderingOptions(IntlBidi::OPTION_REMOVE_CONTROLS); + +for ($i = 0, $iMax = \count($testCases); $i < $iMax; $i++) { + $src = $testCases[$i]; + $srcU8 = pseudoToU8($src); + + $bidi->setPara($srcU8, 0); + var_dump(u8ToPseudo($bidi->getReordered(IntlBidi::DO_MIRRORING))); + + $bidi->setPara($srcU8, 1); + var_dump(u8ToPseudo($bidi->getReordered(IntlBidi::DO_MIRRORING))); +} + +?> +==DONE== +--EXPECT-- +string(13) "de 896 ab 234" +string(13) "de 896 ab 234" +string(6) "GHIabc" +string(6) "GHIabc" +string(7) "<-67<.a" +string(7) "<-67<.a" +string(10) "* /%$123=-" +string(10) "* /%$123=-" +string(13) "JKL<..12<-abc" +string(13) "JKL<..abc->12" +string(13) "abc<..JKL->12" +string(13) "abc<..12<-JKL" +string(8) "abc<-123" +string(8) "abc<-123" +string(8) "JKL<-123" +string(8) "123->JKL" +string(13) "JKL<-34<.12<*" +string(13) "12.>34->JKL<*" +string(13) "67.>89->JKL<*" +string(13) "67.>89->JKL<*" +string(13) "$%123=-abc/ *" +string(13) "abc-=$%123/ *" +string(13) "123=-def%$/ *" +string(13) "def-=123%$/ *" +string(13) "GHI* /123%$=-" +string(13) "123%$/ *GHI=-" +string(13) "JKL* /%$123=-" +string(13) "123/ *JKL$%=-" +string(13) "CD *?450#= ab" +string(13) "450?* CD#= ab" +string(13) "de 896 ab 234" +string(13) "de 896 ab 234" +string(16) "LMN* /%$123=-abc" +string(16) "123/ *LMN$%=-abc" +string(11) "JKLMNP<-123" +string(11) "123->JKLMNP" +string(3) "123" +string(3) "123" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt new file mode 100644 index 0000000000000..5cf1915ed057c --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt @@ -0,0 +1,105 @@ +--TEST-- +Regression test for variants to the UBA. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +67->', + '-=%$123/ *', + 'abc->12..>JKL', + 'JKL->12..>abc', + '123->abc', + '123->JKL', + '*>12.>34->JKL', + '*>67.>89->JKL', + '* /abc-=$%123', + '* /$%def-=123', + '-=GHI* /123%$', + '-=%$JKL* /123', + 'ab =#CD *?450', + 'ab 234 896 de', + 'abc-=%$LMN* /123', + '123->JKL&MN&P', + '123' +]; + +$bidi = new IntlBidi(); + +$bidi->setReorderingMode(IntlBidi::REORDER_RUNS_ONLY); +$bidi->setReorderingOptions(IntlBidi::OPTION_INSERT_MARKS); + +for ($i = 0, $iMax = \count($testCases); $i < $iMax; $i++) { + $src = $testCases[$i]; + $srcU8 = pseudoToU8($src); + + $bidi->setPara($srcU8, 0); + var_dump(u8ToPseudo($bidi->getReordered(IntlBidi::DO_MIRRORING))); + + $bidi->setPara($srcU8, 1); + var_dump(u8ToPseudo($bidi->getReordered(IntlBidi::DO_MIRRORING))); +} + +?> +==DONE== +--EXPECT-- +string(15) "ab 234 @896@ de" +string(13) "de 896 ab 234" +string(6) "GHIabc" +string(6) "GHIabc" +string(7) "<-67<.a" +string(7) "<-67<.a" +string(10) "* /%$123=-" +string(10) "* /%$123=-" +string(13) "JKL<..12<-abc" +string(13) "JKL<..abc->12" +string(13) "abc<..JKL->12" +string(13) "abc<..12<-JKL" +string(9) "abc&<-123" +string(8) "abc<-123" +string(8) "JKL<-123" +string(9) "JKL<-@123" +string(13) "JKL<-34<.12<*" +string(14) "JKL<-@34<.12<*" +string(13) "67.>89->JKL<*" +string(13) "67.>89->JKL<*" +string(13) "$%123=-abc/ *" +string(13) "abc-=$%123/ *" +string(13) "123=-def%$/ *" +string(13) "def-=123%$/ *" +string(13) "GHI* /123%$=-" +string(13) "123%$/ *GHI=-" +string(13) "JKL* /%$123=-" +string(13) "123/ *JKL$%=-" +string(13) "CD *?450#= ab" +string(13) "450?* CD#= ab" +string(15) "ab 234 @896@ de" +string(13) "de 896 ab 234" +string(16) "LMN* /%$123=-abc" +string(16) "123/ *LMN$%=-abc" +string(11) "JKLMNP<-123" +string(12) "JKLMNP<-@123" +string(3) "123" +string(3) "123" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt new file mode 100644 index 0000000000000..4fbe9cf5eb810 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt @@ -0,0 +1,19 @@ +--TEST-- +U_BUFFER_OVERFLOW_ERROR error. (IS EMBEDDED IN OTHER TEST, BUT EXTRACTED AND REDUCED FOR SIMPLICITY) +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +setReorderingMode(\IntlBidi::REORDER_RUNS_ONLY); +$bidi->setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS); + +$bidi->setPara('ab 234' . "\x20\xD9\xA8\xD9\xA9\xD9\xA6" . 'de', 0); +var_dump(bin2hex($bidi->getReordered(\IntlBidi::DO_MIRRORING))); // U_BUFFER_OVERFLOW_ERROR +?> +==DONE== +--EXPECT-- +string(42) "61622032333420e2808ed9a8d9a9d9a6e2808e6465" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt new file mode 100644 index 0000000000000..24d721231710b --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt @@ -0,0 +1,17 @@ +--TEST-- +U_ZERO_ERROR error. (IS EMBEDDED IN OTHER TEST, BUT EXTRACTED AND REDUCED FOR SIMPLICITY) +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +setPara('', \IntlBidi::DEFAULT_LTR); +// TODO: this function throws a U_ZERO_ERROR exception. +var_dump($bidi->getReordered(\IntlBidi::INSERT_LRM_FOR_NUMERIC)); +?> +==DONE== +--EXPECT-- +string(0) "" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReorderingMode_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReorderingMode_basic.phpt new file mode 100644 index 0000000000000..fa59bb85d2e48 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReorderingMode_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test the getter and setter, to make sure that it stores the mode. +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +getReorderingMode()); +$bidi->setReorderingMode(IntlBidi::REORDER_NUMBERS_SPECIAL); +var_dump($bidi->getReorderingMode()); +$bidi->setReorderingMode(IntlBidi::REORDER_RUNS_ONLY); +var_dump($bidi->getReorderingMode()); +?> +==DONE== +--EXPECT-- +int(0) +int(1) +int(3) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReorderingOptions_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReorderingOptions_basic.phpt new file mode 100644 index 0000000000000..e1ed3c3803060 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReorderingOptions_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test the getter and setter, to make sure that it stores the options. +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +getReorderingOptions()); +$bidi->setReorderingOptions(IntlBidi::OPTION_STREAMING); +var_dump($bidi->getReorderingOptions()); +$bidi->setReorderingOptions(IntlBidi::OPTION_INSERT_MARKS); +var_dump($bidi->getReorderingOptions()); +?> +==DONE== +--EXPECT-- +int(0) +int(4) +int(1) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt new file mode 100644 index 0000000000000..c8b1c8dc8e8e1 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test get result length. +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +setPara($str, IntlBidi::RTL); +$bidi->setReorderingOptions(IntlBidi::REMOVE_BIDI_CONTROLS); + +var_dump($bidi->getResultLength()); +$bidiLine2 = $bidi->setLine(0, 6); +var_dump($bidi->getResultLength()); +var_dump($bidiLine2->getResultLength()); + +unset($bidiLine2); +gc_collect_cycles(); + +var_dump($bidi->getResultLength()); +unset($bidi); +gc_collect_cycles(); + +?> +==DONE== +--EXPECT-- +int(14) +int(14) +int(5) +int(14) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt new file mode 100644 index 0000000000000..1aa4ebf8e9aa7 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt @@ -0,0 +1,34 @@ +--TEST-- +This has wrong behaviour, since the bidi object of $bidi gets deleted, but actually should stay alive until $bidiLine2 gets deleted or $bidiLine2->setPara() gets called. +Or we return a completely different instance, just to make it easier to handle. (But this would disable "stacking" of the setLine() call. +Also we should change the name to getLine(). +http://icu-project.org/apiref/icu4c/ubidi_8h.html#a88693e5a8ad4be974dc90ec6b8db56df +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +setPara($str, IntlBidi::RTL); +$bidi->setReorderingOptions(IntlBidi::REMOVE_BIDI_CONTROLS); + +var_dump($bidi->getResultLength()); +$bidiLine2 = $bidi->setLine(0, 6); +var_dump($bidi->getResultLength()); + +unset($bidi); + +gc_collect_cycles(); +gc_collect_cycles(); + +var_dump($bidiLine2->getResultLength()); +?> +==DONE== +--EXPECT-- +int(14) +int(14) +int(5) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_isInverse_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_isInverse_basic.phpt new file mode 100644 index 0000000000000..a9f1e84315ea3 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_isInverse_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test the getter and setter, to make sure that it stores the inverse flag. +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +isInverse()); +$bidi->setInverse(false); +var_dump($bidi->isInverse()); +$bidi->setInverse(true); +var_dump($bidi->isInverse()); +$bidi->setInverse(false); +$bidi->setReorderingMode(IntlBidi::REORDER_INVERSE_NUMBERS_AS_L); // 4 +var_dump($bidi->isInverse()); +$bidi->setInverse(false); // set the flag and the value to 0 +var_dump($bidi->isInverse()); +var_dump($bidi->getReorderingMode()); // should be 0, since the flag got reset by setInverse +?> +==DONE== +--EXPECT-- +bool(false) +bool(false) +bool(true) +bool(true) +bool(false) +int(0) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_isOrderParagraphsLTR_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_isOrderParagraphsLTR_basic.phpt new file mode 100644 index 0000000000000..2e0607c301772 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_isOrderParagraphsLTR_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test the getter and setter, to make sure that it stores the isOrderParagraphsLTR flag. +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +isOrderParagraphsLTR()); +$bidi->orderParagraphsLTR(true); +var_dump($bidi->isOrderParagraphsLTR()); +$bidi->orderParagraphsLTR(false); +var_dump($bidi->isOrderParagraphsLTR()); +?> +==DONE== +--EXPECT-- +bool(false) +bool(true) +bool(false) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_orderParagraphsLTR_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_orderParagraphsLTR_basic.phpt new file mode 100644 index 0000000000000..6f5dac4656516 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_orderParagraphsLTR_basic.phpt @@ -0,0 +1,100 @@ +--TEST-- +Regression test for doing transformations in context. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +orderParagraphsLTR(true); + +for ($i = 0, $iMax = \count($data); $i < $iMax; $i++) { + [$prologue, $src, $epilogue, $paraLevel] = $data[$i]; + + $prologue = pseudoToU8($prologue); + $epilogue = pseudoToU8($epilogue); + $src = pseudoToU8($src); + + $bidi->setContext($epilogue, $prologue); + $bidi->setContext($prologue, $epilogue); + + $bidi->setPara($src, $paraLevel); + var_dump(u8ToPseudo($bidi->getReordered(\IntlBidi::DO_MIRRORING))); +} +?> +==DONE== +--EXPECT-- +string(0) "" +string(9) ".-=LKJ-+*" +string(9) ".-=LKJ-+*" +string(9) ".-=LKJ-+*" +string(9) "LKJ=-.-+*" +string(9) ".-=*+-LKJ" +string(9) ".-=*+-LKJ" +string(9) ".-=*+-LKJ" +string(9) "*+-LKJ=-." +string(9) ".-=*+-LKJ" +string(9) "*+-abc=-." +string(9) "*+-abc=-." +string(9) "*+-abc=-." +string(9) "*+-.-=abc" +string(9) "abc-+*=-." +string(9) "abc-+*=-." +string(9) ".-=abc-+*" +string(9) "*+-.-=abc" +string(9) "*+-abc=-." +string(9) "*+-.-=abc" +string(3) ".-=" +string(3) "=-." +string(3) "=-." +string(3) ".-=" +string(3) "=-." +string(7) "=-.|-+*" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_ut_common.inc b/ext/intl/tests/IntlBidi/IntlBidi_ut_common.inc new file mode 100644 index 0000000000000..a0f257ad37758 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_ut_common.inc @@ -0,0 +1,181 @@ +'] = 0x003E; + $uCharToPseudo[0x3E] = '>'; + $pseudoToUChar['?'] = 0x003F; + $uCharToPseudo[0x3F] = '?'; + $pseudoToUChar['\\'] = 0x005C; + $uCharToPseudo[0x5C] = '\\'; + + /* initialize specially used characters */ + $pseudoToUChar['`'] = 0x3000; + $uCharToPseudo2[0x00] = '`'; /* NSM */ + $pseudoToUChar['@'] = 0x200E; + $uCharToPseudo2[0x0E] = '@'; /* LRM */ + $pseudoToUChar['&'] = 0x200F; + $uCharToPseudo2[0x0F] = '&'; /* RLM */ + $pseudoToUChar['_'] = 0x001F; + $uCharToPseudo[0x1F] = '_'; /* S */ + $pseudoToUChar['|'] = 0x2029; + $uCharToPseudo2[0x29] = '|'; /* B */ + $pseudoToUChar['['] = 0x202A; + $uCharToPseudo2[0x2A] = '['; /* LRE */ + $pseudoToUChar[']'] = 0x202B; + $uCharToPseudo2[0x2B] = ']'; /* RLE */ + $pseudoToUChar['^'] = 0x202C; + $uCharToPseudo2[0x2C] = '^'; /* PDF */ + $pseudoToUChar['{'] = 0x202D; + $uCharToPseudo2[0x2D] = '{'; /* LRO */ + $pseudoToUChar['}'] = 0x202E; + $uCharToPseudo2[0x2E] = '}'; /* RLO */ + $pseudoToUChar['~'] = 0x007F; + $uCharToPseudo[0x7F] = '~'; /* BN */ + + $columns_str = str_split('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'); + $columns = []; + foreach ($columns_str as $value) { + $columns[] = \IntlChar::chr(\ord($value)); + } + + /* initialize western digits */ + for ($i = 0, $uchar = 0x0030; $i < 6; $i++, $uchar++) { + $c = $columns[$i]; + $pseudoToUChar[$c] = $uchar; + $uCharToPseudo[$uchar & 0x00FF] = $c; + } + /* initialize Hindi digits */ + for ($i = 6, $uchar = 0x0666; $i < 10; $i++, $uchar++) { + $c = $columns[$i]; + $pseudoToUChar[$c] = $uchar; + $uCharToPseudo2[$uchar & 0x00FF] = $c; + } + /* initialize Arabic letters */ + for ($i = 10, $uchar = 0x0631; $i < 16; $i++, $uchar++) { + $c = $columns[$i]; + $pseudoToUChar[$c] = $uchar; + $uCharToPseudo2[$uchar & 0x00FF] = $c; + } + /* initialize Hebrew letters */ + for ($i = 16, $uchar = 0x05D7; $i < 32; $i++, $uchar++) { + $c = $columns[$i]; + $pseudoToUChar[$c] = $uchar; + $uCharToPseudo2[$uchar & 0x00FF] = $c; + } + /* initialize Unassigned code points */ + for ($i = 32, $uchar = 0x08D0; $i < 36; $i++, $uchar++) { + $c = $columns[$i]; + $pseudoToUChar[$c] = $uchar; + $uCharToPseudo2[$uchar & 0x00FF] = $c; + } + /* initialize Latin lower case letters */ + for ($i = 36, $uchar = 0x0061; $i < 62; $i++, $uchar++) { + $c = $columns[$i]; + $pseudoToUChar[$c] = $uchar; + $uCharToPseudo[$uchar & 0x00FF] = $c; + } + + return [ + 'pseudoToUChar' => $pseudoToUChar, + 'uCharToPseudo' => $uCharToPseudo, + 'uCharToPseudo2' => $uCharToPseudo2 + ]; +} + +function getMapping() { + static $mapping = null; + if ($mapping === null) { + $mapping = initMapping(); + } + + return $mapping; +} + +function pseudoToU8(string $input) +{ + $len = strlen($input); + $output = ''; + + for ($i = 0; $i < $len; $i++) { + $output .= \IntlChar::chr(getMapping()['pseudoToUChar'][$input[$i]]); + } + + return $output; +} + +function u8ToPseudo(string $input) +{ + $encoding = 'utf-8'; + $len = \mb_strlen($input, $encoding); + $output = ''; + + $mapping = getMapping(); + + for ($i = 0; $i < $len; $i++) { + $uChar = \IntlChar::ord(\mb_substr($input, $i, 1, $encoding)); + $output .= $uChar < 0x0100 ? $mapping['uCharToPseudo'][$uChar] : $mapping['uCharToPseudo2'][$uChar & 0x00FF]; + } + + return $output; +} \ No newline at end of file From 96f37e769ff6372cd3c070b0bf0a557c8a3cb7bd Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Thu, 27 Sep 2018 15:25:41 +0200 Subject: [PATCH 05/50] Updated parameter parsing to the fast paramter parsing api. --- ext/intl/bidi/bidi.c | 114 +++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 54 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index a1bdcd84200b8..26f8cef21068f 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -74,9 +74,11 @@ static PHP_METHOD(IntlBidi, __construct) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); UErrorCode error; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "|ll", &maxLength, &maxRunCount) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(maxLength) + Z_PARAM_LONG(maxRunCount) + ZEND_PARSE_PARAMETERS_END(); if (maxRunCount < 0) { php_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, @@ -119,9 +121,9 @@ static PHP_METHOD(IntlBidi, setInverse) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); zend_bool inverse; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "b", &inverse) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_BOOL(inverse) + ZEND_PARSE_PARAMETERS_END(); ubidi_setInverse(objval->bidi, (UBool)inverse); RETURN_ZVAL(getThis(), 1, 0); @@ -146,9 +148,9 @@ static PHP_METHOD(IntlBidi, orderParagraphsLTR) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); zend_bool ltr; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "b", <r) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_BOOL(ltr) + ZEND_PARSE_PARAMETERS_END(); ubidi_orderParagraphsLTR(objval->bidi, (UBool)ltr); RETURN_ZVAL(getThis(), 1, 0); @@ -173,9 +175,9 @@ static PHP_METHOD(IntlBidi, setReorderingMode) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); zend_long mode; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &mode) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(mode) + ZEND_PARSE_PARAMETERS_END(); ubidi_setReorderingMode(objval->bidi, (UBiDiReorderingMode)mode); RETURN_ZVAL(getThis(), 1, 0); @@ -200,9 +202,9 @@ static PHP_METHOD(IntlBidi, setReorderingOptions) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); zend_long opts; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &opts) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(opts) + ZEND_PARSE_PARAMETERS_END(); ubidi_setReorderingOptions(objval->bidi, (UBiDiReorderingOption)opts); RETURN_ZVAL(getThis(), 1, 0); @@ -231,9 +233,11 @@ static PHP_METHOD(IntlBidi, setContext) { UChar *uprologue = NULL, *uepilogue = NULL; int32_t uprologue_len = 0, uepilogue_len = 0; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "|S!S!", &prologue, &epilogue) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(0, 2) + Z_PARAM_OPTIONAL + Z_PARAM_STR(prologue) + Z_PARAM_STR(epilogue) + ZEND_PARSE_PARAMETERS_END(); if (prologue && ZSTR_LEN(prologue)) { UErrorCode error = U_ZERO_ERROR; @@ -294,17 +298,19 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_setpara_arginfo, ZEND_RETURN_VALUE, ZEND_ARG_TYPE_INFO(0, embeddingLevels, IS_STRING, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, setPara) { + zend_string *para, *embeddingLevels = NULL; + zend_long paraLevel = UBIDI_DEFAULT_LTR; php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - zend_string *para; - zend_string *embeddingLevels = NULL; UChar *upara = NULL; int32_t upara_len = 0; - zend_long paraLevel = UBIDI_DEFAULT_LTR; UErrorCode error; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S|l", ¶, ¶Level, &embeddingLevels) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_STR(para) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(paraLevel) + Z_PARAM_STR(embeddingLevels) + ZEND_PARSE_PARAMETERS_END(); error = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&upara, &upara_len, ZSTR_VAL(para), ZSTR_LEN(para), &error); @@ -396,9 +402,9 @@ static PHP_METHOD(IntlBidi, getBaseDirection) { int32_t utext_len; UErrorCode error; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S", &text) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(text) + ZEND_PARSE_PARAMETERS_END(); error = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&utext, &utext_len, ZSTR_VAL(text), ZSTR_LEN(text), &error); @@ -447,9 +453,9 @@ static PHP_METHOD(IntlBidi, getParagraph) { UBiDiLevel level = UBIDI_MAX_EXPLICIT_LEVEL; UErrorCode error = U_ZERO_ERROR; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &pos) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(pos) + ZEND_PARSE_PARAMETERS_END(); idx = ubidi_getParagraph(objval->bidi, pos, &start, &limit, &level, &error); if (U_FAILURE(error)) { @@ -476,9 +482,9 @@ static PHP_METHOD(IntlBidi, getParagraphByIndex) { UBiDiLevel level = UBIDI_MAX_EXPLICIT_LEVEL; UErrorCode error = U_ZERO_ERROR; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &idx) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1); + Z_PARAM_LONG(idx) + ZEND_PARSE_PARAMETERS_END(); ubidi_getParagraphByIndex(objval->bidi, idx, &start, &limit, &level, &error); if (U_FAILURE(error)) { @@ -502,9 +508,9 @@ static PHP_METHOD(IntlBidi, getLevelAt) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); zend_long pos; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &pos) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(pos) + ZEND_PARSE_PARAMETERS_END(); RETURN_LONG(ubidi_getLevelAt(objval->bidi, pos)); } @@ -546,9 +552,9 @@ static PHP_METHOD(IntlBidi, getLogicalRun) { int32_t limit = 0; UBiDiLevel level = UBIDI_MAX_EXPLICIT_LEVEL; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &pos) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(pos) + ZEND_PARSE_PARAMETERS_END(); ubidi_getLogicalRun(objval->bidi, pos, &limit, &level); @@ -588,9 +594,9 @@ static PHP_METHOD(IntlBidi, getVisualRun) { int32_t start = 0, length = 0; UBiDiDirection dir; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &idx) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(idx) + ZEND_PARSE_PARAMETERS_END(); dir = ubidi_getVisualRun(objval->bidi, idx, &start, &length); @@ -611,9 +617,9 @@ static PHP_METHOD(IntlBidi, getVisualIndex) { int32_t ret; UErrorCode error = U_ZERO_ERROR; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &idx) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(idx) + ZEND_PARSE_PARAMETERS_END(); ret = ubidi_getVisualIndex(objval->bidi, idx, &error); if (U_FAILURE(error)) { @@ -635,9 +641,9 @@ static PHP_METHOD(IntlBidi, getLogicalIndex) { int32_t ret; UErrorCode error = U_ZERO_ERROR; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &idx) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(idx) + ZEND_PARSE_PARAMETERS_END(); ret = ubidi_getLogicalIndex(objval->bidi, idx, &error); if (U_FAILURE(error)) { @@ -736,9 +742,9 @@ static PHP_METHOD(IntlBidi, getCustomizedClass) { size_t len; UChar32 c; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "S", &text) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(text) + ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(text) > 4) { php_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, @@ -771,9 +777,9 @@ static PHP_METHOD(IntlBidi, getReordered) { zend_string *ret; UErrorCode error; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "l", &options) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(options) + ZEND_PARSE_PARAMETERS_END(); if (options & UBIDI_INSERT_LRM_FOR_NUMERIC) { error = U_ZERO_ERROR; From c85537ba26b1348bc83e2974c0697b55b10ea226 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Thu, 27 Sep 2018 15:30:58 +0200 Subject: [PATCH 06/50] Changed the call style of setLine to a java like approach and fixed the method. --- ext/intl/bidi/bidi.c | 76 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 26f8cef21068f..3698c398716ff 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -353,32 +353,84 @@ static PHP_METHOD(IntlBidi, setPara) { } /* }}} */ -/* {{{ proto self IntlBidi::setLine(int $tart, int $limit, IntlBidi $line) */ -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_setline_arginfo, ZEND_RETURN_VALUE, 3, IS_OBJECT, 0) +/* {{{ proto IntlBidi IntlBidi::setLine(int $start, int $limit) */ +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_setline_arginfo, ZEND_RETURN_VALUE, 2, IS_OBJECT, 0) ZEND_ARG_TYPE_INFO(0, start, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, limit, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, line, IS_OBJECT, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, setLine) { zend_long start, limit; - zend_object *zline; - php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - php_intl_bidi_object *lineval; + zval retval; + zend_function * constructor; + zend_fcall_info fci; + zend_fcall_info_cache fcc; + php_intl_bidi_object *objval, *lineval; UErrorCode error; - if (zend_parse_parameters_throw(ZEND_NUM_ARGS(), "llO", &start, &limit, &zline, php_intl_bidi_ce) == FAILURE) { - return; + // Parse parameters. + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(start) + Z_PARAM_LONG(limit) + ZEND_PARSE_PARAMETERS_END(); + + // init return value as new object. (This code is from php_reflection ReflectionClass::newInstance()) + + // init the return value as a IntlBidi instance. + object_init_ex(return_value, php_intl_bidi_ce); + + + // get the constructor. + constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); + + fci.size = sizeof(fci); + ZVAL_UNDEF(&fci.function_name); + fci.object = Z_OBJ_P(return_value); + fci.retval = &retval; + fci.param_count = 0; + fci.params = NULL; + fci.no_separation = 1; + + fcc.function_handler = constructor; + fcc.called_scope = Z_OBJCE_P(return_value); + fcc.object = Z_OBJ_P(return_value); + + int ret = zend_call_function(&fci, &fcc); + zval_ptr_dtor(&retval); + + //TODO: keep objval alive while lineval is alive or setPara() gets called on lineval. + // @see http://icu-project.org/apiref/icu4c/ubidi_8h.html#ac7d96b281cd6ab2d56900bfdc37c808a + // altough i am not sure about "destroying" or "reusing" (if this is also the case when other functions get called)? + // it should be right to return a new istance, insteadof overriding a old one, to prevent circular references. + // also setPara should not be callable while an object gets referenced, or the referenced objects need to be reset. + // I tried to implement it, but i got stuck on that unset() resets the reference count. + + + // get the instance. + objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); + + if (ret == FAILURE) { + THROW_UFAILURE(objval, "setLine", ret); + goto setLine_cleanup; } - lineval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); + // get the bidi istance. + lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); + + // just call bidi, because the return value is already set. error = U_ZERO_ERROR; - ubidi_setLine(objval->bidi, start, limit, lineval->bidi, &error); + ubidi_setLine(objval->bidi, start, limit - 1, lineval->bidi, &error); if (U_FAILURE(error)) { THROW_UFAILURE(objval, "setLine", error); - return; + goto setLine_cleanup; } - RETURN_ZVAL(getThis(), 1, 0); + RETURN_ZVAL(return_value, 0, 0); +setLine_cleanup: + if (return_value) { + zval_ptr_dtor(return_value); + } + + return; } /* }}} */ From 3bce63d721cbb959a503c200ff6d0ee9a9c1c670 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Fri, 28 Sep 2018 07:52:37 +0200 Subject: [PATCH 07/50] Added comment. --- ext/intl/bidi/bidi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 3698c398716ff..96ead919c30db 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -835,7 +835,7 @@ static PHP_METHOD(IntlBidi, getReordered) { if (options & UBIDI_INSERT_LRM_FOR_NUMERIC) { error = U_ZERO_ERROR; - utext_len = ubidi_getLength(objval->bidi) + 2 * ubidi_countRuns(objval->bidi, &error); + utext_len = ubidi_getLength(objval->bidi) + (2 * ubidi_countRuns(objval->bidi, &error)); if (U_FAILURE(error)) { THROW_UFAILURE(objval, "getReordered", error); return; @@ -855,6 +855,7 @@ static PHP_METHOD(IntlBidi, getReordered) { return; } + // HERE IT CRASHES WHEN RUNNING IntlBidi_getReordered_varian.phpt (not enough memory allocated for the string). error = U_ZERO_ERROR; ret = intl_convert_utf16_to_utf8(utext, utext_len, &error); efree(utext); From 340151c3339b8552e55733a0b9c08127c3f799f1 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Fri, 28 Sep 2018 07:53:03 +0200 Subject: [PATCH 08/50] Removed duplicate in a test. --- ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt index 5cf1915ed057c..fc1f525c5f49c 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt @@ -24,7 +24,6 @@ Timo Scholz include 'IntlBidi_ut_common.inc'; $testCases = [ - 'ab 234 896 de', 'abcGHI', 'a.>67->', '-=%$123/ *', @@ -64,8 +63,6 @@ for ($i = 0, $iMax = \count($testCases); $i < $iMax; $i++) { ?> ==DONE== --EXPECT-- -string(15) "ab 234 @896@ de" -string(13) "de 896 ab 234" string(6) "GHIabc" string(6) "GHIabc" string(7) "<-67<.a" From 55c07f0ebdba2ed2844497f780df559263a1834e Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 2 Oct 2018 14:22:02 +0200 Subject: [PATCH 09/50] Removed unnecessary memory zeroing. --- ext/intl/bidi/bidi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 96ead919c30db..0b28c40a68948 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -102,8 +102,6 @@ static PHP_METHOD(IntlBidi, __construct) { } } - objval->embeddingLevels = NULL; - error = U_ZERO_ERROR; objval->bidi = ubidi_openSized(maxLength, maxRunCount, &error); if (U_FAILURE(error)) { From d7853682cc39f90bccc6541b46795311deacf958 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 2 Oct 2018 14:24:04 +0200 Subject: [PATCH 10/50] Made function arguments nullable. --- ext/intl/bidi/bidi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 0b28c40a68948..03b845ef104ee 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -233,8 +233,8 @@ static PHP_METHOD(IntlBidi, setContext) { ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STR(prologue) - Z_PARAM_STR(epilogue) + Z_PARAM_STR_EX(prologue) + Z_PARAM_STR_EX(epilogue) ZEND_PARSE_PARAMETERS_END(); if (prologue && ZSTR_LEN(prologue)) { @@ -307,7 +307,7 @@ static PHP_METHOD(IntlBidi, setPara) { Z_PARAM_STR(para) Z_PARAM_OPTIONAL Z_PARAM_LONG(paraLevel) - Z_PARAM_STR(embeddingLevels) + Z_PARAM_STR_EX(embeddingLevels) ZEND_PARSE_PARAMETERS_END(); error = U_ZERO_ERROR; From 3cd9c174485f375d0c6cf9520102596cac3b8430 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 2 Oct 2018 14:26:33 +0200 Subject: [PATCH 11/50] removed unnecessary emalloc calll, since erealloc with null has the same behavior. --- ext/intl/bidi/bidi.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 03b845ef104ee..05c6b9d75a975 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -319,11 +319,7 @@ static PHP_METHOD(IntlBidi, setPara) { // TODO: maybe check for the length of the embeddingLevels. if (embeddingLevels != NULL && ZSTR_LEN(embeddingLevels) > 0) { - if (objval->embeddingLevels != NULL) { objval->embeddingLevels = (UBiDiLevel*)erealloc(objval->embeddingLevels, ZSTR_LEN(embeddingLevels)); - } else { - objval->embeddingLevels = (UBiDiLevel*)emalloc(ZSTR_LEN(embeddingLevels)); - } memcpy(objval->embeddingLevels, ZSTR_VAL(embeddingLevels), ZSTR_LEN(embeddingLevels)); } else { efree(objval->embeddingLevels); From f67506fb33236e8372c8ee199291777a836038a8 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 2 Oct 2018 14:27:21 +0200 Subject: [PATCH 12/50] Removed unnecessary comments and a unnecessary return --- ext/intl/bidi/bidi.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 05c6b9d75a975..c8a1e1971cee6 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -319,7 +319,7 @@ static PHP_METHOD(IntlBidi, setPara) { // TODO: maybe check for the length of the embeddingLevels. if (embeddingLevels != NULL && ZSTR_LEN(embeddingLevels) > 0) { - objval->embeddingLevels = (UBiDiLevel*)erealloc(objval->embeddingLevels, ZSTR_LEN(embeddingLevels)); + objval->embeddingLevels = (UBiDiLevel*)erealloc(objval->embeddingLevels, ZSTR_LEN(embeddingLevels)); memcpy(objval->embeddingLevels, ZSTR_VAL(embeddingLevels), ZSTR_LEN(embeddingLevels)); } else { efree(objval->embeddingLevels); @@ -361,19 +361,15 @@ static PHP_METHOD(IntlBidi, setLine) { php_intl_bidi_object *objval, *lineval; UErrorCode error; - // Parse parameters. ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_LONG(start) Z_PARAM_LONG(limit) ZEND_PARSE_PARAMETERS_END(); - // init return value as new object. (This code is from php_reflection ReflectionClass::newInstance()) - // init the return value as a IntlBidi instance. object_init_ex(return_value, php_intl_bidi_ce); - // get the constructor. constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); fci.size = sizeof(fci); @@ -399,7 +395,6 @@ static PHP_METHOD(IntlBidi, setLine) { // I tried to implement it, but i got stuck on that unset() resets the reference count. - // get the instance. objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (ret == FAILURE) { @@ -407,10 +402,8 @@ static PHP_METHOD(IntlBidi, setLine) { goto setLine_cleanup; } - // get the bidi istance. lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); - // just call bidi, because the return value is already set. error = U_ZERO_ERROR; ubidi_setLine(objval->bidi, start, limit - 1, lineval->bidi, &error); if (U_FAILURE(error)) { @@ -423,8 +416,6 @@ static PHP_METHOD(IntlBidi, setLine) { if (return_value) { zval_ptr_dtor(return_value); } - - return; } /* }}} */ From f26405ce1371312a96d0853e2a41e52302abe20f Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 20 Nov 2018 14:25:46 +0100 Subject: [PATCH 13/50] Added tests. --- .../IntlBidi/IntlBidi___construct_basic.phpt | 3 +- .../IntlBidi_countParagraphs_basic.phpt | 35 ++++ .../IntlBidi/IntlBidi_countRuns_basic.phpt | 66 +++++++ .../IntlBidi_getBaseDirection_basic.phpt | 53 ++++++ .../IntlBidi_getCustomizedClass_basic.phpt | 12 ++ .../IntlBidi/IntlBidi_getDirection_basic.phpt | 178 ++++++++++++++++++ .../IntlBidi/IntlBidi_getLevelAt_basic.phpt | 43 +++++ .../IntlBidi_getResultLength_variant.phpt | 14 +- 8 files changed, 395 insertions(+), 9 deletions(-) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt index d2b1f547b1526..b010589dd3150 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt @@ -1,10 +1,9 @@ --TEST-- -Regression test for the UBA implementation. +Basic test to check the construction of IntlBidi. --CREDITS-- Timo Scholz --SKIPIF-- - --FILE-- +--SKIPIF-- + +--FILE-- +setPara('', IntlBidi::LTR, null); +var_dump($bidi->countParagraphs()); + +$text = "__ABC\u{001c}" /* Para #0 offset 0 */ + . "__\u{05d0}DE\u{001c}" /* 1 6 */ + . "__123\u{001c}" /* 2 12 */ + . "\r\n" /* 3 18 */ + . "FG\r" /* 4 20 */ + . "\r" /* 5 23 */ + . "HI\r\n" /* 6 24 */ + . "\r\n" /* 7 28 */ + . "\n" /* 8 30 */ + . "\n" /* 9 31 */ + . "JK\u{001c}"; /* 10 32 */ + +$bidi->setPara($text, IntlBidi::LTR, null); + +var_dump($bidi->countParagraphs()); +?> +==DONE== +--EXPECT-- +int(0) +int(11) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt new file mode 100644 index 0000000000000..5e79ceb201650 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test for IntlBidi countRuns +--CREDITS-- +Timo Scholz + +--SKIPIF-- + + +--FILE-- +setPara($string, 0); + + $runCount = $bidi->countRuns(); + $len = $bidi->getLength(); + + $run = new IntlBidi(); + for ($logicalIndex = 0; $logicalIndex < $len; ) { + $logicalIndex = $bidi->getLogicalRun($logicalIndex)['limit']; + + if (--$runCount < 0) { + throw new RuntimeException('Wrong number of runs compared to Bidi.countRuns()'); + } + } + if ($runCount > 0) { + throw new RuntimeException('Wrong number of runs compared to Bidi.countRuns()'); + } + + var_dump($runCount); +} + +doTest("Testen"); +doTest(pseudoToU8('del(KC)add(K.C.&)')); +doTest(pseudoToU8('del(QDVT) add(BVDL)')); +doTest(pseudoToU8('del(PQ)add(R.S.)T)U.&')); +doTest(pseudoToU8('del(LV)add(L.V.) L.V.&')); +doTest(pseudoToU8('day 0 R DPDHRVR dayabbr')); +doTest(pseudoToU8('day 1 H DPHPDHDA dayabbr')); +doTest(pseudoToU8('day 2 L DPBLENDA dayabbr')); +doTest(pseudoToU8('day 3 J DPJQVM dayabbr')); +doTest(pseudoToU8('day 4 I DPIQNF dayabbr')); +doTest(pseudoToU8('day 5 M DPMEG dayabbr')); +doTest(pseudoToU8('helloDPMEG')); +doTest(pseudoToU8('hello WXY')); +?> +==DONE== +--EXPECT-- +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +==DONE== diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt new file mode 100644 index 0000000000000..74d882e5051fa --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt @@ -0,0 +1,53 @@ ++--TEST-- +Test for IntlBidi getBaseDirection to verify string direction detection function. +This currently fails, i still need to check if the test has the wrong implementation or if Bidi is giving faulty results. +--CREDITS-- +Timo Scholz + +--SKIPIF-- + +--FILE-- +getBaseDirection("\u{0061}\u{0627}\u{0032}\u{06f3}\u{0061}\u{0034}")); +// arabic mixed +var_dump($bidi->getBaseDirection( "\u{0661}\u{0627}\u{0662}\u{06f3}\u{0061}\u{0664}")); +// hebrew mixed +var_dump($bidi->getBaseDirection("\u{05EA}\u{0627}\u{0662}\u{06f3}\u{0061}\u{0664}")); +// persian +var_dump($bidi->getBaseDirection("\u{0698}\u{067E}\u{0686}\u{06AF}")); +// hebrew +var_dump($bidi->getBaseDirection("\u{0590}\u{05D5}\u{05EA}\u{05F1}")); +// english +var_dump($bidi->getBaseDirection("\u{0071}\u{0061}\u{0066}")); + +// empty +var_dump($bidi->getBaseDirection('')); +// all wait Al (English digits) +var_dump($bidi->getBaseDirection("\u{0031}\u{0032}\u{0033}")); +// all weak Al (Arabic digits) +var_dump($bidi->getBaseDirection("\u{0663}\u{0664}\u{0665}")); +// english and hebrew +var_dump($bidi->getBaseDirection("\u{0071}\u{0590}\u{05D5}\u{05EA}\u{05F1}")); +// all english and last hebrew +var_dump($bidi->getBaseDirection("\u{0031}\u{0032}\u{0033}\u{05F1}")); +?> +==DONE== +--EXPECT-- +int(0) +int(1) +int(1) +int(1) +int(1) +int(0) +int(2) +int(2) +int(2) +int(0) +int(1) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt new file mode 100644 index 0000000000000..a3a878d13f9ca --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt @@ -0,0 +1,12 @@ ++--TEST-- +We keep this file to track untested/implemented features: + The method getCustomizedClass() will currently not work, because there's no setter method at all. +--SKIPIF-- + +--FILE-- + +==DONE== +--EXPECT-- +invalid +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt new file mode 100644 index 0000000000000..05ddae4939dab --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt @@ -0,0 +1,178 @@ ++--TEST-- +Test for IntlBidi countParagraphs +This currently fails, i still need to check if the test has the wrong implementation or if Bidi is giving faulty results. +--CREDITS-- +Timo Scholz + +--SKIPIF-- + +--FILE-- + $value) { + $buffer .= $charFromDirProp[$value]; + } + + return $buffer; +} + +// $charFromDirProp[$ES] = 0x2b; + +foreach ($testDirProps as $index => $dirProp) { + $bidi = new \IntlBidi(); + $bidi->setPara(iconv('UTF-16', 'UTF-8', getStringFromDirProps($dirProp)), $paraLevels[$index]); + $lineStart = $lineStarts[$index]; + if ($lineStart === -1) { + $line = $bidi; + } else { + $line = $bidi->setLine($lineStart, $lineLimits[$index]); + } + + var_dump($line->getDirection()); +} +?> +==DONE== +--EXPECT-- +int(0) +int(1) +int(2) +int(2) +int(2) +int(1) +int(1) +int(0) +int(2) +int(2) +int(2) +int(1) +int(2) +int(2) +int(2) +int(2) +int(2) +int(2) +int(2) +int(2) +int(2) +int(2) +int(1) +int(0) +int(2) +int(2) +int(2) +int(0) +==DONE== diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt new file mode 100644 index 0000000000000..2c0ac68a1fcfc --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test for IntlBidi getLevelAt +--CREDITS-- +Timo Scholz + +--SKIPIF-- + +--FILE-- +setPara("abc ", \IntlBidi::RTL, null); +$bidiLine = $bidi->setLine(0, 6); +for ($i = 3; $i < 6; $i++) { + var_dump($bidiLine->getLevelAt($i)); +} + +$bidi->setPara("abc def", \IntlBidi::RTL, null); +$bidiLine = $bidi->setLine(0, 6); +for ($i = 3; $i < 6; $i++) { + var_dump($bidiLine->getLevelAt($i)); +} + +$bidi->setPara("abcdefghi ", \IntlBidi::RTL, null); +$bidiLine = $bidi->setLine(0, 6); +for ($i = 3; $i < 6; $i++) { + var_dump($bidiLine->getLevelAt($i)); +} + +?> +==DONE== +--EXPECT-- +bool(0) +bool(0) +bool(0) +bool(1) +bool(1) +bool(1) +bool(2) +bool(2) +bool(2) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt index 1aa4ebf8e9aa7..fff9cd25c31e6 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt @@ -1,8 +1,5 @@ --TEST-- -This has wrong behaviour, since the bidi object of $bidi gets deleted, but actually should stay alive until $bidiLine2 gets deleted or $bidiLine2->setPara() gets called. -Or we return a completely different instance, just to make it easier to handle. (But this would disable "stacking" of the setLine() call. -Also we should change the name to getLine(). -http://icu-project.org/apiref/icu4c/ubidi_8h.html#a88693e5a8ad4be974dc90ec6b8db56df +Test for keeping the parent UBiDI instance. (fails) --CREDITS-- Timo Scholz --SKIPIF-- @@ -16,19 +13,22 @@ $bidi->setPara($str, IntlBidi::RTL); $bidi->setReorderingOptions(IntlBidi::REMOVE_BIDI_CONTROLS); var_dump($bidi->getResultLength()); -$bidiLine2 = $bidi->setLine(0, 6); +$bidiLine = $bidi->setLine(0, 6); var_dump($bidi->getResultLength()); +var_dump($bidiLine->getResultLength()); unset($bidi); gc_collect_cycles(); -gc_collect_cycles(); -var_dump($bidiLine2->getResultLength()); +var_dump($bidiLine->getResultLength()); + +unset($bidiLine); ?> ==DONE== --EXPECT-- int(14) int(14) int(5) +int(5) ==DONE== \ No newline at end of file From 6dcd0e451407583f379e0ad46360b7f31b395cce Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 20 Nov 2018 14:34:30 +0100 Subject: [PATCH 14/50] Renamed error method. Moved logic out of the constructor. Fixed the setContext parameters. Fixed the setPara parameters. Removed unnecessary comments. Added IntlBidi::getLength() --- ext/intl/bidi/bidi.c | 105 ++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index c8a1e1971cee6..fc526208cff04 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -44,12 +44,12 @@ static inline zend_object *bidi_object_to_zend_object(php_intl_bidi_object *obj) } #define THROW_UFAILURE(obj, fname, error) \ - php_bidi_throw_failure(obj, error, \ + php_intl_bidi_throw_failure(obj, error, \ "IntlBidi::" fname "() returned error " ZEND_LONG_FMT ": %s", \ (zend_long)error, u_errorName(error)) -/* {{{ php_bidi_throw_failure */ -static inline void php_bidi_throw_failure(php_intl_bidi_object *objval, +/* {{{ php_intl_bidi_throw_failure */ +static inline void php_intl_bidi_throw_failure(php_intl_bidi_object *objval, UErrorCode error, const char *format, ...) { intl_error *err = objval ? &(objval->error) : NULL; char message[1024]; @@ -64,6 +64,29 @@ static inline void php_bidi_throw_failure(php_intl_bidi_object *objval, } /* }}} */ +static inline void php_intl_bidi_invokeConstruction(zval * instance, zend_long maxRunCount, zend_long maxLength) { + UErrorCode error; + php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(instance)); + + if (PG(memory_limit) > 0) { + if (maxLength == 0) { + maxLength = PG(memory_limit) / 2; + } else if (maxLength > PG(memory_limit)) { + php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "IntlBidi::__construct() given maxLength greater than memory_limit"); + return; + } + } + + error = U_ZERO_ERROR; + + objval->bidi = ubidi_openSized(maxLength, maxRunCount, &error); + if (U_FAILURE(error)) { + THROW_UFAILURE(NULL, "__construct", error); + return; + } +} + /* {{{ proto void IntlBidi::__construct([int $maxLength = 0, [int $maxRunCount = 0]]) */ ZEND_BEGIN_ARG_INFO_EX(bidi_ctor_arginfo, 0, ZEND_RETURN_VALUE, 0) ZEND_ARG_TYPE_INFO(0, maxLength, IS_LONG, 0) @@ -71,8 +94,6 @@ ZEND_BEGIN_ARG_INFO_EX(bidi_ctor_arginfo, 0, ZEND_RETURN_VALUE, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, __construct) { zend_long maxLength = 0, maxRunCount = 0; - php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - UErrorCode error; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL @@ -81,33 +102,18 @@ static PHP_METHOD(IntlBidi, __construct) { ZEND_PARSE_PARAMETERS_END(); if (maxRunCount < 0) { - php_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, + php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, "IntlBidi::__construct() expects maxRunCount to be a non-negative value"); return; } if (maxLength < 0) { - php_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, + php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, "IntlBidi::__construct() expects maxLength to be a non-negative value"); return; } - if (PG(memory_limit) > 0) { - if (maxLength == 0) { - maxLength = PG(memory_limit) / 2; - } else if (maxLength > PG(memory_limit)) { - php_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "IntlBidi::__construct() given maxLength greater than memory_limit"); - return; - } - } - - error = U_ZERO_ERROR; - objval->bidi = ubidi_openSized(maxLength, maxRunCount, &error); - if (U_FAILURE(error)) { - THROW_UFAILURE(NULL, "__construct", error); - return; - } + php_intl_bidi_invokeConstruction(getThis(), maxLength, maxRunCount); } /* }}} */ @@ -233,8 +239,8 @@ static PHP_METHOD(IntlBidi, setContext) { ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STR_EX(prologue) - Z_PARAM_STR_EX(epilogue) + Z_PARAM_STR_EX(prologue, 0, 0) + Z_PARAM_STR_EX(epilogue, 0, 0) ZEND_PARSE_PARAMETERS_END(); if (prologue && ZSTR_LEN(prologue)) { @@ -307,7 +313,7 @@ static PHP_METHOD(IntlBidi, setPara) { Z_PARAM_STR(para) Z_PARAM_OPTIONAL Z_PARAM_LONG(paraLevel) - Z_PARAM_STR_EX(embeddingLevels) + Z_PARAM_STR_EX(embeddingLevels, 0, 0) ZEND_PARSE_PARAMETERS_END(); error = U_ZERO_ERROR; @@ -317,7 +323,6 @@ static PHP_METHOD(IntlBidi, setPara) { goto setPara_cleanup; } - // TODO: maybe check for the length of the embeddingLevels. if (embeddingLevels != NULL && ZSTR_LEN(embeddingLevels) > 0) { objval->embeddingLevels = (UBiDiLevel*)erealloc(objval->embeddingLevels, ZSTR_LEN(embeddingLevels)); memcpy(objval->embeddingLevels, ZSTR_VAL(embeddingLevels), ZSTR_LEN(embeddingLevels)); @@ -354,12 +359,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_setline_arginfo, ZEND_RETURN_VALUE, ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, setLine) { zend_long start, limit; + php_intl_bidi_object *objval, *lineval; + UErrorCode error; + zval retval; zend_function * constructor; zend_fcall_info fci; zend_fcall_info_cache fcc; - php_intl_bidi_object *objval, *lineval; - UErrorCode error; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_LONG(start) @@ -369,7 +375,6 @@ static PHP_METHOD(IntlBidi, setLine) { object_init_ex(return_value, php_intl_bidi_ce); - constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); fci.size = sizeof(fci); @@ -384,9 +389,12 @@ static PHP_METHOD(IntlBidi, setLine) { fcc.called_scope = Z_OBJCE_P(return_value); fcc.object = Z_OBJ_P(return_value); - int ret = zend_call_function(&fci, &fcc); + zend_call_function(&fci, &fcc); zval_ptr_dtor(&retval); + // php_intl_bidi_invokeConstruction(return_value, 0, 0); + // zval_ptr_dtor(return_value); + //TODO: keep objval alive while lineval is alive or setPara() gets called on lineval. // @see http://icu-project.org/apiref/icu4c/ubidi_8h.html#ac7d96b281cd6ab2d56900bfdc37c808a // altough i am not sure about "destroying" or "reusing" (if this is also the case when other functions get called)? @@ -395,14 +403,8 @@ static PHP_METHOD(IntlBidi, setLine) { // I tried to implement it, but i got stuck on that unset() resets the reference count. - objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - - if (ret == FAILURE) { - THROW_UFAILURE(objval, "setLine", ret); - goto setLine_cleanup; - } - - lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); +objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); + lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); error = U_ZERO_ERROR; ubidi_setLine(objval->bidi, start, limit - 1, lineval->bidi, &error); @@ -430,13 +432,13 @@ static PHP_METHOD(IntlBidi, getDirection) { /* }}} */ /* {{{ proto int IntlBidi::getBaseDirection(string $text) */ -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getbasedir_arginfo, ZEND_RETURN_VALUE, 0, IS_LONG, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getbasedir_arginfo, ZEND_RETURN_VALUE, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, text, IS_STRING, 0) ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getBaseDirection) { zend_string *text; UChar *utext = NULL; - int32_t utext_len; + int32_t utext_len = 0; UErrorCode error; ZEND_PARSE_PARAMETERS_START(1, 1) @@ -450,7 +452,9 @@ static PHP_METHOD(IntlBidi, getBaseDirection) { goto getBaseDirection_cleanup; } - RETURN_LONG(ubidi_getBaseDirection(utext, utext_len)); + zend_long result = ubidi_getBaseDirection(utext, utext_len); + //efree(utext); + RETURN_LONG(result); getBaseDirection_cleanup: if (utext) { @@ -784,7 +788,7 @@ static PHP_METHOD(IntlBidi, getCustomizedClass) { ZEND_PARSE_PARAMETERS_END(); if (ZSTR_LEN(text) > 4) { - php_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, + php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, "IntlChar::getCustomizedClass() requires precisely one unicode character as input"); return; } @@ -793,7 +797,7 @@ static PHP_METHOD(IntlBidi, getCustomizedClass) { U8_NEXT(ZSTR_VAL(text), pos, len, c); if ((size_t)pos != len) { - php_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, + php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, "IntlChar::getCustomizedClass() requires precisely one unicode character as input"); return; } @@ -840,7 +844,7 @@ static PHP_METHOD(IntlBidi, getReordered) { return; } - // HERE IT CRASHES WHEN RUNNING IntlBidi_getReordered_varian.phpt (not enough memory allocated for the string). + // HERE IT CRASHES WHEN RUNNING IntlBidi_getReordered_variant.phpt (not enough memory allocated for the string). error = U_ZERO_ERROR; ret = intl_convert_utf16_to_utf8(utext, utext_len, &error); efree(utext); @@ -853,6 +857,16 @@ static PHP_METHOD(IntlBidi, getReordered) { } /* }}} */ +// TODO: leave this in ??? this is a new feature. +/* {{{ proto int IntlBidi::getLength() */ +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getlength_arginfo, ZEND_RETURN_VALUE, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() +static PHP_METHOD(IntlBidi, getLength) { + php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); + if (zend_parse_parameters_none_throw() == FAILURE) { return; } + RETURN_LONG(ubidi_getLength(objval->bidi)); +} + static zend_function_entry bidi_methods[] = { PHP_ME(IntlBidi, __construct, bidi_ctor_arginfo, ZEND_ACC_CTOR | ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, setInverse, bidi_setinverse_arginfo, ZEND_ACC_PUBLIC) @@ -863,6 +877,7 @@ static zend_function_entry bidi_methods[] = { PHP_ME(IntlBidi, getReorderingMode, bidi_getreordermode_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, setReorderingOptions, bidi_setreorderopts_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getReorderingOptions, bidi_getreorderopts_arginfo, ZEND_ACC_PUBLIC) + PHP_ME(IntlBidi, getLength, bidi_getlength_arginfo, ZEND_ACC_PUBLIC) #if ((U_ICU_VERSION_MAJOR_NUM * 10) + U_ICU_VERSION_MINOR_NUM) >= 48 PHP_ME(IntlBidi, setContext, bidi_setctx_arginfo, ZEND_ACC_PUBLIC) #endif From 8874440e3dc76923cd72b5ba039fffa3495f88e6 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 20 Nov 2018 14:35:15 +0100 Subject: [PATCH 15/50] Removed comments. --- ext/intl/bidi/bidi.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index fc526208cff04..0bb92b869d477 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -392,9 +392,6 @@ static PHP_METHOD(IntlBidi, setLine) { zend_call_function(&fci, &fcc); zval_ptr_dtor(&retval); - // php_intl_bidi_invokeConstruction(return_value, 0, 0); - // zval_ptr_dtor(return_value); - //TODO: keep objval alive while lineval is alive or setPara() gets called on lineval. // @see http://icu-project.org/apiref/icu4c/ubidi_8h.html#ac7d96b281cd6ab2d56900bfdc37c808a // altough i am not sure about "destroying" or "reusing" (if this is also the case when other functions get called)? @@ -403,7 +400,7 @@ static PHP_METHOD(IntlBidi, setLine) { // I tried to implement it, but i got stuck on that unset() resets the reference count. -objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); + objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); error = U_ZERO_ERROR; @@ -857,7 +854,6 @@ static PHP_METHOD(IntlBidi, getReordered) { } /* }}} */ -// TODO: leave this in ??? this is a new feature. /* {{{ proto int IntlBidi::getLength() */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getlength_arginfo, ZEND_RETURN_VALUE, 0, IS_LONG, 0) ZEND_END_ARG_INFO() From 9229362518603743f8bbe4c9cfe0a101457721e7 Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Tue, 20 Nov 2018 16:22:00 +0100 Subject: [PATCH 16/50] Use FQN in constant --- ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt index cd80023501d71..d1df03db565e3 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt @@ -51,7 +51,7 @@ for ($testNumber = 0; $testNumber < $nTests; $testNumber++) { $bidi = new \IntlBidi(); $bidi->setInverse(true); - $levels = str_repeat("\0", IntlBidi::MAX_EXPLICIT_LEVEL); + $levels = str_repeat("\0", \IntlBidi::MAX_EXPLICIT_LEVEL); for ($i = 0; $i < 10; $i++) { $levels[$i] = chr($i + 1); } From e4f8844e9897c350d03e21e9fc39230d40e4df3a Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 20 Nov 2018 16:34:00 +0100 Subject: [PATCH 17/50] Added Copyright notice and source informations. --- .../IntlBidi_getBaseDirection_basic.phpt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt index 74d882e5051fa..fc7f3f7212ade 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt @@ -8,9 +8,19 @@ Timo Scholz --FILE-- Date: Tue, 20 Nov 2018 16:55:07 +0100 Subject: [PATCH 18/50] Update ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt Make test run. This actually fails because of a memory leak. Functionality is tested. --- .../IntlBidi_getBaseDirection_basic.phpt | 87 +++++++++++-------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt index fc7f3f7212ade..1d85372b2c4e4 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt @@ -1,6 +1,5 @@ -+--TEST-- +--TEST-- Test for IntlBidi getBaseDirection to verify string direction detection function. -This currently fails, i still need to check if the test has the wrong implementation or if Bidi is giving faulty results. --CREDITS-- Timo Scholz @@ -21,43 +20,59 @@ Timo Scholz * Ported from Java. * Original: https://github.com/unicode-org/icu/blob/778d0a6d1d46faa724ead19613bda84621794b72/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestBidi.java#L531 */ -$bidi = new IntlBidi(); - -//mixed english -var_dump($bidi->getBaseDirection("\u{0061}\u{0627}\u{0032}\u{06f3}\u{0061}\u{0034}")); -// arabic mixed -var_dump($bidi->getBaseDirection( "\u{0661}\u{0627}\u{0662}\u{06f3}\u{0061}\u{0664}")); -// hebrew mixed -var_dump($bidi->getBaseDirection("\u{05EA}\u{0627}\u{0662}\u{06f3}\u{0061}\u{0664}")); -// persian -var_dump($bidi->getBaseDirection("\u{0698}\u{067E}\u{0686}\u{06AF}")); -// hebrew -var_dump($bidi->getBaseDirection("\u{0590}\u{05D5}\u{05EA}\u{05F1}")); -// english -var_dump($bidi->getBaseDirection("\u{0071}\u{0061}\u{0066}")); +$bidi = new \IntlBidi(); + +// mixed start with L +var_dump($bidi->getBaseDirection("\u{0061}\u{0627}\u{0032}\u{06f3}\u{0061}\u{0034}") === \IntlBidi::LTR); +// mixed start with AL +var_dump($bidi->getBaseDirection( "\u{0661}\u{0627}\u{0662}\u{06f3}\u{0061}\u{0664}") === \IntlBidi::RTL); + +// mixed Start with R +var_dump($bidi->getBaseDirection("\u{05EA}\u{0627}\u{0662}\u{06f3}\u{0061}\u{0664}") === \IntlBidi::RTL); + +// all AL (Arabic. Persian) +var_dump($bidi->getBaseDirection("\u{0698}\u{067E}\u{0686}\u{06AF}") === \IntlBidi::RTL); + +// all R (Hebrew etc.) +var_dump($bidi->getBaseDirection("\u{0590}\u{05D5}\u{05EA}\u{05F1}") === \IntlBidi::RTL); + +// all L (English) +var_dump($bidi->getBaseDirection("\u{0071}\u{0061}\u{0066}") === \IntlBidi::LTR); + +// mixed start with weak AL an then L +var_dump($bidi->getBaseDirection("\u{0663}\u{0071}\u{0061}\u{0066}") === \IntlBidi::LTR); + +// mixed start with weak L and then AL */ +var_dump($bidi->getBaseDirection("\u{0031}\u{0698}\u{067E}\u{0686}\u{06AF}") === \IntlBidi::RTL); // empty -var_dump($bidi->getBaseDirection('')); -// all wait Al (English digits) -var_dump($bidi->getBaseDirection("\u{0031}\u{0032}\u{0033}")); -// all weak Al (Arabic digits) -var_dump($bidi->getBaseDirection("\u{0663}\u{0664}\u{0665}")); -// english and hebrew -var_dump($bidi->getBaseDirection("\u{0071}\u{0590}\u{05D5}\u{05EA}\u{05F1}")); -// all english and last hebrew -var_dump($bidi->getBaseDirection("\u{0031}\u{0032}\u{0033}\u{05F1}")); +var_dump($bidi->getBaseDirection('') === \IntlBidi::NEUTRAL); + +// all weak L (English digits) +var_dump($bidi->getBaseDirection("\u{0031}\u{0032}\u{0033}") === \IntlBidi::NEUTRAL); + +// all weak AL (Arabic digits) +var_dump($bidi->getBaseDirection("\u{0663}\u{0664}\u{0665}") === \IntlBidi::NEUTRAL); + +// first L (English) others are R (Hebrew etc.) +var_dump($bidi->getBaseDirection("\u{0071}\u{0590}\u{05D5}\u{05EA}\u{05F1}") === \IntlBidi::LTR); + +// last R (Hebrew etc.) others are weak L (English Digits) +var_dump($bidi->getBaseDirection("\u{0031}\u{0032}\u{0033}\u{05F1}") === \IntlBidi::RTL); ?> ==DONE== --EXPECT-- -int(0) -int(1) -int(1) -int(1) -int(1) -int(0) -int(2) -int(2) -int(2) -int(0) -int(1) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) ==DONE== \ No newline at end of file From 172566d9e3d3d1ea80b54f04e206121eddfa5a78 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 20 Nov 2018 17:05:11 +0100 Subject: [PATCH 19/50] Removed IntlBidi::getCustomizedClass() + code style. --- ext/intl/bidi/bidi.c | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 0bb92b869d477..74fcacd3cf8c4 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -449,9 +449,7 @@ static PHP_METHOD(IntlBidi, getBaseDirection) { goto getBaseDirection_cleanup; } - zend_long result = ubidi_getBaseDirection(utext, utext_len); - //efree(utext); - RETURN_LONG(result); + RETURN_LONG(ubidi_getBaseDirection(utext, utext_len)); getBaseDirection_cleanup: if (utext) { @@ -769,40 +767,6 @@ static PHP_METHOD(IntlBidi, getResultLength) { } /* }}} */ -/* {{{ proto int IntlBidi::getCustomizedClass(string $char) */ -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getcustomclass_arginfo, ZEND_RETURN_VALUE, 1, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, character, IS_STRING, 0) -ZEND_END_ARG_INFO(); -static PHP_METHOD(IntlBidi, getCustomizedClass) { - php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - zend_string *text; - int32_t pos = 0; - size_t len; - UChar32 c; - - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(text) - ZEND_PARSE_PARAMETERS_END(); - - if (ZSTR_LEN(text) > 4) { - php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "IntlChar::getCustomizedClass() requires precisely one unicode character as input"); - return; - } - - len = ZSTR_LEN(text); - - U8_NEXT(ZSTR_VAL(text), pos, len, c); - if ((size_t)pos != len) { - php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "IntlChar::getCustomizedClass() requires precisely one unicode character as input"); - return; - } - - RETURN_LONG(ubidi_getCustomizedClass(objval->bidi, c)); -} -/* }}} */ - /* {{{ proto string IntlBidi::getReordered(int $options) */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getreordered_arginfo, ZEND_RETURN_VALUE, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, options, IS_LONG, 0) @@ -896,7 +860,6 @@ static zend_function_entry bidi_methods[] = { PHP_ME(IntlBidi, getVisualMap, bidi_getvisualmap_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getProcessedLength, bidi_getprocessedlen_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getResultLength, bidi_getresultlen_arginfo, ZEND_ACC_PUBLIC) - PHP_ME(IntlBidi, getCustomizedClass, bidi_getcustomclass_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getReordered, bidi_getreordered_arginfo, ZEND_ACC_PUBLIC) PHP_FE_END From 2711a106cc7c7392990fcea116294d21b3a93f33 Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Tue, 20 Nov 2018 17:09:40 +0100 Subject: [PATCH 20/50] Deleted obsolete test Method was removed because it is useless unless getClassCallback() and setClassCallback() are implemented. --- .../IntlBidi/IntlBidi_getCustomizedClass_basic.phpt | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt deleted file mode 100644 index a3a878d13f9ca..0000000000000 --- a/ext/intl/tests/IntlBidi/IntlBidi_getCustomizedClass_basic.phpt +++ /dev/null @@ -1,12 +0,0 @@ -+--TEST-- -We keep this file to track untested/implemented features: - The method getCustomizedClass() will currently not work, because there's no setter method at all. ---SKIPIF-- - ---FILE-- - -==DONE== ---EXPECT-- -invalid -==DONE== \ No newline at end of file From 47bf0763f4104cd5148818264ed640173898e61f Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Wed, 21 Nov 2018 08:29:39 +0100 Subject: [PATCH 21/50] Added Copyright notices to tests. --- ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt | 1 + .../IntlBidi_countParagraphs_basic.phpt | 14 ++++++++++++++ .../IntlBidi/IntlBidi_countRuns_basic.phpt | 14 +++++++++++++- .../IntlBidi/IntlBidi_getDirection_basic.phpt | 14 +++++++++++++- .../IntlBidi/IntlBidi_getLevelAt_basic.phpt | 13 +++++++++++++ .../IntlBidi/IntlBidi_getReordered_basic.phpt | 1 + .../IntlBidi_getResultLength_basic.phpt | 19 ++++++++++++++----- 7 files changed, 69 insertions(+), 7 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt index d1df03db565e3..e5743eb48c5dc 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt @@ -21,6 +21,7 @@ Timo Scholz * Original: https://github.com/unicode-org/icu/blob/master/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestReorder.java */ +// include helper functions include 'IntlBidi_ut_common.inc'; // --- INIT TEST DATA --- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt index e5620174edb12..8a270781914a6 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt @@ -7,6 +7,20 @@ Timo Scholz --FILE-- setPara('', IntlBidi::LTR, null); diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt index 5e79ceb201650..bc17cd0139cea 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt @@ -8,6 +8,19 @@ Timo Scholz --FILE-- countRuns(); $len = $bidi->getLength(); - $run = new IntlBidi(); for ($logicalIndex = 0; $logicalIndex < $len; ) { $logicalIndex = $bidi->getLogicalRun($logicalIndex)['limit']; diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt index 05ddae4939dab..5ed736203842b 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt @@ -8,7 +8,19 @@ Timo Scholz --FILE-- --FILE-- * Original: https://github.com/unicode-org/icu/blob/master/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestReorder.java */ +// include helper functions include 'IntlBidi_ut_common.inc'; // --- INIT TEST DATA --- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt index c8b1c8dc8e8e1..ec0c663fb8434 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt @@ -6,6 +6,20 @@ Timo Scholz --FILE-- setLine(0, 6); var_dump($bidi->getResultLength()); var_dump($bidiLine2->getResultLength()); -unset($bidiLine2); -gc_collect_cycles(); -var_dump($bidi->getResultLength()); -unset($bidi); -gc_collect_cycles(); ?> ==DONE== From a84a7dcb571d8f0eeaafd363266e3b66ab013d59 Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 21 Nov 2018 10:01:47 +0100 Subject: [PATCH 22/50] Added and optimized various tests --- .../IntlBidi/IntlBidi_countRuns_variant.phpt | 32 ++++ .../IntlBidi/IntlBidi_getDirection_basic.phpt | 152 +++++++++--------- .../IntlBidi_getReordered_basic5.phpt | 88 ++++++++++ .../IntlBidi_getReordered_variant1.phpt | 39 +++++ .../IntlBidi_getReordered_variant3.phpt | 34 ++++ .../IntlBidi_getReordered_variant4.phpt | 34 ++++ .../IntlBidi/IntlBidi_setLine_basic.phpt | 25 +++ .../IntlBidi/IntlBidi_setPara_variant.phpt | 31 ++++ 8 files changed, 363 insertions(+), 72 deletions(-) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt new file mode 100644 index 0000000000000..8edfa3c1c49a1 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt @@ -0,0 +1,32 @@ +--TEST-- +Check 1-char runs with RUNS_ONLY +--CREDITS-- +Timo Scholz + +--SKIPIF-- + +--FILE-- +setReorderingMode(IntlBidi::REORDER_RUNS_ONLY); +$bidi->setPara("a \u{05d0} b \u{05d1} c \u{05d2} d ", IntlBidi::LTR); +var_dump($bidi->countRuns()); +?> +==DONE== +--EXPECT-- +int(14) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt index 5ed736203842b..8caba6e6f0bfe 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt @@ -1,4 +1,4 @@ -+--TEST-- +--TEST-- Test for IntlBidi countParagraphs This currently fails, i still need to check if the test has the wrong implementation or if Bidi is giving faulty results. --CREDITS-- @@ -21,43 +21,34 @@ Timo Scholz * Ported from Java. * Original: https://github.com/unicode-org/icu/blob/778d0a6d1d46faa724ead19613bda84621794b72/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestBidi.java */ -$lineStarts = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 13, 2, 0, 0, -1, -1]; +// https://github.com/unicode-org/icu/blob/778d0a6d1d46faa724ead19613bda84621794b72/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestData.java#L23 +$L = \IntlChar::CHAR_DIRECTION_LEFT_TO_RIGHT; +$R = \IntlChar::CHAR_DIRECTION_RIGHT_TO_LEFT; +$EN = \IntlChar::CHAR_DIRECTION_EUROPEAN_NUMBER; +$ES = \IntlChar::CHAR_DIRECTION_EUROPEAN_NUMBER_SEPARATOR; +$ET = \IntlChar::CHAR_DIRECTION_EUROPEAN_NUMBER_TERMINATOR; +$AN = \IntlChar::CHAR_DIRECTION_ARABIC_NUMBER; +$CS = \IntlChar::CHAR_DIRECTION_COMMON_NUMBER_SEPARATOR; +$B = \IntlChar::CHAR_DIRECTION_BLOCK_SEPARATOR; +$S = \IntlChar::CHAR_DIRECTION_SEGMENT_SEPARATOR; +$WS = \IntlChar::CHAR_DIRECTION_WHITE_SPACE_NEUTRAL; +$ON = \IntlChar::CHAR_DIRECTION_OTHER_NEUTRAL; +$LRE = \IntlChar::CHAR_DIRECTION_LEFT_TO_RIGHT_EMBEDDING; +$LRO = \IntlChar::CHAR_DIRECTION_LEFT_TO_RIGHT_OVERRIDE; +$AL = \IntlChar::CHAR_DIRECTION_RIGHT_TO_LEFT_ARABIC; +$RLE = \IntlChar::CHAR_DIRECTION_RIGHT_TO_LEFT_EMBEDDING; +$RLO = \IntlChar::CHAR_DIRECTION_RIGHT_TO_LEFT_OVERRIDE; +$PDF = \IntlChar::CHAR_DIRECTION_POP_DIRECTIONAL_FORMAT; +$NSM = \IntlChar::CHAR_DIRECTION_DIR_NON_SPACING_MARK; +$BN = \IntlChar::CHAR_DIRECTION_BOUNDARY_NEUTRAL; +$FSI = \IntlChar::CHAR_DIRECTION_FIRST_STRONG_ISOLATE; +$LRI = \IntlChar::CHAR_DIRECTION_LEFT_TO_RIGHT_ISOLATE; +$RLI = \IntlChar::CHAR_DIRECTION_RIGHT_TO_LEFT_ISOLATE; +$PDI = \IntlChar::CHAR_DIRECTION_POP_DIRECTIONAL_ISOLATE; -$lineLimits = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 14, 3, 8, 8, -1, -1]; - -$paraLevels = [ - IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, - IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, 64, 64, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_RTL, - 2, 5, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, - IntlBidi::DEFAULT_LTR, IntlBidi::RTL, IntlBidi::LTR, IntlBidi::RTL, IntlBidi::DEFAULT_LTR -]; - -$L = 0; -$R = 1; -$EN = 2; -$ES = 3; -$ET = 4; -$AN = 5; -$CS = 6; -$B = 7; -$S = 8; -$WS = 9; -$ON = 10; -$LRE = 11; -$LRO = 12; -$AL = 13; -$RLE = 14; -$RLO = 15; -$PDF = 16; -$NSM = 17; -$BN = 18; -$FSI = 19; -$LRI = 20; -$RLI = 21; -$PDI = 22; - -$DEF = 19; +$DEF = \IntlChar::CHAR_DIRECTION_CHAR_DIRECTION_COUNT; // why ever this is 19 in Java +// https://github.com/unicode-org/icu/blob/778d0a6d1d46faa724ead19613bda84621794b72/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestData.java#L53 $testDirProps = [ [$L, $L, $WS, $L, $WS, $EN, $L, $B], [$R, $AL, $WS, $R, $AL, $WS, $R], @@ -121,10 +112,35 @@ $testDirProps = [ [$L], ]; +$paraLevels = [ + IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, + IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, + IntlBidi::DEFAULT_LTR, 64, 64, + IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_RTL, + 2, 5, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, + IntlBidi::DEFAULT_LTR, IntlBidi::DEFAULT_LTR, IntlBidi::RTL, IntlBidi::LTR, IntlBidi::RTL, + IntlBidi::DEFAULT_LTR +]; + +$testDirections = [ + \IntlBidi::LTR, \IntlBidi::RTL, \IntlBidi::LTR, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, + \IntlBidi::RTL, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, + \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::RTL, + \IntlBidi::LTR, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::MIXED, \IntlBidi::LTR +]; + +$lineStarts = [ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 13, + 2, 0, 0, -1, -1 +]; + +$lineLimits = [ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 14, + 3, 8, 8, -1, -1 +]; function getStringFromDirProps($dirProp) { - $charFromDirProp = [ /* L R EN ES ET AN CS B S WS ON */ 0x61, 0x5d0, 0x30, 0x2f, 0x25, 0x660, 0x2c, 0xa, 0x9, 0x20, 0x26, @@ -135,18 +151,16 @@ function getStringFromDirProps($dirProp) ]; $buffer = ''; - foreach ($dirProp as $key => $value) { - $buffer .= $charFromDirProp[$value]; + foreach ($dirProp as $value) { + $buffer .= \IntlChar::chr($charFromDirProp[$value]); } return $buffer; } -// $charFromDirProp[$ES] = 0x2b; - -foreach ($testDirProps as $index => $dirProp) { +for ($index = 0, $indexMax = count($testDirProps); $index < $indexMax; $index++) { $bidi = new \IntlBidi(); - $bidi->setPara(iconv('UTF-16', 'UTF-8', getStringFromDirProps($dirProp)), $paraLevels[$index]); + $bidi->setPara(getStringFromDirProps($testDirProps[$index]), $paraLevels[$index]); $lineStart = $lineStarts[$index]; if ($lineStart === -1) { $line = $bidi; @@ -154,37 +168,31 @@ foreach ($testDirProps as $index => $dirProp) { $line = $bidi->setLine($lineStart, $lineLimits[$index]); } - var_dump($line->getDirection()); + var_dump($line->getDirection() === $testDirections[$index]); } ?> ==DONE== --EXPECT-- -int(0) -int(1) -int(2) -int(2) -int(2) -int(1) -int(1) -int(0) -int(2) -int(2) -int(2) -int(1) -int(2) -int(2) -int(2) -int(2) -int(2) -int(2) -int(2) -int(2) -int(2) -int(2) -int(1) -int(0) -int(2) -int(2) -int(2) -int(0) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) ==DONE== diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt new file mode 100644 index 0000000000000..c95cbadc9093a --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt @@ -0,0 +1,88 @@ +--TEST-- +Test inverse Bidi with marks and contextual orientation. +--CREDITS-- +Timo Scholz , Jan Slabon +--SKIPIF-- + + +--FILE-- +setReorderingMode(\IntlBidi::REORDER_INVERSE_LIKE_DIRECT); +$bidi->setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS); + +$bidi->setPara(''); +var_dump($bidi->getReordered(0) === ''); + +$bidi->setPara(' ', \IntlBidi::DEFAULT_RTL); +var_dump($bidi->getReordered(0) === ' '); + +$bidi->setPara("abc", \IntlBidi::DEFAULT_RTL); +var_dump($bidi->getReordered(0) === 'abc'); + +$bidi->setPara("\u{05d0}\u{05d1}", \IntlBidi::DEFAULT_RTL); +var_dump($bidi->getReordered(0) === "\u{05d1}\u{05d0}"); + +$bidi->setPara("abc \u{05d0}\u{05d1}", \IntlBidi::DEFAULT_RTL); +var_dump($bidi->getReordered(0) === "\u{05d1}\u{05d0} abc"); + +$bidi->setPara("\u{05d0}\u{05d1} abc", \IntlBidi::DEFAULT_RTL); +var_dump($bidi->getReordered(0) === "\u{200f}abc \u{05d1}\u{05d0}"); + +$bidi->setPara("\u{05d0}\u{05d1} abc .-=", \IntlBidi::DEFAULT_RTL); +var_dump($bidi->getReordered(0) === "\u{200f}=-. abc \u{05d1}\u{05d0}"); + +$bidi->orderParagraphsLTR(true); + +// THIS ONE CURRENTLY RAISES A BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant1.phpt +//$bidi->setPara("\n\r \n\rabc\n\u{05d0}\u{05d1}\rabc \u{05d2}\u{05d3}\n\r" . +// "\u{05d4}\u{05d5} abc\n\u{05d6}\u{05d7} abc .-=\r\n" . +// "-* \u{05d8}\u{05d9} abc .-=", \IntlBidi::DEFAULT_RTL); +//$expectedResult = "\n\r \n\rabc\n\u{05d1}\u{05d0}\r\u{05d3}\u{05d2} abc\n\r" . +// "\u{200f}abc \u{05d5}\u{05d4}\n\u{200f}=-. abc \u{05d7}\u{05d6}\r\n" . +// "\u{200f}=-. abc \u{05d9}\u{05d8} *-"; +//var_dump($bidi->getReordered(0) === $expectedResult); + +$bidi->setPara("\u{05d0} \t", \IntlBidi::LTR); +var_dump($bidi->getReordered(0) === "\u{05d0}\u{200e} \t"); + +// THIS ONE CURRENTLY RAISES A BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant3.phpt +//$bidi->setPara("\u{05d0} 123 \t\u{05d1} 123 \u{05d2}", \IntlBidi::LTR); +//var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123\u{200e} \t\u{05d2} 123 \u{05d1}"); + +// THIS ONE CURRENTLY RAISES A BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant4.phpt +//$bidi->setPara("\u{05d0} 123 \u{0660}\u{0661} ab", \IntlBidi::LTR); +//var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123 \u{200e}\u{0660}\u{0661} ab"); + +$bidi->setPara("ab \t", \IntlBidi::RTL); +var_dump($bidi->getReordered(0) === "\u{200f}\t ab"); + +?> +==DONE== +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt new file mode 100644 index 0000000000000..b24e013cc4087 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt @@ -0,0 +1,39 @@ +--TEST-- +U_BUFFER_OVERFLOW_ERROR error. +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +setReorderingMode(\IntlBidi::REORDER_INVERSE_LIKE_DIRECT); +$bidi->setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS); +$bidi->orderParagraphsLTR(true); + +$bidi->setPara("\n\r \n\rabc\n\u{05d0}\u{05d1}\rabc \u{05d2}\u{05d3}\n\r" . + "\u{05d4}\u{05d5} abc\n\u{05d6}\u{05d7} abc .-=\r\n" . + "-* \u{05d8}\u{05d9} abc .-=", \IntlBidi::DEFAULT_RTL); +$expectedResult = "\n\r \n\rabc\n\u{05d1}\u{05d0}\r\u{05d3}\u{05d2} abc\n\r" . + "\u{200f}abc \u{05d5}\u{05d4}\n\u{200f}=-. abc \u{05d7}\u{05d6}\r\n" . + "\u{200f}=-. abc \u{05d9}\u{05d8} *-"; +var_dump($bidi->getReordered(0) === $expectedResult); +?> +==DONE== +--EXPECT-- +bool(true) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt new file mode 100644 index 0000000000000..8a35f49e30836 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt @@ -0,0 +1,34 @@ +--TEST-- +U_BUFFER_OVERFLOW_ERROR error. +--CREDITS-- +Jan Slabon +--SKIPIF-- + +--FILE-- +setReorderingMode(\IntlBidi::REORDER_INVERSE_LIKE_DIRECT); +$bidi->setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS); +$bidi->orderParagraphsLTR(true); + +$bidi->setPara("\u{05d0} 123 \t\u{05d1} 123 \u{05d2}", \IntlBidi::LTR); +var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123\u{200e} \t\u{05d2} 123 \u{05d1}"); +?> +==DONE== +--EXPECT-- +bool(true) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt new file mode 100644 index 0000000000000..38988401b83f1 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt @@ -0,0 +1,34 @@ +--TEST-- +U_BUFFER_OVERFLOW_ERROR error. +--CREDITS-- +Jan Slabon +--SKIPIF-- + +--FILE-- +setReorderingMode(\IntlBidi::REORDER_INVERSE_LIKE_DIRECT); +$bidi->setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS); +$bidi->orderParagraphsLTR(true); + +$bidi->setPara("\u{05d0} 123 \u{0660}\u{0661} ab", \IntlBidi::LTR); +var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123 \u{200e}\u{0660}\u{0661} ab"); +?> +==DONE== +--EXPECT-- +bool(true) +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt new file mode 100644 index 0000000000000..5d37a9e9b80a1 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +Simple test for setLine +--CREDITS-- +Timo Scholz + +--SKIPIF-- + +--FILE-- +setPara('abcde'); + +$line = $bidi->setLine(0, 2); +var_dump($line->getReordered(0)); + +$line = $bidi->setLine(0, 1); +var_dump($line->getReordered(0)); + +?> +==DONE== +--EXPECT-- +string(2) "ab" +string(1) "a" +==DONE== + diff --git a/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt new file mode 100644 index 0000000000000..72495eb46f141 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt @@ -0,0 +1,31 @@ +--TEST-- +Check exceeding para level +--CREDITS-- +Timo Scholz + +--SKIPIF-- + +--FILE-- +setPara("A\u{202a}\u{05d0}\u{202a}C\u{202c}\u{05d1}\u{202c}E", IntlBidi::MAX_EXPLICIT_LEVEL - 1); +var_dump($bidi->getLevelAt(2) === IntlBidi::MAX_EXPLICIT_LEVEL); +?> +==DONE== +--EXPECT-- +bool(true) +==DONE== From da78f5ea5cfc986fc13b0141d67cbe61cd93a9d1 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Wed, 21 Nov 2018 12:21:25 +0100 Subject: [PATCH 23/50] Fixed bug in IntlBidi::setLine() Fixed memory leak in IntlBidi::getBaseDirection() Fixed memory allocation IntlBidi::getReordered() --- ext/intl/bidi/bidi.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 74fcacd3cf8c4..03b3fde2d8ed1 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -404,7 +404,7 @@ static PHP_METHOD(IntlBidi, setLine) { lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); error = U_ZERO_ERROR; - ubidi_setLine(objval->bidi, start, limit - 1, lineval->bidi, &error); + ubidi_setLine(objval->bidi, start, limit, lineval->bidi, &error); if (U_FAILURE(error)) { THROW_UFAILURE(objval, "setLine", error); goto setLine_cleanup; @@ -449,7 +449,11 @@ static PHP_METHOD(IntlBidi, getBaseDirection) { goto getBaseDirection_cleanup; } - RETURN_LONG(ubidi_getBaseDirection(utext, utext_len)); + zend_long result = ubidi_getBaseDirection(utext, utext_len); + + efree(utext); + + RETVAL_LONG(result); getBaseDirection_cleanup: if (utext) { @@ -783,7 +787,10 @@ static PHP_METHOD(IntlBidi, getReordered) { Z_PARAM_LONG(options) ZEND_PARSE_PARAMETERS_END(); - if (options & UBIDI_INSERT_LRM_FOR_NUMERIC) { + if ( + (options & UBIDI_INSERT_LRM_FOR_NUMERIC) == UBIDI_INSERT_LRM_FOR_NUMERIC || + (ubidi_getReorderingOptions(objval->bidi) & UBIDI_OPTION_INSERT_MARKS) == UBIDI_OPTION_INSERT_MARKS + ) { error = U_ZERO_ERROR; utext_len = ubidi_getLength(objval->bidi) + (2 * ubidi_countRuns(objval->bidi, &error)); if (U_FAILURE(error)) { @@ -798,14 +805,13 @@ static PHP_METHOD(IntlBidi, getReordered) { utext = safe_emalloc(sizeof(UChar), utext_len, sizeof(UChar)); error = U_ZERO_ERROR; - utext_len = ubidi_writeReordered(objval->bidi, utext, utext_len + 1, options, &error); + utext_len = ubidi_writeReordered(objval->bidi, utext, utext_len, options, &error); if (U_FAILURE(error)) { efree(utext); THROW_UFAILURE(objval, "getReordered", error); return; } - // HERE IT CRASHES WHEN RUNNING IntlBidi_getReordered_variant.phpt (not enough memory allocated for the string). error = U_ZERO_ERROR; ret = intl_convert_utf16_to_utf8(utext, utext_len, &error); efree(utext); From e45a19731d7297fb57052cfa811cff7e91b92bd0 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Wed, 21 Nov 2018 12:24:49 +0100 Subject: [PATCH 24/50] Updated tests --- .../IntlBidi/IntlBidi_getLevelAt_basic.phpt | 28 +++++++-------- .../IntlBidi_getReordered_variant.phpt | 6 ++-- .../IntlBidi_getReordered_variant5.phpt | 36 +++++++++++++++++++ .../IntlBidi_getResultLength_basic.phpt | 8 +---- .../IntlBidi_getResultLength_variant.phpt | 4 +-- 5 files changed, 56 insertions(+), 26 deletions(-) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt index 1cff5108afaa3..aafb4d858b609 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt @@ -18,39 +18,39 @@ Timo Scholz */ /** * Ported from Java. - * Original: https://github.com/unicode-org/icu/blob/778d0a6d1d46faa724ead19613bda84621794b72/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestBidi.java#L380 + * Original: https://github.com/unicode-org/icu/blob/778d0a6d1d46faa724ead19613bda84621794b72/icu4j/main/tests/core/src/com/ibm/icu/dev/test/bidi/TestBidi.java#L397 */ $bidi = new \IntlBidi(); -$bidi->setPara("abc ", \IntlBidi::RTL, null); +$bidi->setPara("abc ", \IntlBidi::RTL); $bidiLine = $bidi->setLine(0, 6); for ($i = 3; $i < 6; $i++) { - var_dump($bidiLine->getLevelAt($i)); + var_dump($bidiLine->getLevelAt($i) === \IntlBidi::RTL); } $bidi->setPara("abc def", \IntlBidi::RTL, null); $bidiLine = $bidi->setLine(0, 6); for ($i = 3; $i < 6; $i++) { - var_dump($bidiLine->getLevelAt($i)); + var_dump($bidiLine->getLevelAt($i) === \IntlBidi::RTL); } $bidi->setPara("abcdefghi ", \IntlBidi::RTL, null); $bidiLine = $bidi->setLine(0, 6); for ($i = 3; $i < 6; $i++) { - var_dump($bidiLine->getLevelAt($i)); + var_dump($bidiLine->getLevelAt($i) === \IntlBidi::MIXED); } ?> ==DONE== --EXPECT-- -bool(0) -bool(0) -bool(0) -bool(1) -bool(1) -bool(1) -bool(2) -bool(2) -bool(2) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) ==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt index 4fbe9cf5eb810..10f4482faf9b6 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant.phpt @@ -1,5 +1,5 @@ --TEST-- -U_BUFFER_OVERFLOW_ERROR error. (IS EMBEDDED IN OTHER TEST, BUT EXTRACTED AND REDUCED FOR SIMPLICITY) +Test getReordered() with previous setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS). --CREDITS-- Timo Scholz --SKIPIF-- @@ -10,8 +10,8 @@ $bidi = new \IntlBidi(); $bidi->setReorderingMode(\IntlBidi::REORDER_RUNS_ONLY); $bidi->setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS); -$bidi->setPara('ab 234' . "\x20\xD9\xA8\xD9\xA9\xD9\xA6" . 'de', 0); -var_dump(bin2hex($bidi->getReordered(\IntlBidi::DO_MIRRORING))); // U_BUFFER_OVERFLOW_ERROR +$bidi->setPara('ab 234 ' . "\xD9\xA8\xD9\xA9\xD9\xA6" . 'de', 0); +var_dump(bin2hex($bidi->getReordered(\IntlBidi::DO_MIRRORING))); ?> ==DONE== --EXPECT-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt new file mode 100644 index 0000000000000..0a51b895748c2 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test getReordered() with previous setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS) + \IntlBidi::INSERT_LRM_FOR_NUMERIC in $options argument. +--CREDITS-- +Timo Scholz +--SKIPIF-- + +--FILE-- +setReorderingMode(\IntlBidi::REORDER_RUNS_ONLY); +$bidi->setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS); + +$bidi->setPara(hex2bin('61622032333420e2808ed9a8d9a9d9a6e2808e6465'), 0); +$bidi->setInverse(true); +$a = $bidi->getReordered(\IntlBidi::DO_MIRRORING); +$b = $bidi->getReordered(\IntlBidi::DO_MIRRORING | \IntlBidi::INSERT_LRM_FOR_NUMERIC); +// because \IntlBidi::OPTION_INSERT_MARKS isset we've no difference +var_dump($a === $b); +var_dump(bin2hex($a)); + +// reset the global reordering options +$bidi->setReorderingOptions(\IntlBidi::OPTION_DEFAULT); +$a = $bidi->getReordered(\IntlBidi::DO_MIRRORING); +$b = $bidi->getReordered(\IntlBidi::DO_MIRRORING | \IntlBidi::INSERT_LRM_FOR_NUMERIC); +var_dump($a === $b); // false +var_dump(bin2hex($a)); +var_dump(bin2hex($b)); +?> +==DONE== +--EXPECT-- +bool(true) +string(48) "61622032333420e2808ee2808ed9a8d9a9d9a6e2808e6465" +bool(false) +string(30) "61622032333420d9a8d9a9d9a66465" +string(48) "61622032333420e2808ee2808ed9a8d9a9d9a6e2808e6465" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt index ec0c663fb8434..58cbec973a80a 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_basic.phpt @@ -28,16 +28,10 @@ $bidi->setReorderingOptions(IntlBidi::REMOVE_BIDI_CONTROLS); var_dump($bidi->getResultLength()); $bidiLine2 = $bidi->setLine(0, 6); -var_dump($bidi->getResultLength()); var_dump($bidiLine2->getResultLength()); - - - ?> ==DONE== --EXPECT-- int(14) -int(14) -int(5) -int(14) +int(6) ==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt index fff9cd25c31e6..f1efaa3e739a9 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getResultLength_variant.phpt @@ -29,6 +29,6 @@ unset($bidiLine); --EXPECT-- int(14) int(14) -int(5) -int(5) +int(6) +int(6) ==DONE== \ No newline at end of file From c18d367747fe4428e059f2ca0c76b91d4d28120c Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Wed, 21 Nov 2018 13:19:54 +0100 Subject: [PATCH 25/50] Updated test name --- ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt index 8caba6e6f0bfe..2735c8f9de07f 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt @@ -1,6 +1,5 @@ --TEST-- -Test for IntlBidi countParagraphs -This currently fails, i still need to check if the test has the wrong implementation or if Bidi is giving faulty results. +Test for IntlBidi getDirection --CREDITS-- Timo Scholz From 208aeb4af75619f6538d4c1676629af083c8d039 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Wed, 21 Nov 2018 13:20:33 +0100 Subject: [PATCH 26/50] Removed zend-callstack object generation from IntlBidi::setLine() --- ext/intl/bidi/bidi.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 03b3fde2d8ed1..ee94022588b07 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -362,11 +362,6 @@ static PHP_METHOD(IntlBidi, setLine) { php_intl_bidi_object *objval, *lineval; UErrorCode error; - zval retval; - zend_function * constructor; - zend_fcall_info fci; - zend_fcall_info_cache fcc; - ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_LONG(start) Z_PARAM_LONG(limit) @@ -374,23 +369,7 @@ static PHP_METHOD(IntlBidi, setLine) { object_init_ex(return_value, php_intl_bidi_ce); - - constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value)); - - fci.size = sizeof(fci); - ZVAL_UNDEF(&fci.function_name); - fci.object = Z_OBJ_P(return_value); - fci.retval = &retval; - fci.param_count = 0; - fci.params = NULL; - fci.no_separation = 1; - - fcc.function_handler = constructor; - fcc.called_scope = Z_OBJCE_P(return_value); - fcc.object = Z_OBJ_P(return_value); - - zend_call_function(&fci, &fcc); - zval_ptr_dtor(&retval); + php_intl_bidi_invokeConstruction(return_value, 0, 0);; //TODO: keep objval alive while lineval is alive or setPara() gets called on lineval. // @see http://icu-project.org/apiref/icu4c/ubidi_8h.html#ac7d96b281cd6ab2d56900bfdc37c808a From 757ceb51b6506961b4b43ddcf2b214cbb618ae6d Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 21 Nov 2018 15:00:44 +0100 Subject: [PATCH 27/50] Tweaks in tests Fixed format of test files. Better test titles. Enabled tests for fixed bugs. --- .../IntlBidi_countParagraphs_basic.phpt | 3 +- .../IntlBidi/IntlBidi_countRuns_basic.phpt | 5 ++- .../IntlBidi/IntlBidi_countRuns_variant.phpt | 3 +- .../IntlBidi_getBaseDirection_basic.phpt | 3 +- .../IntlBidi/IntlBidi_getDirection_basic.phpt | 3 +- .../IntlBidi/IntlBidi_getLevelAt_basic.phpt | 3 +- .../IntlBidi_getReordered_basic5.phpt | 31 ++++++++++--------- .../IntlBidi_getReordered_variant1.phpt | 4 +-- .../IntlBidi_getReordered_variant2.phpt | 3 +- .../IntlBidi_getReordered_variant3.phpt | 2 +- .../IntlBidi_getReordered_variant4.phpt | 2 +- .../IntlBidi_getReordered_variant5.phpt | 2 +- 12 files changed, 30 insertions(+), 34 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt index 8a270781914a6..acf9272553385 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt @@ -1,8 +1,7 @@ --TEST-- Test for IntlBidi countParagraphs --CREDITS-- -Timo Scholz - +Timo Scholz --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt index bc17cd0139cea..abe9f93c267b8 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt @@ -1,8 +1,7 @@ --TEST-- Test for IntlBidi countRuns --CREDITS-- -Timo Scholz - +Timo Scholz --SKIPIF-- @@ -25,7 +24,7 @@ Timo Scholz include 'IntlBidi_ut_common.inc'; function doTest($string) { - $bidi = new IntlBidi(); + $bidi = new \IntlBidi(); $bidi->setPara($string, 0); diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt index 8edfa3c1c49a1..cf1b4e379be0d 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_countRuns_variant.phpt @@ -1,8 +1,7 @@ --TEST-- Check 1-char runs with RUNS_ONLY --CREDITS-- -Timo Scholz - +Timo Scholz --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt index 1d85372b2c4e4..b7ceeeb033972 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getBaseDirection_basic.phpt @@ -1,8 +1,7 @@ --TEST-- Test for IntlBidi getBaseDirection to verify string direction detection function. --CREDITS-- -Timo Scholz - +Timo Scholz --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt index 8caba6e6f0bfe..9be5f08713cc6 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getDirection_basic.phpt @@ -2,8 +2,7 @@ Test for IntlBidi countParagraphs This currently fails, i still need to check if the test has the wrong implementation or if Bidi is giving faulty results. --CREDITS-- -Timo Scholz - +Timo Scholz --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt index aafb4d858b609..240966ef8d281 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getLevelAt_basic.phpt @@ -1,8 +1,7 @@ --TEST-- Test for IntlBidi getLevelAt --CREDITS-- -Timo Scholz - +Timo Scholz , Jan Slabon --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt index c95cbadc9093a..eacdd73cad112 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt @@ -50,25 +50,25 @@ var_dump($bidi->getReordered(0) === "\u{200f}=-. abc \u{05d1}\u{05d0}"); $bidi->orderParagraphsLTR(true); -// THIS ONE CURRENTLY RAISES A BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant1.phpt -//$bidi->setPara("\n\r \n\rabc\n\u{05d0}\u{05d1}\rabc \u{05d2}\u{05d3}\n\r" . -// "\u{05d4}\u{05d5} abc\n\u{05d6}\u{05d7} abc .-=\r\n" . -// "-* \u{05d8}\u{05d9} abc .-=", \IntlBidi::DEFAULT_RTL); -//$expectedResult = "\n\r \n\rabc\n\u{05d1}\u{05d0}\r\u{05d3}\u{05d2} abc\n\r" . -// "\u{200f}abc \u{05d5}\u{05d4}\n\u{200f}=-. abc \u{05d7}\u{05d6}\r\n" . -// "\u{200f}=-. abc \u{05d9}\u{05d8} *-"; -//var_dump($bidi->getReordered(0) === $expectedResult); +// This had raised a BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant1.phpt + $bidi->setPara("\n\r \n\rabc\n\u{05d0}\u{05d1}\rabc \u{05d2}\u{05d3}\n\r" . + "\u{05d4}\u{05d5} abc\n\u{05d6}\u{05d7} abc .-=\r\n" . + "-* \u{05d8}\u{05d9} abc .-=", \IntlBidi::DEFAULT_RTL); +$expectedResult = "\n\r \n\rabc\n\u{05d1}\u{05d0}\r\u{05d3}\u{05d2} abc\n\r" . + "\u{200f}abc \u{05d5}\u{05d4}\n\u{200f}=-. abc \u{05d7}\u{05d6}\r\n" . + "\u{200f}=-. abc \u{05d9}\u{05d8} *-"; +var_dump($bidi->getReordered(0) === $expectedResult); $bidi->setPara("\u{05d0} \t", \IntlBidi::LTR); var_dump($bidi->getReordered(0) === "\u{05d0}\u{200e} \t"); -// THIS ONE CURRENTLY RAISES A BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant3.phpt -//$bidi->setPara("\u{05d0} 123 \t\u{05d1} 123 \u{05d2}", \IntlBidi::LTR); -//var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123\u{200e} \t\u{05d2} 123 \u{05d1}"); +// This had raised a BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant3.phpt +$bidi->setPara("\u{05d0} 123 \t\u{05d1} 123 \u{05d2}", \IntlBidi::LTR); +var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123\u{200e} \t\u{05d2} 123 \u{05d1}"); -// THIS ONE CURRENTLY RAISES A BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant4.phpt -//$bidi->setPara("\u{05d0} 123 \u{0660}\u{0661} ab", \IntlBidi::LTR); -//var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123 \u{200e}\u{0660}\u{0661} ab"); +// This had raised a BUFFER OVERFLOW ERROR: see IntlBidi_getReordered_variant4.phpt +$bidi->setPara("\u{05d0} 123 \u{0660}\u{0661} ab", \IntlBidi::LTR); +var_dump($bidi->getReordered(0) === "\u{05d0} \u{200e}123 \u{200e}\u{0660}\u{0661} ab"); $bidi->setPara("ab \t", \IntlBidi::RTL); var_dump($bidi->getReordered(0) === "\u{200f}\t ab"); @@ -85,4 +85,7 @@ bool(true) bool(true) bool(true) bool(true) +bool(true) +bool(true) +bool(true) ==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt index b24e013cc4087..9f37d64d71747 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant1.phpt @@ -1,7 +1,7 @@ --TEST-- -U_BUFFER_OVERFLOW_ERROR error. +This tests triggered a U_BUFFER_OVERFLOW_ERROR error during implementation. --CREDITS-- -Timo Scholz +Jan Slabon --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt index 24d721231710b..31b35a912f4a9 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant2.phpt @@ -1,5 +1,5 @@ --TEST-- -U_ZERO_ERROR error. (IS EMBEDDED IN OTHER TEST, BUT EXTRACTED AND REDUCED FOR SIMPLICITY) +This tests raised an U_ZERO_ERROR error during implementation. --CREDITS-- Timo Scholz --SKIPIF-- @@ -8,7 +8,6 @@ Timo Scholz setPara('', \IntlBidi::DEFAULT_LTR); -// TODO: this function throws a U_ZERO_ERROR exception. var_dump($bidi->getReordered(\IntlBidi::INSERT_LRM_FOR_NUMERIC)); ?> ==DONE== diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt index 8a35f49e30836..f529b8dc4311c 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant3.phpt @@ -1,5 +1,5 @@ --TEST-- -U_BUFFER_OVERFLOW_ERROR error. +This tests triggered a U_BUFFER_OVERFLOW_ERROR error during implementation. --CREDITS-- Jan Slabon --SKIPIF-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt index 38988401b83f1..e781e106d7f22 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant4.phpt @@ -1,5 +1,5 @@ --TEST-- -U_BUFFER_OVERFLOW_ERROR error. +This tests triggered a U_BUFFER_OVERFLOW_ERROR error during implementation. --CREDITS-- Jan Slabon --SKIPIF-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt index 0a51b895748c2..d5b63fe2f28d3 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant5.phpt @@ -1,7 +1,7 @@ --TEST-- Test getReordered() with previous setReorderingOptions(\IntlBidi::OPTION_INSERT_MARKS) + \IntlBidi::INSERT_LRM_FOR_NUMERIC in $options argument. --CREDITS-- -Timo Scholz +Timo Scholz , Jan Slabon --SKIPIF-- --FILE-- From 94e781284f2690e8f703f3c39b53aca4b1a38c60 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Wed, 21 Nov 2018 15:31:08 +0100 Subject: [PATCH 28/50] Code style. --- ext/intl/bidi/bidi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index ee94022588b07..5bf48f397d313 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -367,7 +367,6 @@ static PHP_METHOD(IntlBidi, setLine) { Z_PARAM_LONG(limit) ZEND_PARSE_PARAMETERS_END(); - object_init_ex(return_value, php_intl_bidi_ce); php_intl_bidi_invokeConstruction(return_value, 0, 0);; @@ -376,7 +375,7 @@ static PHP_METHOD(IntlBidi, setLine) { // altough i am not sure about "destroying" or "reusing" (if this is also the case when other functions get called)? // it should be right to return a new istance, insteadof overriding a old one, to prevent circular references. // also setPara should not be callable while an object gets referenced, or the referenced objects need to be reset. - // I tried to implement it, but i got stuck on that unset() resets the reference count. + // I tried to implement it, but got stuck on collecting the leftovers. objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); From 7243c93a7a5a2397693b8a2b1702d68c96977ffd Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 21 Nov 2018 16:20:05 +0100 Subject: [PATCH 29/50] Code style --- ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt | 2 +- ext/intl/tests/IntlBidi/IntlBidi_basic.phpt | 4 ++-- ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt | 4 ++-- ext/intl/tests/IntlBidi/IntlBidi_countRuns_basic.phpt | 2 +- ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic.phpt | 4 ++-- ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic1.phpt | 4 ++-- ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic2.phpt | 4 ++-- ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic3.phpt | 4 ++-- ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic4.phpt | 4 ++-- ext/intl/tests/IntlBidi/IntlBidi_getReordered_basic5.phpt | 4 ++-- .../tests/IntlBidi/IntlBidi_orderParagraphsLTR_basic.phpt | 4 ++-- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt index b010589dd3150..1d3965cbd4361 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi___construct_basic.phpt @@ -3,7 +3,7 @@ Basic test to check the construction of IntlBidi. --CREDITS-- Timo Scholz --SKIPIF-- - + --FILE-- --SKIPIF-- - - + + --FILE-- --SKIPIF-- - - + + --FILE-- --SKIPIF-- - + --FILE-- --SKIPIF-- - - + + --FILE-- --SKIPIF-- - - + + --FILE-- --SKIPIF-- - - + + --FILE-- --SKIPIF-- - - + + --FILE-- --SKIPIF-- - - + + --FILE-- , Jan Slabon --SKIPIF-- - - + + --FILE-- --SKIPIF-- - - + + --FILE-- Date: Wed, 21 Nov 2018 16:21:51 +0100 Subject: [PATCH 30/50] Added test for inverse behavior --- .../IntlBidi_getReordered_variant6.phpt | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant6.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant6.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant6.phpt new file mode 100644 index 0000000000000..7531d3cef8417 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant6.phpt @@ -0,0 +1,70 @@ +--TEST-- +Test inverse behavior +--CREDITS-- +Timo Scholz , Jan Slabon +--SKIPIF-- + + +--FILE-- +setPara($original); +$result = $bidi->getReordered(0); +var_dump(u8ToPseudo($result) === ")&.C.K(add)CK("); + +$bidi->setPara($result); +$bidi->setInverse(true); +$result = $bidi->getReordered(0); +var_dump($original === $result); + +// \IntlBidi::DO_MIRRORING +$bidi->setInverse(false); +$bidi->setPara($original); +$result = $bidi->getReordered(\IntlBidi::DO_MIRRORING); +var_dump(u8ToPseudo($result) === "(&.C.K)add(CK)"); + +$bidi->setPara($result); +$bidi->setInverse(true); +$result = $bidi->getReordered(\IntlBidi::DO_MIRRORING); +var_dump($original === $result); + +// \IntlBidi::OUTPUT_REVERSE +$bidi->setInverse(false); +$bidi->setPara($original); +$result = $bidi->getReordered(\IntlBidi::OUTPUT_REVERSE); +var_dump(u8ToPseudo($result) === "(KC)dda(K.C.&)"); + +$bidi->setPara($result); +$bidi->setInverse(true); +$result = $bidi->getReordered(\IntlBidi::OUTPUT_REVERSE); +var_dump($original === $result); + +// \IntlBidi::DO_MIRRORING | \IntlBidi::OUTPUT_REVERSE +$bidi->setInverse(false); +$bidi->setPara($original); +$result = $bidi->getReordered(\IntlBidi::DO_MIRRORING | \IntlBidi::OUTPUT_REVERSE); +var_dump(u8ToPseudo($result) === ")KC(dda)K.C.&("); + +$bidi->setPara($result); +$bidi->setInverse(true); +$result = $bidi->getReordered(\IntlBidi::DO_MIRRORING | \IntlBidi::OUTPUT_REVERSE); +var_dump($original === $result); + +?> +==DONE== +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +==DONE== \ No newline at end of file From db9528b9486073ccaf4002de89a3bfe1749d6dc7 Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 21 Nov 2018 21:07:42 +0100 Subject: [PATCH 31/50] Added test For IntlBidi::getVisualIndex(), IntlBidi::getLogicalIndex(), IntlBidi::getLogicMap(), IntlBidi::getVisualMap() --- .../IntlBidi_getMapsAndIndexes_basic.phpt | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getMapsAndIndexes_basic.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getMapsAndIndexes_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getMapsAndIndexes_basic.phpt new file mode 100644 index 0000000000000..0fca08d485482 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getMapsAndIndexes_basic.phpt @@ -0,0 +1,128 @@ +--TEST-- +Test for IntlBidi::getVisualIndex(), IntlBidi::getLogicalIndex(), IntlBidi::getLogicMap(), IntlBidi::getVisualMap() +--CREDITS-- +Jan Slabon +--SKIPIF-- + + +--FILE-- +setPara($string); + +$logicalMap = $bidi->getLogicalMap(); +$visualMap = $bidi->getVisualMap(); + +var_dump(count($logicalMap)); +var_dump($bidi->getProcessedLength() === count($logicalMap)); + +// We do cross checks in both tables and getter methods: +foreach ($chars as $logicalIndex => $char) { + $visualIndex = $bidi->getVisualIndex($logicalIndex); + var_dump($visualIndex === $logicalMap[$visualMap[$visualIndex]]); + var_dump($visualIndex === $logicalMap[$logicalIndex]); + var_dump($logicalIndex === $bidi->getLogicalIndex($visualIndex)); +} + +// That's how this is done manually/reproducable: + +//var_dump(u8ToPseudo($bidi->getReordered(0))); + +//$logicalIndex = 0; // ( +//$visualIndex = $bidi->getVisualIndex($logicalIndex); +//var_dump($visualIndex === 13, $visualIndex === $logicalMap[$logicalIndex]); +//var_dump($visualIndex === $logicalMap[$logicalIndex]); +//var_dump($bidi->getLogicalIndex($visualIndex) === $logicalIndex); +// +//$logicalIndex = 1; // K +//$visualIndex = $bidi->getVisualIndex($logicalIndex); +//var_dump($visualIndex === 12, $visualIndex === $logicalMap[$visualMap[$visualIndex]]); +//var_dump($visualIndex === $logicalMap[$logicalIndex]); +//var_dump($bidi->getLogicalIndex($visualIndex) === $logicalIndex); +// +//$logicalIndex = 2; // C +//$visualIndex = $bidi->getVisualIndex($logicalIndex); +//var_dump($visualIndex === 11, $visualIndex === $logicalMap[$visualMap[$visualIndex]]); +//var_dump($visualIndex === $logicalMap[$logicalIndex]); +//var_dump($bidi->getLogicalIndex($visualIndex) === $logicalIndex); +// +//$logicalIndex = 3; // ) +//$visualIndex = $bidi->getVisualIndex($logicalIndex); +//var_dump($visualIndex === 10, $visualIndex === $logicalMap[$visualMap[$visualIndex]]); +//var_dump($bidi->getLogicalIndex($visualIndex) === $logicalIndex); +// +//$logicalIndex = 4; // a +//$visualIndex = $bidi->getVisualIndex($logicalIndex); +//var_dump($visualIndex === 7, $visualIndex === $logicalMap[$visualMap[$visualIndex]]); +//var_dump($bidi->getLogicalIndex($visualIndex) === $logicalIndex); +// +//$logicalIndex = 5; // d +//$visualIndex = $bidi->getVisualIndex($logicalIndex); +//var_dump($visualIndex === 8, $visualIndex === $logicalMap[$visualMap[$visualIndex]]); +//var_dump($bidi->getLogicalIndex($visualIndex) === $logicalIndex); +// +//$logicalIndex = 6; // d +//$visualIndex = $bidi->getVisualIndex($logicalIndex); +//var_dump($visualIndex === 9, $visualIndex === $logicalMap[$visualMap[$visualIndex]]); +//var_dump($bidi->getLogicalIndex($visualIndex) === $logicalIndex); + +// ... + +//var_dump($logicalMap); +//var_dump($visualMap); + +?> +==DONE== +--EXPECT-- +int(14) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +==DONE== From 76469026be3166427a5d845c161fa7aeec9fe876 Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 21 Nov 2018 22:57:30 +0100 Subject: [PATCH 32/50] Added and optimized various tests --- .../IntlBidi_countParagraphs_basic.phpt | 22 ++-- .../IntlBidi/IntlBidi_getLevels_basic.phpt | 78 ++++++++++++++ .../IntlBidi/IntlBidi_getParaX_variant.phpt | 101 ++++++++++++++++++ .../IntlBidi/IntlBidi_setLine_basic.phpt | 3 +- .../IntlBidi/IntlBidi_setPara_variant.phpt | 3 +- .../IntlBidi/IntlBidi_setPara_variant1.phpt | 45 ++++++++ 6 files changed, 237 insertions(+), 15 deletions(-) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getLevels_basic.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getParaX_variant.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_setPara_variant1.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt index acf9272553385..ca230d0468e43 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_countParagraphs_basic.phpt @@ -25,17 +25,17 @@ $bidi = new \IntlBidi(); $bidi->setPara('', IntlBidi::LTR, null); var_dump($bidi->countParagraphs()); -$text = "__ABC\u{001c}" /* Para #0 offset 0 */ - . "__\u{05d0}DE\u{001c}" /* 1 6 */ - . "__123\u{001c}" /* 2 12 */ - . "\r\n" /* 3 18 */ - . "FG\r" /* 4 20 */ - . "\r" /* 5 23 */ - . "HI\r\n" /* 6 24 */ - . "\r\n" /* 7 28 */ - . "\n" /* 8 30 */ - . "\n" /* 9 31 */ - . "JK\u{001c}"; /* 10 32 */ +$text = "__ABC\u{001c}" /* Para #0 offset 0 */ + . "__\u{05d0}DE\u{001c}" /* 1 6 */ + . "__123\u{001c}" /* 2 12 */ + . "\r\n" /* 3 18 */ + . "FG\r" /* 4 20 */ + . "\r" /* 5 23 */ + . "HI\r\n" /* 6 24 */ + . "\r\n" /* 7 28 */ + . "\n" /* 8 30 */ + . "\n" /* 9 31 */ + . "JK\u{001c}"; /* 10 32 */ $bidi->setPara($text, IntlBidi::LTR, null); diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getLevels_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getLevels_basic.phpt new file mode 100644 index 0000000000000..c557efe716880 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getLevels_basic.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test IntlBidi::getLevels() method +--CREDITS-- +Jan Slabon +--SKIPIF-- + + +--FILE-- +setPara($string); + +$levels = $bidi->getLevels(); + +var_dump(strlen($levels) === strlen($original)); + +for ($i = 0, $len = strlen($levels); $i < $len; $i++) { + echo $original[$i] . ': ' . bin2hex($levels[$i]) . "\n"; +} + +echo "\n"; + +// do the with level set to RTL +$bidi = new \IntlBidi(); +$bidi->setPara($string, \IntlBidi::RTL); +$levels = $bidi->getLevels(); + +for ($i = 0, $len = strlen($levels); $i < $len; $i++) { + echo $original[$i] . ': ' . bin2hex($levels[$i]) . "\n"; +} + +?> +==DONE== +--EXPECT-- +bool(true) +d: 00 +e: 00 +l: 00 +(: 00 +K: 01 +C: 01 +): 00 +a: 00 +d: 00 +d: 00 +(: 00 +K: 01 +.: 01 +C: 01 +.: 01 +&: 01 +): 00 + +d: 02 +e: 02 +l: 02 +(: 01 +K: 01 +C: 01 +): 01 +a: 02 +d: 02 +d: 02 +(: 01 +K: 01 +.: 01 +C: 01 +.: 01 +&: 01 +): 01 +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getParaX_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getParaX_variant.phpt new file mode 100644 index 0000000000000..13405b2cd0e96 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getParaX_variant.phpt @@ -0,0 +1,101 @@ +--TEST-- +Test IntlBidi::getPara*() methods: getParaLevel(), getParagraph(), getParagraphByIndex() +--CREDITS-- +Jan Slabon +--SKIPIF-- + +--FILE-- +setPara($string); +var_dump($bidi->getParagraph(0)); +var_dump($bidi->getParaLevel() === \IntlBidi::LTR); +echo "\n"; + +$bidi->setPara($string, \IntlBidi::RTL); +var_dump($bidi->getParagraph(5)); +var_dump($bidi->getParaLevel() === \IntlBidi::RTL); +echo "\n"; + +$bidi->setPara("ABC\r\nDEF"); +var_dump($bidi->getParagraph(4)); // position of the block separator +var_dump($bidi->getParagraphByIndex(0)); +echo "\n"; + +var_dump($bidi->getParagraph(5)); // position after the block separator +var_dump($bidi->getParagraphByIndex(1)); + + +echo "\n"; +?> +==DONE== +--EXPECT-- +array(4) { + ["index"]=> + int(0) + ["start"]=> + int(0) + ["limit"]=> + int(13) + ["level"]=> + int(0) +} +bool(true) + +array(4) { + ["index"]=> + int(0) + ["start"]=> + int(0) + ["limit"]=> + int(13) + ["level"]=> + int(1) +} +bool(true) + +array(4) { + ["index"]=> + int(0) + ["start"]=> + int(0) + ["limit"]=> + int(5) + ["level"]=> + int(0) +} +array(4) { + ["index"]=> + int(0) + ["start"]=> + int(0) + ["limit"]=> + int(5) + ["level"]=> + int(0) +} + +array(4) { + ["index"]=> + int(1) + ["start"]=> + int(5) + ["limit"]=> + int(8) + ["level"]=> + int(0) +} +array(4) { + ["index"]=> + int(1) + ["start"]=> + int(5) + ["limit"]=> + int(8) + ["level"]=> + int(0) +} + +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt index 5d37a9e9b80a1..c7ecdb87ed126 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_setLine_basic.phpt @@ -1,8 +1,7 @@ --TEST-- Simple test for setLine --CREDITS-- -Timo Scholz - +Timo Scholz --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt index 72495eb46f141..8a371d8c469e0 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant.phpt @@ -1,8 +1,7 @@ --TEST-- Check exceeding para level --CREDITS-- -Timo Scholz - +Timo Scholz --SKIPIF-- --FILE-- diff --git a/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant1.phpt new file mode 100644 index 0000000000000..46e7e29fc5e82 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_setPara_variant1.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test the behavior of the $embeddingLevels argument +--CREDITS-- +Jan Slabon +--SKIPIF-- + + +--FILE-- +setPara($string, 0, $embeddingLevels); +var_dump(u8ToPseudo($bidi->getReordered(0))); + +// let's revert the levels: +$embeddingLevels[0] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::RTL); // a + +$embeddingLevels[2] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::LTR); // K +$embeddingLevels[3] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::LTR); // C + +$embeddingLevels[5] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::RTL); // a +$embeddingLevels[6] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::RTL); // d +$embeddingLevels[7] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::RTL); // d + +$embeddingLevels[9] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::LTR); // K +$embeddingLevels[10] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::LTR); // . +$embeddingLevels[11] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::LTR); // C +$embeddingLevels[12] = chr(\IntlBidi::LEVEL_OVERRIDE | \IntlBidi::LTR); // . + +$bidi->setPara($string, \IntlBidi::DEFAULT_LTR | \IntlBidi::LEVEL_OVERRIDE, $embeddingLevels); +var_dump(u8ToPseudo($bidi->getReordered(0))); +?> +==DONE== +--EXPECT-- +string(13) "a CK add C.K." +string(13) "a KC dda K.C." +==DONE== From 54cbaa1a891e2a2d7aeca8555fcf5dcb6e2d2dad Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 21 Nov 2018 23:08:00 +0100 Subject: [PATCH 33/50] Added test for getVisualRun() method. --- .../IntlBidi/IntlBidi_getVisualRun_basic.phpt | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getVisualRun_basic.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getVisualRun_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getVisualRun_basic.phpt new file mode 100644 index 0000000000000..1169c85ad8878 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getVisualRun_basic.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test IntlBidi::getVisualRun() method. +--CREDITS-- +Jan Slabon +--SKIPIF-- + + +--FILE-- +setPara($string); + +var_dump($bidi->countRuns()); // 5 + +var_dump($bidi->getVisualRun(0)); // del( +var_dump($bidi->getVisualRun(1)); // KC +var_dump($bidi->getVisualRun(2)); // )add( +var_dump($bidi->getVisualRun(3)); // K.C.& +var_dump($bidi->getVisualRun(4)); // ) + +?> +==DONE== +--EXPECT-- +int(5) +array(3) { + ["start"]=> + int(0) + ["length"]=> + int(4) + ["direction"]=> + int(0) +} +array(3) { + ["start"]=> + int(4) + ["length"]=> + int(2) + ["direction"]=> + int(1) +} +array(3) { + ["start"]=> + int(6) + ["length"]=> + int(5) + ["direction"]=> + int(0) +} +array(3) { + ["start"]=> + int(11) + ["length"]=> + int(5) + ["direction"]=> + int(1) +} +array(3) { + ["start"]=> + int(16) + ["length"]=> + int(1) + ["direction"]=> + int(0) +} +==DONE== \ No newline at end of file From 22c1f5d7c75875801b686dc0fc17cd1121e3d999 Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 21 Nov 2018 23:25:22 +0100 Subject: [PATCH 34/50] Added test for IntlBidi::getProcessedLength() method --- .../IntlBidi_getProcessedLength_basic.phpt | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt new file mode 100644 index 0000000000000..d9be5fa69f0dc --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test IntlBidi::getProcessedLength() method. +--CREDITS-- +Jan Slabon +--SKIPIF-- + + +--FILE-- +setPara('testen'); +var_dump($bidi->getProcessedLength()); // 6 +// 'del(KC)add(K.C.&)' + +$string = pseudoToU8('del(KC)'); +$bidi->setPara($string); +var_dump($bidi->getProcessedLength()); // 7 + +$string = pseudoToU8('(K.C.&)'); +$bidi->setPara($string); +var_dump($bidi->getProcessedLength()); // 7 + + +$bidi->setReorderingOptions(\IntlBidi::OPTION_STREAMING); +// meaningful boundary +$bidi->setPara('abcdefghijklmnopqrstuvwxyz'); +var_dump($bidi->getProcessedLength()); // 0 + +$string = "testen\ntesten\ntesten"; +$len = strlen($string); +$bidi->setPara($string); +var_dump($bidi->getProcessedLength()); // 14 +// turn streaming off before getting the last part of the text +$bidi->setReorderingOptions(\IntlBidi::OPTION_DEFAULT); +$bidi->setPara(substr($string, 14, $len - 14)); +var_dump($bidi->getProcessedLength()); // 6 + +?> +==DONE== +--EXPECT-- +int(6) +int(7) +int(7) +int(0) +int(14) +int(6) +==DONE== \ No newline at end of file From 6b2a29e819557b60516e40839b02946c1580c88e Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Thu, 22 Nov 2018 08:26:29 +0100 Subject: [PATCH 35/50] Test optimizations --- ...tlBidi_getParaX_variant.phpt => IntlBidi_getParaX_basic.phpt} | 0 ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt | 1 - 2 files changed, 1 deletion(-) rename ext/intl/tests/IntlBidi/{IntlBidi_getParaX_variant.phpt => IntlBidi_getParaX_basic.phpt} (100%) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getParaX_variant.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getParaX_basic.phpt similarity index 100% rename from ext/intl/tests/IntlBidi/IntlBidi_getParaX_variant.phpt rename to ext/intl/tests/IntlBidi/IntlBidi_getParaX_basic.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt index d9be5fa69f0dc..bc4a5f6a746f3 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getProcessedLength_basic.phpt @@ -15,7 +15,6 @@ $bidi = new \IntlBidi(); $bidi->setPara('testen'); var_dump($bidi->getProcessedLength()); // 6 -// 'del(KC)add(K.C.&)' $string = pseudoToU8('del(KC)'); $bidi->setPara($string); From f984ec7c6b53bc6a1d79aa0eb66edca4ce787442 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Fri, 30 Nov 2018 08:45:45 +0100 Subject: [PATCH 36/50] Implemented parent managemant. --- ext/intl/bidi/bidi.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 5bf48f397d313..240e259483f49 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -32,6 +32,7 @@ typedef struct _php_intl_bidi_object { UBiDiLevel *embeddingLevels; UChar *prologue, *text, *epilogue; intl_error error; + zend_object * parent; zend_object std; } php_intl_bidi_object; @@ -368,18 +369,12 @@ static PHP_METHOD(IntlBidi, setLine) { ZEND_PARSE_PARAMETERS_END(); object_init_ex(return_value, php_intl_bidi_ce); - php_intl_bidi_invokeConstruction(return_value, 0, 0);; - - //TODO: keep objval alive while lineval is alive or setPara() gets called on lineval. - // @see http://icu-project.org/apiref/icu4c/ubidi_8h.html#ac7d96b281cd6ab2d56900bfdc37c808a - // altough i am not sure about "destroying" or "reusing" (if this is also the case when other functions get called)? - // it should be right to return a new istance, insteadof overriding a old one, to prevent circular references. - // also setPara should not be callable while an object gets referenced, or the referenced objects need to be reset. - // I tried to implement it, but got stuck on collecting the leftovers. - + php_intl_bidi_invokeConstruction(return_value, 0, 0); objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); + lineval->parent = Z_OBJ_P(getThis()); + GC_ADDREF(lineval->parent); error = U_ZERO_ERROR; ubidi_setLine(objval->bidi, start, limit, lineval->bidi, &error); @@ -875,7 +870,12 @@ static void bidi_object_dtor(zend_object *obj) { if (objval->epilogue) { efree(objval->epilogue); } if (objval->embeddingLevels) { efree(objval->embeddingLevels); } + if (objval->parent) { + GC_DELREF(objval->parent); + } + intl_error_reset(&(objval->error)); + zend_object_release(obj); } PHP_MINIT_FUNCTION(intl_bidi) { From 47e7e36325b500b993c078e49cc84b2be29de16e Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Fri, 30 Nov 2018 08:46:06 +0100 Subject: [PATCH 37/50] Optimized Code style. --- ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt index 48172382daed3..9f7e33f07a097 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_basic1.phpt @@ -56,6 +56,7 @@ for ($testNumber = 0; $testNumber < $nTests; $testNumber++) { for ($i = 0; $i < 10; $i++) { $levels[$i] = chr($i + 1); } + $bidi->setPara($srcUt8, \IntlBidi::DEFAULT_LTR, $levels); $result = u8ToPseudo($bidi->getReordered(\IntlBidi::DO_MIRRORING | \IntlBidi::REMOVE_BIDI_CONTROLS)); var_dump($result); From bd93331bf77c75f8bc5b41af725c76ea6e1c7bfb Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 09:09:50 +0100 Subject: [PATCH 38/50] Decoupled bidi instance from the zend_object. --- ext/intl/bidi/bidi.c | 201 +++++++++++++++++++++++++------------------ 1 file changed, 116 insertions(+), 85 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 240e259483f49..72b1212179b5f 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -27,12 +27,16 @@ zend_class_entry *php_intl_bidi_ce; static zend_object_handlers bidi_object_handlers; -typedef struct _php_intl_bidi_object { +typedef struct _bidi_object { UBiDi *bidi; UBiDiLevel *embeddingLevels; + int32_t textLength; UChar *prologue, *text, *epilogue; intl_error error; - zend_object * parent; +} bidi_object; + +typedef struct _php_intl_bidi_object { + bidi_object * bidi; zend_object std; } php_intl_bidi_object; @@ -50,9 +54,9 @@ static inline zend_object *bidi_object_to_zend_object(php_intl_bidi_object *obj) (zend_long)error, u_errorName(error)) /* {{{ php_intl_bidi_throw_failure */ -static inline void php_intl_bidi_throw_failure(php_intl_bidi_object *objval, +static inline void php_intl_bidi_throw_failure(bidi_object *obj, UErrorCode error, const char *format, ...) { - intl_error *err = objval ? &(objval->error) : NULL; + intl_error *err = obj ? &(obj->error) : NULL; char message[1024]; va_list vargs; @@ -81,7 +85,7 @@ static inline void php_intl_bidi_invokeConstruction(zval * instance, zend_long m error = U_ZERO_ERROR; - objval->bidi = ubidi_openSized(maxLength, maxRunCount, &error); + objval->bidi->bidi = ubidi_openSized(maxLength, maxRunCount, &error); if (U_FAILURE(error)) { THROW_UFAILURE(NULL, "__construct", error); return; @@ -130,7 +134,7 @@ static PHP_METHOD(IntlBidi, setInverse) { Z_PARAM_BOOL(inverse) ZEND_PARSE_PARAMETERS_END(); - ubidi_setInverse(objval->bidi, (UBool)inverse); + ubidi_setInverse(objval->bidi->bidi, (UBool)inverse); RETURN_ZVAL(getThis(), 1, 0); } /* }}} */ @@ -141,7 +145,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, isInverse) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_BOOL(ubidi_isInverse(objval->bidi)); + RETURN_BOOL(ubidi_isInverse(objval->bidi->bidi)); } /* }}} */ @@ -157,7 +161,7 @@ static PHP_METHOD(IntlBidi, orderParagraphsLTR) { Z_PARAM_BOOL(ltr) ZEND_PARSE_PARAMETERS_END(); - ubidi_orderParagraphsLTR(objval->bidi, (UBool)ltr); + ubidi_orderParagraphsLTR(objval->bidi->bidi, (UBool)ltr); RETURN_ZVAL(getThis(), 1, 0); } /* }}} */ @@ -168,7 +172,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, isOrderParagraphsLTR) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_BOOL(ubidi_isOrderParagraphsLTR(objval->bidi)); + RETURN_BOOL(ubidi_isOrderParagraphsLTR(objval->bidi->bidi)); } /* }}} */ @@ -184,7 +188,7 @@ static PHP_METHOD(IntlBidi, setReorderingMode) { Z_PARAM_LONG(mode) ZEND_PARSE_PARAMETERS_END(); - ubidi_setReorderingMode(objval->bidi, (UBiDiReorderingMode)mode); + ubidi_setReorderingMode(objval->bidi->bidi, (UBiDiReorderingMode)mode); RETURN_ZVAL(getThis(), 1, 0); } /* }}} */ @@ -195,7 +199,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getReorderingMode) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_getReorderingMode(objval->bidi)); + RETURN_LONG(ubidi_getReorderingMode(objval->bidi->bidi)); } /* }}} */ @@ -211,7 +215,7 @@ static PHP_METHOD(IntlBidi, setReorderingOptions) { Z_PARAM_LONG(opts) ZEND_PARSE_PARAMETERS_END(); - ubidi_setReorderingOptions(objval->bidi, (UBiDiReorderingOption)opts); + ubidi_setReorderingOptions(objval->bidi->bidi, (UBiDiReorderingOption)opts); RETURN_ZVAL(getThis(), 1, 0); } /* }}} */ @@ -222,7 +226,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getReorderingOptions) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_getReorderingOptions(objval->bidi)); + RETURN_LONG(ubidi_getReorderingOptions(objval->bidi->bidi)); } /* }}} */ @@ -248,7 +252,7 @@ static PHP_METHOD(IntlBidi, setContext) { UErrorCode error = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uprologue, &uprologue_len, ZSTR_VAL(prologue), ZSTR_LEN(prologue), &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "setContext", error); + THROW_UFAILURE(objval->bidi, "setContext", error); goto setContext_cleanup; } } @@ -257,30 +261,30 @@ static PHP_METHOD(IntlBidi, setContext) { UErrorCode error = U_ZERO_ERROR; intl_convert_utf8_to_utf16(&uepilogue, &uepilogue_len, ZSTR_VAL(epilogue), ZSTR_LEN(epilogue), &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "setContext", error); + THROW_UFAILURE(objval->bidi, "setContext", error); goto setContext_cleanup; } } { UErrorCode error = U_ZERO_ERROR; - ubidi_setContext(objval->bidi, uprologue, uprologue_len, uepilogue, uepilogue_len, &error); + ubidi_setContext(objval->bidi->bidi, uprologue, uprologue_len, uepilogue, uepilogue_len, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "setContext", error); + THROW_UFAILURE(objval->bidi, "setContext", error); goto setContext_cleanup; } } /* Preserve prologue/epilogue as set for later use */ - if (objval->prologue) { - efree(objval->prologue); + if (objval->bidi->prologue) { + efree(objval->bidi->prologue); } - objval->prologue = uprologue; + objval->bidi->prologue = uprologue; - if (objval->epilogue) { - efree(objval->epilogue); + if (objval->bidi->epilogue) { + efree(objval->bidi->epilogue); } - objval->epilogue = uepilogue; + objval->bidi->epilogue = uepilogue; RETURN_ZVAL(getThis(), 1, 0); @@ -318,32 +322,33 @@ static PHP_METHOD(IntlBidi, setPara) { ZEND_PARSE_PARAMETERS_END(); error = U_ZERO_ERROR; + objval->bidi->textLength = ZSTR_LEN(para); intl_convert_utf8_to_utf16(&upara, &upara_len, ZSTR_VAL(para), ZSTR_LEN(para), &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "setPara", error); + THROW_UFAILURE(objval->bidi, "setPara", error); goto setPara_cleanup; } if (embeddingLevels != NULL && ZSTR_LEN(embeddingLevels) > 0) { - objval->embeddingLevels = (UBiDiLevel*)erealloc(objval->embeddingLevels, ZSTR_LEN(embeddingLevels)); - memcpy(objval->embeddingLevels, ZSTR_VAL(embeddingLevels), ZSTR_LEN(embeddingLevels)); + objval->bidi->embeddingLevels = (UBiDiLevel*)erealloc(objval->bidi->embeddingLevels, ZSTR_LEN(embeddingLevels)); + memcpy(objval->bidi->embeddingLevels, ZSTR_VAL(embeddingLevels), ZSTR_LEN(embeddingLevels)); } else { - efree(objval->embeddingLevels); - objval->embeddingLevels = NULL; + efree(objval->bidi->embeddingLevels); + objval->bidi->embeddingLevels = NULL; } error = U_ZERO_ERROR; - ubidi_setPara(objval->bidi, upara, upara_len, (UBiDiLevel)paraLevel, objval->embeddingLevels, &error); + ubidi_setPara(objval->bidi->bidi, upara, upara_len, (UBiDiLevel)paraLevel, objval->bidi->embeddingLevels, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "setPara", error); + THROW_UFAILURE(objval->bidi, "setPara", error); goto setPara_cleanup; } /* Most recently set paragraph must be retained by us. */ - if (objval->text) { - efree(objval->text); + if (objval->bidi->text) { + efree(objval->bidi->text); } - objval->text = upara; + objval->bidi->text = upara; RETURN_ZVAL(getThis(), 1, 0); setPara_cleanup: @@ -373,13 +378,13 @@ static PHP_METHOD(IntlBidi, setLine) { objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); - lineval->parent = Z_OBJ_P(getThis()); - GC_ADDREF(lineval->parent); + //lineval->parent = Z_OBJ_P(getThis()); + //GC_ADDREF(lineval->parent); error = U_ZERO_ERROR; - ubidi_setLine(objval->bidi, start, limit, lineval->bidi, &error); + ubidi_setLine(objval->bidi->bidi, start, limit, lineval->bidi->bidi, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "setLine", error); + THROW_UFAILURE(objval->bidi, "setLine", error); goto setLine_cleanup; } @@ -397,7 +402,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getDirection) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_getDirection(objval->bidi)); + RETURN_LONG(ubidi_getDirection(objval->bidi->bidi)); } /* }}} */ @@ -411,6 +416,8 @@ static PHP_METHOD(IntlBidi, getBaseDirection) { int32_t utext_len = 0; UErrorCode error; + // TODO: maybe make this static. + ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR(text) ZEND_PARSE_PARAMETERS_END(); @@ -441,7 +448,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getParaLevel) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_getParaLevel(objval->bidi)); + RETURN_LONG(ubidi_getParaLevel(objval->bidi->bidi)); } /* }}} */ @@ -451,7 +458,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, countParagraphs) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_countParagraphs(objval->bidi)); + RETURN_LONG(ubidi_countParagraphs(objval->bidi->bidi)); } /* }}} */ @@ -470,9 +477,9 @@ static PHP_METHOD(IntlBidi, getParagraph) { Z_PARAM_LONG(pos) ZEND_PARSE_PARAMETERS_END(); - idx = ubidi_getParagraph(objval->bidi, pos, &start, &limit, &level, &error); + idx = ubidi_getParagraph(objval->bidi->bidi, pos, &start, &limit, &level, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "getParagraph", error); + THROW_UFAILURE(objval->bidi, "getParagraph", error); return; } @@ -499,9 +506,9 @@ static PHP_METHOD(IntlBidi, getParagraphByIndex) { Z_PARAM_LONG(idx) ZEND_PARSE_PARAMETERS_END(); - ubidi_getParagraphByIndex(objval->bidi, idx, &start, &limit, &level, &error); + ubidi_getParagraphByIndex(objval->bidi->bidi, idx, &start, &limit, &level, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "getParagraph", error); + THROW_UFAILURE(objval->bidi, "getParagraph", error); return; } @@ -525,7 +532,7 @@ static PHP_METHOD(IntlBidi, getLevelAt) { Z_PARAM_LONG(pos) ZEND_PARSE_PARAMETERS_END(); - RETURN_LONG(ubidi_getLevelAt(objval->bidi, pos)); + RETURN_LONG(ubidi_getLevelAt(objval->bidi->bidi, pos)); } /* }}} */ @@ -541,12 +548,12 @@ static PHP_METHOD(IntlBidi, getLevels) { if (zend_parse_parameters_none_throw() == FAILURE) { return; } - levels = ubidi_getLevels(objval->bidi, &error); + levels = ubidi_getLevels(objval->bidi->bidi, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "getLevels", error); + THROW_UFAILURE(objval->bidi, "getLevels", error); return; } - len = ubidi_getProcessedLength(objval->bidi); + len = ubidi_getProcessedLength(objval->bidi->bidi); ret = zend_string_alloc(len, 0); memcpy(ZSTR_VAL(ret), levels, len); ZSTR_VAL(ret)[len] = 0; @@ -569,7 +576,7 @@ static PHP_METHOD(IntlBidi, getLogicalRun) { Z_PARAM_LONG(pos) ZEND_PARSE_PARAMETERS_END(); - ubidi_getLogicalRun(objval->bidi, pos, &limit, &level); + ubidi_getLogicalRun(objval->bidi->bidi, pos, &limit, &level); array_init(return_value); add_assoc_long(return_value, "limit", limit); @@ -587,9 +594,9 @@ static PHP_METHOD(IntlBidi, countRuns) { if (zend_parse_parameters_none_throw() == FAILURE) { return; } - ret = ubidi_countRuns(objval->bidi, &error); + ret = ubidi_countRuns(objval->bidi->bidi, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "countRuns", error); + THROW_UFAILURE(objval->bidi, "countRuns", error); return; } @@ -611,7 +618,7 @@ static PHP_METHOD(IntlBidi, getVisualRun) { Z_PARAM_LONG(idx) ZEND_PARSE_PARAMETERS_END(); - dir = ubidi_getVisualRun(objval->bidi, idx, &start, &length); + dir = ubidi_getVisualRun(objval->bidi->bidi, idx, &start, &length); array_init(return_value); add_assoc_long(return_value, "start", start); @@ -634,9 +641,9 @@ static PHP_METHOD(IntlBidi, getVisualIndex) { Z_PARAM_LONG(idx) ZEND_PARSE_PARAMETERS_END(); - ret = ubidi_getVisualIndex(objval->bidi, idx, &error); + ret = ubidi_getVisualIndex(objval->bidi->bidi, idx, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "getVisualIndex", error); + THROW_UFAILURE(objval->bidi, "getVisualIndex", error); return; } @@ -658,9 +665,9 @@ static PHP_METHOD(IntlBidi, getLogicalIndex) { Z_PARAM_LONG(idx) ZEND_PARSE_PARAMETERS_END(); - ret = ubidi_getLogicalIndex(objval->bidi, idx, &error); + ret = ubidi_getLogicalIndex(objval->bidi->bidi, idx, &error); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "getLogicalIndex", error); + THROW_UFAILURE(objval->bidi, "getLogicalIndex", error); return; } @@ -673,17 +680,17 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getlogicalmap_arginfo, ZEND_RETURN_ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getLogicalMap) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - int32_t len = ubidi_getProcessedLength(objval->bidi), i; + int32_t len = ubidi_getProcessedLength(objval->bidi->bidi), i; int32_t *map; UErrorCode error = U_ZERO_ERROR; if (zend_parse_parameters_none_throw() == FAILURE) { return; } map = safe_emalloc(sizeof(int32_t), len, 0); - ubidi_getLogicalMap(objval->bidi, map, &error); + ubidi_getLogicalMap(objval->bidi->bidi, map, &error); if (U_FAILURE(error)) { efree(map); - THROW_UFAILURE(objval, "getLogicalMap", error); + THROW_UFAILURE(objval->bidi, "getLogicalMap", error); return; } @@ -701,17 +708,17 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_getvisualmap_arginfo, ZEND_RETURN_V ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getVisualMap) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - int32_t len = ubidi_getResultLength(objval->bidi), i; + int32_t len = ubidi_getResultLength(objval->bidi->bidi), i; int32_t *map; UErrorCode error = U_ZERO_ERROR; if (zend_parse_parameters_none_throw() == FAILURE) { return; } map = safe_emalloc(sizeof(int32_t), len, 0); - ubidi_getVisualMap(objval->bidi, map, &error); + ubidi_getVisualMap(objval->bidi->bidi, map, &error); if (U_FAILURE(error)) { efree(map); - THROW_UFAILURE(objval, "getVisualMap", error); + THROW_UFAILURE(objval->bidi, "getVisualMap", error); return; } @@ -730,7 +737,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getProcessedLength) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_getProcessedLength(objval->bidi)); + RETURN_LONG(ubidi_getProcessedLength(objval->bidi->bidi)); } /* }}} */ @@ -740,7 +747,7 @@ ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, getResultLength) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_getResultLength(objval->bidi)); + RETURN_LONG(ubidi_getResultLength(objval->bidi->bidi)); } /* }}} */ @@ -762,26 +769,26 @@ static PHP_METHOD(IntlBidi, getReordered) { if ( (options & UBIDI_INSERT_LRM_FOR_NUMERIC) == UBIDI_INSERT_LRM_FOR_NUMERIC || - (ubidi_getReorderingOptions(objval->bidi) & UBIDI_OPTION_INSERT_MARKS) == UBIDI_OPTION_INSERT_MARKS + (ubidi_getReorderingOptions(objval->bidi->bidi) & UBIDI_OPTION_INSERT_MARKS) == UBIDI_OPTION_INSERT_MARKS ) { error = U_ZERO_ERROR; - utext_len = ubidi_getLength(objval->bidi) + (2 * ubidi_countRuns(objval->bidi, &error)); + utext_len = ubidi_getLength(objval->bidi->bidi) + (2 * ubidi_countRuns(objval->bidi->bidi, &error)); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "getReordered", error); + THROW_UFAILURE(objval->bidi, "getReordered", error); return; } } else if (options & UBIDI_REMOVE_BIDI_CONTROLS) { - utext_len = ubidi_getLength(objval->bidi); + utext_len = ubidi_getLength(objval->bidi->bidi); } else { - utext_len = ubidi_getProcessedLength(objval->bidi); + utext_len = ubidi_getProcessedLength(objval->bidi->bidi); } utext = safe_emalloc(sizeof(UChar), utext_len, sizeof(UChar)); error = U_ZERO_ERROR; - utext_len = ubidi_writeReordered(objval->bidi, utext, utext_len, options, &error); + utext_len = ubidi_writeReordered(objval->bidi->bidi, utext, utext_len, options, &error); if (U_FAILURE(error)) { efree(utext); - THROW_UFAILURE(objval, "getReordered", error); + THROW_UFAILURE(objval->bidi, "getReordered", error); return; } @@ -789,7 +796,7 @@ static PHP_METHOD(IntlBidi, getReordered) { ret = intl_convert_utf16_to_utf8(utext, utext_len, &error); efree(utext); if (U_FAILURE(error)) { - THROW_UFAILURE(objval, "getReordered", error); + THROW_UFAILURE(objval->bidi, "getReordered", error); return; } @@ -803,8 +810,32 @@ ZEND_END_ARG_INFO() static PHP_METHOD(IntlBidi, getLength) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); if (zend_parse_parameters_none_throw() == FAILURE) { return; } - RETURN_LONG(ubidi_getLength(objval->bidi)); + RETURN_LONG(ubidi_getLength(objval->bidi->bidi)); } +/* }}} */ + +/* {{{ proto string IntlBidi::getText() */ +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_gettext_arginfo, ZEND_RETURN_VALUE, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() +static PHP_METHOD(IntlBidi, getText) { + php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); + zend_string * str; + UErrorCode error; + + error = U_ZERO_ERROR; + str = intl_convert_utf16_to_utf8(objval->bidi->text, objval->bidi->textLength, &error); + + if (U_FAILURE(error)) { + THROW_UFAILURE(objval->bidi, "getText", error); + efree(str); + return; + } + + + + RETURN_STR(str); +} +/* }}} */ static zend_function_entry bidi_methods[] = { PHP_ME(IntlBidi, __construct, bidi_ctor_arginfo, ZEND_ACC_CTOR | ZEND_ACC_PUBLIC) @@ -840,6 +871,7 @@ static zend_function_entry bidi_methods[] = { PHP_ME(IntlBidi, getProcessedLength, bidi_getprocessedlen_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getResultLength, bidi_getresultlen_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getReordered, bidi_getreordered_arginfo, ZEND_ACC_PUBLIC) + PHP_ME(IntlBidi, getText, bidi_gettext_arginfo, ZEND_ACC_PUBLIC) PHP_FE_END }; @@ -852,9 +884,12 @@ static zend_object *bidi_object_ctor(zend_class_entry *ce) { objval = zend_object_alloc(sizeof(php_intl_bidi_object), ce); + // change this to a nulling + objval->bidi = ecalloc(1, sizeof(bidi_object)); + zend_object_std_init(&objval->std, ce); object_properties_init(&objval->std, ce); - intl_error_init(&(objval->error)); + intl_error_init(&(objval->bidi->error)); objval->std.handlers = &bidi_object_handlers; @@ -864,18 +899,14 @@ static zend_object *bidi_object_ctor(zend_class_entry *ce) { static void bidi_object_dtor(zend_object *obj) { php_intl_bidi_object *objval = bidi_object_from_zend_object(obj); - if (objval->bidi) { ubidi_close(objval->bidi); } - if (objval->prologue) { efree(objval->prologue); } - if (objval->text) { efree(objval->text); } - if (objval->epilogue) { efree(objval->epilogue); } - if (objval->embeddingLevels) { efree(objval->embeddingLevels); } - - if (objval->parent) { - GC_DELREF(objval->parent); - } + if (objval->bidi->bidi) { ubidi_close(objval->bidi->bidi); } + if (objval->bidi->prologue) { efree(objval->bidi->prologue); } + if (objval->bidi->text) { efree(objval->bidi->text); } + if (objval->bidi->epilogue) { efree(objval->bidi->epilogue); } + if (objval->bidi->embeddingLevels) { efree(objval->bidi->embeddingLevels); } - intl_error_reset(&(objval->error)); - zend_object_release(obj); + intl_error_reset(&(objval->bidi->error)); + efree(objval->bidi); } PHP_MINIT_FUNCTION(intl_bidi) { From a1692a40bdf9fb3c134f6627a218295f228f7f7f Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 09:34:04 +0100 Subject: [PATCH 39/50] Added parent instance management. --- ext/intl/bidi/bidi.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 72b1212179b5f..ed56759208859 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -33,9 +33,11 @@ typedef struct _bidi_object { int32_t textLength; UChar *prologue, *text, *epilogue; intl_error error; + unsigned int childCount; } bidi_object; typedef struct _php_intl_bidi_object { + bidi_object * parent; bidi_object * bidi; zend_object std; } php_intl_bidi_object; @@ -48,6 +50,22 @@ static inline zend_object *bidi_object_to_zend_object(php_intl_bidi_object *obj) return ((zend_object*)(obj + 1)) - 1; } +static inline void bidi_free_bidi_object(bidi_object * obj) { + if (obj != NULL) { + obj->childCount--; + if (obj->childCount == 0) { + if (obj->bidi) { ubidi_close(obj->bidi); } + if (obj->prologue) { efree(obj->prologue); } + if (obj->text) { efree(obj->text); } + if (obj->epilogue) { efree(obj->epilogue); } + if (obj->embeddingLevels) { efree(obj->embeddingLevels); } + + intl_error_reset(&(obj->error)); + efree(obj); + } + } +} + #define THROW_UFAILURE(obj, fname, error) \ php_intl_bidi_throw_failure(obj, error, \ "IntlBidi::" fname "() returned error " ZEND_LONG_FMT ": %s", \ @@ -378,8 +396,8 @@ static PHP_METHOD(IntlBidi, setLine) { objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); - //lineval->parent = Z_OBJ_P(getThis()); - //GC_ADDREF(lineval->parent); + lineval->parent = objval->bidi; + objval->bidi->childCount++; error = U_ZERO_ERROR; ubidi_setLine(objval->bidi->bidi, start, limit, lineval->bidi->bidi, &error); @@ -884,8 +902,8 @@ static zend_object *bidi_object_ctor(zend_class_entry *ce) { objval = zend_object_alloc(sizeof(php_intl_bidi_object), ce); - // change this to a nulling objval->bidi = ecalloc(1, sizeof(bidi_object)); + objval->bidi->childCount = 1; zend_object_std_init(&objval->std, ce); object_properties_init(&objval->std, ce); @@ -898,15 +916,8 @@ static zend_object *bidi_object_ctor(zend_class_entry *ce) { static void bidi_object_dtor(zend_object *obj) { php_intl_bidi_object *objval = bidi_object_from_zend_object(obj); - - if (objval->bidi->bidi) { ubidi_close(objval->bidi->bidi); } - if (objval->bidi->prologue) { efree(objval->bidi->prologue); } - if (objval->bidi->text) { efree(objval->bidi->text); } - if (objval->bidi->epilogue) { efree(objval->bidi->epilogue); } - if (objval->bidi->embeddingLevels) { efree(objval->bidi->embeddingLevels); } - - intl_error_reset(&(objval->bidi->error)); - efree(objval->bidi); + bidi_free_bidi_object(objval->bidi); + bidi_free_bidi_object(objval->parent); } PHP_MINIT_FUNCTION(intl_bidi) { From df2186476d71f5ceb5683ff3ac09c644b7ad89c8 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 10:38:38 +0100 Subject: [PATCH 40/50] Added tests for maintaning bidi instances. --- .../IntlBidi_getReordered_variant7.phpt | 75 +++++++++++++++++ .../IntlBidi_getReordered_variant8.phpt | 82 +++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant7.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant7.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant7.phpt new file mode 100644 index 0000000000000..1c96eeab8b403 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant7.phpt @@ -0,0 +1,75 @@ +--TEST-- +Test getReordered with setLine +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +setPara($srcUt8, \IntlBidi::DEFAULT_LTR); + $newBidi = $bidi->setLine(0, $bidi->getResultLength()); + $bidi->setPara('', \Intlbidi::DEFAULT_LTR); + $result = u8ToPseudo($newBidi->getReordered(\IntlBidi::DO_MIRRORING)); + var_dump($result); +} +?> +==DONE== +--EXPECT-- +string(17) "del(CK)add(&.C.K)" +string(19) "del(TVDQ) add(LDVB)" +string(21) "del(QP)add(S.R.)&.U(T" +string(22) "del(VL)add(V.L.) &.V.L" +string(26) "day 0 RVRHDPD R dayabbr" +string(27) "day 1 ADHDPHPD H dayabbr" +string(28) "day 2 ADNELBPD L dayabbr" +string(26) "day 3 MVQJPD J dayabbr" +string(29) "day 4 FNQIPD I dayabbr" +string(25) "day 5 GEMPD M dayabbr" +string(10) "helloGEMPD" +string(9) "hello YXW" +==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt new file mode 100644 index 0000000000000..47a85cd9d1a69 --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt @@ -0,0 +1,82 @@ +--TEST-- +Test getReordered with setLine and multiple layers. +--CREDITS-- +Timo Scholz +--SKIPIF-- + + +--FILE-- +setPara($srcUt8, \IntlBidi::DEFAULT_LTR); + $newBidi = $bidi->setLine(0, $bidi->getResultLength()); + + for ($i = 0; $i <= 10; $i++) { + $newBidi = $newBidi->setLine(0, $newBidi->getResultLength()); + } + + $bidi->setPara('', \Intlbidi::DEFAULT_LTR); + + + $result = u8ToPseudo($newBidi->getReordered(\IntlBidi::DO_MIRRORING)); + var_dump($result); +} +?> +==DONE== +--EXPECT-- +string(17) "del(CK)add(&.C.K)" +string(19) "del(TVDQ) add(LDVB)" +string(21) "del(QP)add(S.R.)&.U(T" +string(22) "del(VL)add(V.L.) &.V.L" +string(26) "day 0 RVRHDPD R dayabbr" +string(27) "day 1 ADHDPHPD H dayabbr" +string(28) "day 2 ADNELBPD L dayabbr" +string(26) "day 3 MVQJPD J dayabbr" +string(29) "day 4 FNQIPD I dayabbr" +string(25) "day 5 GEMPD M dayabbr" +string(10) "helloGEMPD" +string(9) "hello YXW" +==DONE== \ No newline at end of file From ef9f04e2e2cbc952ec3a188c90b57002482ad383 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 10:39:59 +0100 Subject: [PATCH 41/50] Moved allocation logic in own function. Started implementing parent management in setPara method. --- ext/intl/bidi/bidi.c | 65 ++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index ed56759208859..5a2645d81a139 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -50,22 +50,6 @@ static inline zend_object *bidi_object_to_zend_object(php_intl_bidi_object *obj) return ((zend_object*)(obj + 1)) - 1; } -static inline void bidi_free_bidi_object(bidi_object * obj) { - if (obj != NULL) { - obj->childCount--; - if (obj->childCount == 0) { - if (obj->bidi) { ubidi_close(obj->bidi); } - if (obj->prologue) { efree(obj->prologue); } - if (obj->text) { efree(obj->text); } - if (obj->epilogue) { efree(obj->epilogue); } - if (obj->embeddingLevels) { efree(obj->embeddingLevels); } - - intl_error_reset(&(obj->error)); - efree(obj); - } - } -} - #define THROW_UFAILURE(obj, fname, error) \ php_intl_bidi_throw_failure(obj, error, \ "IntlBidi::" fname "() returned error " ZEND_LONG_FMT ": %s", \ @@ -87,9 +71,12 @@ static inline void php_intl_bidi_throw_failure(bidi_object *obj, } /* }}} */ -static inline void php_intl_bidi_invokeConstruction(zval * instance, zend_long maxRunCount, zend_long maxLength) { +static inline bidi_object * bidi_create_bidi_object(zend_long maxRunCount, zend_long maxLength) { UErrorCode error; - php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(instance)); + bidi_object * obj = ecalloc(1, sizeof(bidi_object)); + + obj->childCount = 1; + intl_error_init(&(obj->error)); if (PG(memory_limit) > 0) { if (maxLength == 0) { @@ -97,17 +84,39 @@ static inline void php_intl_bidi_invokeConstruction(zval * instance, zend_long m } else if (maxLength > PG(memory_limit)) { php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, "IntlBidi::__construct() given maxLength greater than memory_limit"); - return; + return NULL; } } error = U_ZERO_ERROR; - - objval->bidi->bidi = ubidi_openSized(maxLength, maxRunCount, &error); + obj->bidi = ubidi_openSized(maxLength, maxRunCount, &error); if (U_FAILURE(error)) { THROW_UFAILURE(NULL, "__construct", error); - return; + return NULL; } + + return obj; +} + +static inline void bidi_free_bidi_object(bidi_object * obj) { + if (obj != NULL) { + obj->childCount--; + if (obj->childCount == 0) { + if (obj->bidi) { ubidi_close(obj->bidi); } + if (obj->prologue) { efree(obj->prologue); } + if (obj->text) { efree(obj->text); } + if (obj->epilogue) { efree(obj->epilogue); } + if (obj->embeddingLevels) { efree(obj->embeddingLevels); } + + intl_error_reset(&(obj->error)); + efree(obj); + } + } +} + +static inline void php_intl_bidi_invokeConstruction(zval * instance, zend_long maxRunCount, zend_long maxLength) { + php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(instance)); + objval->bidi = bidi_create_bidi_object(0, 0); } /* {{{ proto void IntlBidi::__construct([int $maxLength = 0, [int $maxRunCount = 0]]) */ @@ -332,6 +341,14 @@ static PHP_METHOD(IntlBidi, setPara) { int32_t upara_len = 0; UErrorCode error; + if (objval->bidi->childCount > 1) { + bidi_free_bidi_object(objval->parent); + objval->parent = NULL; + + bidi_free_bidi_object(objval->bidi); + objval->bidi = bidi_create_bidi_object(0, 0); // TODO: put the right values here. + } + ZEND_PARSE_PARAMETERS_START(1, 3) Z_PARAM_STR(para) Z_PARAM_OPTIONAL @@ -902,12 +919,8 @@ static zend_object *bidi_object_ctor(zend_class_entry *ce) { objval = zend_object_alloc(sizeof(php_intl_bidi_object), ce); - objval->bidi = ecalloc(1, sizeof(bidi_object)); - objval->bidi->childCount = 1; - zend_object_std_init(&objval->std, ce); object_properties_init(&objval->std, ce); - intl_error_init(&(objval->bidi->error)); objval->std.handlers = &bidi_object_handlers; From a0aa5370f412b34ca73e80828a85a78e23e14333 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 12:41:41 +0100 Subject: [PATCH 42/50] Code style and value type. --- ext/intl/bidi/bidi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 5a2645d81a139..2119544ead17b 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -33,7 +33,7 @@ typedef struct _bidi_object { int32_t textLength; UChar *prologue, *text, *epilogue; intl_error error; - unsigned int childCount; + zend_long childCount; } bidi_object; typedef struct _php_intl_bidi_object { @@ -413,8 +413,7 @@ static PHP_METHOD(IntlBidi, setLine) { objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); - lineval->parent = objval->bidi; - objval->bidi->childCount++; + (lineval->parent = objval->bidi)->childCount++; error = U_ZERO_ERROR; ubidi_setLine(objval->bidi->bidi, start, limit, lineval->bidi->bidi, &error); From b2383ddbc0a4b3367ff21059a9dc2305230807fd Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 15:35:17 +0100 Subject: [PATCH 43/50] Code cleanup. --- ext/intl/bidi/bidi.c | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 2119544ead17b..0d4641c172169 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -75,9 +75,6 @@ static inline bidi_object * bidi_create_bidi_object(zend_long maxRunCount, zend_ UErrorCode error; bidi_object * obj = ecalloc(1, sizeof(bidi_object)); - obj->childCount = 1; - intl_error_init(&(obj->error)); - if (PG(memory_limit) > 0) { if (maxLength == 0) { maxLength = PG(memory_limit) / 2; @@ -88,6 +85,9 @@ static inline bidi_object * bidi_create_bidi_object(zend_long maxRunCount, zend_ } } + obj->childCount = 1; + intl_error_init(&(obj->error)); + error = U_ZERO_ERROR; obj->bidi = ubidi_openSized(maxLength, maxRunCount, &error); if (U_FAILURE(error)) { @@ -346,7 +346,7 @@ static PHP_METHOD(IntlBidi, setPara) { objval->parent = NULL; bidi_free_bidi_object(objval->bidi); - objval->bidi = bidi_create_bidi_object(0, 0); // TODO: put the right values here. + objval->bidi = bidi_create_bidi_object(0, 0); } ZEND_PARSE_PARAMETERS_START(1, 3) @@ -450,8 +450,6 @@ static PHP_METHOD(IntlBidi, getBaseDirection) { int32_t utext_len = 0; UErrorCode error; - // TODO: maybe make this static. - ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR(text) ZEND_PARSE_PARAMETERS_END(); @@ -848,29 +846,6 @@ static PHP_METHOD(IntlBidi, getLength) { } /* }}} */ -/* {{{ proto string IntlBidi::getText() */ -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_gettext_arginfo, ZEND_RETURN_VALUE, 0, IS_STRING, 0) -ZEND_END_ARG_INFO() -static PHP_METHOD(IntlBidi, getText) { - php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); - zend_string * str; - UErrorCode error; - - error = U_ZERO_ERROR; - str = intl_convert_utf16_to_utf8(objval->bidi->text, objval->bidi->textLength, &error); - - if (U_FAILURE(error)) { - THROW_UFAILURE(objval->bidi, "getText", error); - efree(str); - return; - } - - - - RETURN_STR(str); -} -/* }}} */ - static zend_function_entry bidi_methods[] = { PHP_ME(IntlBidi, __construct, bidi_ctor_arginfo, ZEND_ACC_CTOR | ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, setInverse, bidi_setinverse_arginfo, ZEND_ACC_PUBLIC) @@ -905,7 +880,6 @@ static zend_function_entry bidi_methods[] = { PHP_ME(IntlBidi, getProcessedLength, bidi_getprocessedlen_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getResultLength, bidi_getresultlen_arginfo, ZEND_ACC_PUBLIC) PHP_ME(IntlBidi, getReordered, bidi_getreordered_arginfo, ZEND_ACC_PUBLIC) - PHP_ME(IntlBidi, getText, bidi_gettext_arginfo, ZEND_ACC_PUBLIC) PHP_FE_END }; From a95a63973cec6a3aa460d30c79e71413faec93cf Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 15:35:29 +0100 Subject: [PATCH 44/50] Optimized test. --- .../IntlBidi_getReordered_variant8.phpt | 55 ++++--------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt index 47a85cd9d1a69..984d651e58b1c 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt @@ -26,57 +26,26 @@ include 'IntlBidi_ut_common.inc'; // --- INIT TEST DATA --- -$logicalOrder = [ - 'del(KC)add(K.C.&)', - 'del(QDVT) add(BVDL)', - 'del(PQ)add(R.S.)T)U.&', - 'del(LV)add(L.V.) L.V.&', - 'day 0 R DPDHRVR dayabbr', - 'day 1 H DPHPDHDA dayabbr', - 'day 2 L DPBLENDA dayabbr', - 'day 3 J DPJQVM dayabbr', - 'day 4 I DPIQNF dayabbr', - 'day 5 M DPMEG dayabbr', - 'helloDPMEG', - 'hello WXY' -]; +$logicalOrder = 'del(KC)add(K.C.&)'; -// --- RUN TEST --- - -$nTests = \count($logicalOrder); -for ($testNumber = 0; $testNumber < $nTests; $testNumber++) { - // prepare the source. - $src = $logicalOrder[$testNumber]; - $srcUt8 = pseudoToU8($src); +// --- RUN TEST --- - $bidi = new \IntlBidi(); - $bidi->setPara($srcUt8, \IntlBidi::DEFAULT_LTR); - $newBidi = $bidi->setLine(0, $bidi->getResultLength()); +// prepare the source. +$srcUt8 = pseudoToU8($logicalOrder); - for ($i = 0; $i <= 10; $i++) { - $newBidi = $newBidi->setLine(0, $newBidi->getResultLength()); - } + $bidi = new \IntlBidi(); +$bidi->setPara($srcUt8, \IntlBidi::DEFAULT_LTR); +$newBidi = $bidi->setLine(0, $bidi->getResultLength()); +$newBidi2 = $newBidi->setLine(0, $newBidi->getResultLength()); +$newBidi3 = $newBidi2->setLine(0, $newBidi2->getResultLength()); - $bidi->setPara('', \Intlbidi::DEFAULT_LTR); +// $bidi->setPara('', \Intlbidi::DEFAULT_LTR); - - $result = u8ToPseudo($newBidi->getReordered(\IntlBidi::DO_MIRRORING)); - var_dump($result); -} + $result = u8ToPseudo($newBidi3->getReordered(\IntlBidi::DO_MIRRORING)); +var_dump($result); ?> ==DONE== --EXPECT-- string(17) "del(CK)add(&.C.K)" -string(19) "del(TVDQ) add(LDVB)" -string(21) "del(QP)add(S.R.)&.U(T" -string(22) "del(VL)add(V.L.) &.V.L" -string(26) "day 0 RVRHDPD R dayabbr" -string(27) "day 1 ADHDPHPD H dayabbr" -string(28) "day 2 ADNELBPD L dayabbr" -string(26) "day 3 MVQJPD J dayabbr" -string(29) "day 4 FNQIPD I dayabbr" -string(25) "day 5 GEMPD M dayabbr" -string(10) "helloGEMPD" -string(9) "hello YXW" ==DONE== \ No newline at end of file From de68d04c501eb5b46ee94384bf732e916c1e18dc Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Mon, 3 Dec 2018 15:36:57 +0100 Subject: [PATCH 45/50] Removed unnecessary space. --- ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt index 984d651e58b1c..4c53ec9584515 100644 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt +++ b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt @@ -42,7 +42,7 @@ $newBidi3 = $newBidi2->setLine(0, $newBidi2->getResultLength()); // $bidi->setPara('', \Intlbidi::DEFAULT_LTR); - $result = u8ToPseudo($newBidi3->getReordered(\IntlBidi::DO_MIRRORING)); +$result = u8ToPseudo($newBidi3->getReordered(\IntlBidi::DO_MIRRORING)); var_dump($result); ?> ==DONE== From 500c2d5b905d254c0456a811f99f4e5e97e7bb0d Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 4 Dec 2018 11:40:06 +0100 Subject: [PATCH 46/50] code cleanup. --- ext/intl/bidi/bidi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 0d4641c172169..380fa4b593fc9 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -34,10 +34,10 @@ typedef struct _bidi_object { UChar *prologue, *text, *epilogue; intl_error error; zend_long childCount; + struct _bidi_object * parent; } bidi_object; typedef struct _php_intl_bidi_object { - bidi_object * parent; bidi_object * bidi; zend_object std; } php_intl_bidi_object; @@ -110,6 +110,9 @@ static inline void bidi_free_bidi_object(bidi_object * obj) { intl_error_reset(&(obj->error)); efree(obj); + + bidi_free_bidi_object(obj->parent); + obj->parent = NULL; } } } @@ -342,9 +345,6 @@ static PHP_METHOD(IntlBidi, setPara) { UErrorCode error; if (objval->bidi->childCount > 1) { - bidi_free_bidi_object(objval->parent); - objval->parent = NULL; - bidi_free_bidi_object(objval->bidi); objval->bidi = bidi_create_bidi_object(0, 0); } @@ -413,7 +413,7 @@ static PHP_METHOD(IntlBidi, setLine) { objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); - (lineval->parent = objval->bidi)->childCount++; + (lineval->bidi->parent = objval->bidi)->childCount++; error = U_ZERO_ERROR; ubidi_setLine(objval->bidi->bidi, start, limit, lineval->bidi->bidi, &error); @@ -903,7 +903,6 @@ static zend_object *bidi_object_ctor(zend_class_entry *ce) { static void bidi_object_dtor(zend_object *obj) { php_intl_bidi_object *objval = bidi_object_from_zend_object(obj); bidi_free_bidi_object(objval->bidi); - bidi_free_bidi_object(objval->parent); } PHP_MINIT_FUNCTION(intl_bidi) { From 456776c36ef15ed5bd8043502a834b459c740f1a Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 4 Dec 2018 11:48:33 +0100 Subject: [PATCH 47/50] Changed call order for freeing bidi_objects. --- ext/intl/bidi/bidi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 380fa4b593fc9..267685d75d208 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -109,10 +109,11 @@ static inline void bidi_free_bidi_object(bidi_object * obj) { if (obj->embeddingLevels) { efree(obj->embeddingLevels); } intl_error_reset(&(obj->error)); - efree(obj); bidi_free_bidi_object(obj->parent); obj->parent = NULL; + + efree(obj); } } } From 01d5c8bfde478d53d6fcb5e279a31fd6958e68b6 Mon Sep 17 00:00:00 2001 From: Jan Slabon Date: Wed, 19 Dec 2018 09:57:38 +0100 Subject: [PATCH 48/50] Restructured specific setLine() test. --- .../IntlBidi_getReordered_variant8.phpt | 51 ------------------- .../IntlBidi/IntlBidi_setLine_variant1.phpt | 23 +++++++++ 2 files changed, 23 insertions(+), 51 deletions(-) delete mode 100644 ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt create mode 100644 ext/intl/tests/IntlBidi/IntlBidi_setLine_variant1.phpt diff --git a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt b/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt deleted file mode 100644 index 4c53ec9584515..0000000000000 --- a/ext/intl/tests/IntlBidi/IntlBidi_getReordered_variant8.phpt +++ /dev/null @@ -1,51 +0,0 @@ ---TEST-- -Test getReordered with setLine and multiple layers. ---CREDITS-- -Timo Scholz ---SKIPIF-- - - ---FILE-- -setPara($srcUt8, \IntlBidi::DEFAULT_LTR); -$newBidi = $bidi->setLine(0, $bidi->getResultLength()); -$newBidi2 = $newBidi->setLine(0, $newBidi->getResultLength()); -$newBidi3 = $newBidi2->setLine(0, $newBidi2->getResultLength()); - -// $bidi->setPara('', \Intlbidi::DEFAULT_LTR); - -$result = u8ToPseudo($newBidi3->getReordered(\IntlBidi::DO_MIRRORING)); -var_dump($result); -?> -==DONE== ---EXPECT-- -string(17) "del(CK)add(&.C.K)" -==DONE== \ No newline at end of file diff --git a/ext/intl/tests/IntlBidi/IntlBidi_setLine_variant1.phpt b/ext/intl/tests/IntlBidi/IntlBidi_setLine_variant1.phpt new file mode 100644 index 0000000000000..955341cf9044e --- /dev/null +++ b/ext/intl/tests/IntlBidi/IntlBidi_setLine_variant1.phpt @@ -0,0 +1,23 @@ +--TEST-- +Test for chained setLine() calls. +--CREDITS-- +Jan Slabon +--SKIPIF-- + +--FILE-- +setPara('abcde'); + +$line = $bidi->setLine(0, 2); +var_dump($line->getReordered(0)); + +$line2 = $line->setLine(0, 1); +var_dump($line2->getReordered(0)); + +?> +==DONE== +--EXPECT-- +string(2) "ab" +string(1) "a" +==DONE== From 46e5c90212122e127153c3718499f4670c787d1f Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Tue, 29 Jan 2019 16:48:54 +0100 Subject: [PATCH 49/50] Fixed constructor and moved check into the constructor. Fixed nullable types. --- ext/intl/bidi/bidi.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 267685d75d208..1e7154e8e303d 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -119,8 +119,20 @@ static inline void bidi_free_bidi_object(bidi_object * obj) { } static inline void php_intl_bidi_invokeConstruction(zval * instance, zend_long maxRunCount, zend_long maxLength) { + if (maxRunCount < 0) { + php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "IntlBidi::__construct() expects maxRunCount to be a non-negative value"); + return; + } + + if (maxLength < 0) { + php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "IntlBidi::__construct() expects maxLength to be a non-negative value"); + return; + } + php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(instance)); - objval->bidi = bidi_create_bidi_object(0, 0); + objval->bidi = bidi_create_bidi_object(maxRunCount, maxLength); } /* {{{ proto void IntlBidi::__construct([int $maxLength = 0, [int $maxRunCount = 0]]) */ @@ -137,18 +149,6 @@ static PHP_METHOD(IntlBidi, __construct) { Z_PARAM_LONG(maxRunCount) ZEND_PARSE_PARAMETERS_END(); - if (maxRunCount < 0) { - php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "IntlBidi::__construct() expects maxRunCount to be a non-negative value"); - return; - } - - if (maxLength < 0) { - php_intl_bidi_throw_failure(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "IntlBidi::__construct() expects maxLength to be a non-negative value"); - return; - } - php_intl_bidi_invokeConstruction(getThis(), maxLength, maxRunCount); } /* }}} */ @@ -264,8 +264,8 @@ static PHP_METHOD(IntlBidi, getReorderingOptions) { #if ((U_ICU_VERSION_MAJOR_NUM * 10) + U_ICU_VERSION_MINOR_NUM) >= 48 /* {{{ proto self IntlBidi::setContext([string $prologue = ''[, string $epilogue = '']]) */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(bidi_setctx_arginfo, ZEND_RETURN_VALUE, 0, IS_OBJECT, 0) - ZEND_ARG_TYPE_INFO(0, prologue, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, epilogue, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, prologue, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, epilogue, IS_STRING, 1) ZEND_END_ARG_INFO(); static PHP_METHOD(IntlBidi, setContext) { php_intl_bidi_object *objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); @@ -275,8 +275,8 @@ static PHP_METHOD(IntlBidi, setContext) { ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STR_EX(prologue, 0, 0) - Z_PARAM_STR_EX(epilogue, 0, 0) + Z_PARAM_STR_EX(prologue, 1, 0) + Z_PARAM_STR_EX(epilogue, 1, 0) ZEND_PARSE_PARAMETERS_END(); if (prologue && ZSTR_LEN(prologue)) { @@ -354,7 +354,7 @@ static PHP_METHOD(IntlBidi, setPara) { Z_PARAM_STR(para) Z_PARAM_OPTIONAL Z_PARAM_LONG(paraLevel) - Z_PARAM_STR_EX(embeddingLevels, 0, 0) + Z_PARAM_STR_EX(embeddingLevels, 1, 0) ZEND_PARSE_PARAMETERS_END(); error = U_ZERO_ERROR; From 69e133cf3a53a42c5e0f0d83c77844cb8cd3ec93 Mon Sep 17 00:00:00 2001 From: Timo Scholz <20026070+OmniFaR@users.noreply.github.com> Date: Wed, 30 Jan 2019 13:30:50 +0100 Subject: [PATCH 50/50] Added support for chained setLine() calls. --- ext/intl/bidi/bidi.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ext/intl/bidi/bidi.c b/ext/intl/bidi/bidi.c index 1e7154e8e303d..4a2c2da80316d 100644 --- a/ext/intl/bidi/bidi.c +++ b/ext/intl/bidi/bidi.c @@ -30,6 +30,7 @@ static zend_object_handlers bidi_object_handlers; typedef struct _bidi_object { UBiDi *bidi; UBiDiLevel *embeddingLevels; + int32_t start, limit; int32_t textLength; UChar *prologue, *text, *epilogue; intl_error error; @@ -413,11 +414,29 @@ static PHP_METHOD(IntlBidi, setLine) { php_intl_bidi_invokeConstruction(return_value, 0, 0); objval = bidi_object_from_zend_object(Z_OBJ_P(getThis())); + bidi_object * root = objval->bidi; lineval = bidi_object_from_zend_object(Z_OBJ_P(return_value)); (lineval->bidi->parent = objval->bidi)->childCount++; + if (root->parent != NULL) { + if (start + limit > root->limit) { + THROW_UFAILURE(objval->bidi, "setLine", error); + goto setLine_cleanup; + } + + start += root->start; + + while (root->parent != NULL) { + root = root->parent; + } + } + + lineval->bidi->start = start; + lineval->bidi->limit = limit; + error = U_ZERO_ERROR; - ubidi_setLine(objval->bidi->bidi, start, limit, lineval->bidi->bidi, &error); + + ubidi_setLine(root->bidi, start, limit, lineval->bidi->bidi, &error); if (U_FAILURE(error)) { THROW_UFAILURE(objval->bidi, "setLine", error); goto setLine_cleanup;