From 93c3ec8b191402f4cb3b8b34afadb1999e774f6e Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 20 Jul 2019 15:35:44 +0200 Subject: [PATCH] Fix #78308: IntlPartsIterator key is wrong for KEY_LEFT/KEY_RIGHT We must not increase the iterator's index after it has been properly determined. A clean solution would be to increment the index in the internal `*_move_forward()` methods instead of `IntlIterator::next()`, but since the `*_move_forward()` methods are currently also called by the internal `*_rewind()` methods, and don't have a flag to determine the (intent of the) caller, we apply a hack for now. We also fix the erroneous expectations of an existing test case. --- .../breakiterator/breakiterator_iterators.cpp | 4 +-- .../breakiter_getPartsIterator_var1.phpt | 16 ++++----- ext/intl/tests/bug78308.phpt | 34 +++++++++++++++++++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 ext/intl/tests/bug78308.phpt diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp index bdf1b3e53f37e..aac64547ef9bc 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.cpp +++ b/ext/intl/breakiterator/breakiterator_iterators.cpp @@ -160,9 +160,9 @@ static void _breakiterator_parts_move_forward(zend_object_iterator *iter) } if (zoi_bit->key_type == PARTS_ITERATOR_KEY_LEFT) { - iter->index = cur; + iter->index = cur ? cur - 1 : cur; /* HACK: cater to increment in next(), but not rewind() */ } else if (zoi_bit->key_type == PARTS_ITERATOR_KEY_RIGHT) { - iter->index = next; + iter->index = cur ? next - 1 : next; /* HACK: cater to increment in next(), but not rewind() */ } /* else zoi_bit->key_type == PARTS_ITERATOR_KEY_SEQUENTIAL * No need to do anything, the engine increments ->index */ diff --git a/ext/intl/tests/breakiter_getPartsIterator_var1.phpt b/ext/intl/tests/breakiter_getPartsIterator_var1.phpt index 7bbd27ea45112..78e4b2fb0ffea 100644 --- a/ext/intl/tests/breakiter_getPartsIterator_var1.phpt +++ b/ext/intl/tests/breakiter_getPartsIterator_var1.phpt @@ -36,25 +36,25 @@ array(5) { array(5) { [0]=> string(3) "foo" - [4]=> + [3]=> string(1) " " - [5]=> + [4]=> string(3) "bar" - [8]=> + [7]=> string(1) " " - [9]=> + [8]=> string(3) "tao" } array(5) { [3]=> string(3) "foo" - [5]=> + [4]=> string(1) " " - [8]=> + [7]=> string(3) "bar" - [9]=> + [8]=> string(1) " " - [12]=> + [11]=> string(3) "tao" } ==DONE== diff --git a/ext/intl/tests/bug78308.phpt b/ext/intl/tests/bug78308.phpt new file mode 100644 index 0000000000000..5618c84859633 --- /dev/null +++ b/ext/intl/tests/bug78308.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #78308 (IntlPartsIterator key is wrong for KEY_LEFT/KEY_RIGHT) +--SKIPIF-- + +--FILE-- +setText('ABC'); +echo "KEY_LEFT:\n"; +foreach ($iter->getPartsIterator(\IntlPartsIterator::KEY_LEFT) as $key => $value) { + var_dump($key, $value); +} +echo "KEY_RIGHT:\n"; +foreach ($iter->getPartsIterator(\IntlPartsIterator::KEY_RIGHT) as $key => $value) { + var_dump($key, $value); +} +?> +--EXPECT-- +KEY_LEFT: +int(0) +string(1) "A" +int(1) +string(1) "B" +int(2) +string(1) "C" +KEY_RIGHT: +int(1) +string(1) "A" +int(2) +string(1) "B" +int(3) +string(1) "C"