[php-src] Issue #7734: IntlPartsIterator key is wrong for KEY_LEFT/KEY_RIGHT

From: Date: Tue, 04 Jan 2022 16:22:11 +0000
Subject: [php-src] Issue #7734: IntlPartsIterator key is wrong for KEY_LEFT/KEY_RIGHT
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-238763@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/7734 Comment Author: iluuu1994 The second case is also fixed, except that there's a different issue where index is rewritten to -1 when rewinding the iterator. https://github.com/php/php-src/blob/e1a238333c2713efc7b8693af380d117d7c85dae/Zend/zend_execute.c#L4513 Usually the index is computed in get_current_key but in this case we're relying on index as a storage mechanism. One way to solve this is to store an index_right in zoi_break_iter_parts which does not get reset after rewind. ```patch diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp index 2027fb45c5..3ea56e80d3 100644 --- a/ext/intl/breakiterator/breakiterator_iterators.cpp +++ b/ext/intl/breakiterator/breakiterator_iterators.cpp @@ -127,6 +127,7 @@ typedef struct zoi_break_iter_parts { zoi_with_current zoi_cur; parts_iter_key_type key_type; BreakIterator_object *bio; /* so we don't have to fetch it all the time */ + zend_ulong index_right; } zoi_break_iter_parts; static void _breakiterator_parts_destroy_it(zend_object_iterator *iter) @@ -136,8 +137,13 @@ static void _breakiterator_parts_destroy_it(zend_object_iterator *iter) static void _breakiterator_parts_get_current_key(zend_object_iterator *iter, zval *key) { - /* the actual work is done in move_forward and rewind */ - ZVAL_LONG(key, iter->index); + zoi_break_iter_parts *zoi_bit = (zoi_break_iter_parts*)iter; + + if (iter->index == 0 && zoi_bit->key_type == PARTS_ITERATOR_KEY_RIGHT) { + ZVAL_LONG(key, zoi_bit->index_right); + } else { + ZVAL_LONG(key, iter->index); + } } static void _breakiterator_parts_move_forward(zend_object_iterator *iter) @@ -163,6 +169,7 @@ static void _breakiterator_parts_move_forward(zend_object_iterator *iter) iter->index = cur; } else if (zoi_bit->key_type == PARTS_ITERATOR_KEY_RIGHT) { iter->index = next; + zoi_bit->index_right = next; } /* else zoi_bit->key_type == PARTS_ITERATOR_KEY_SEQUENTIAL * No need to do anything, the engine increments ->index */ @@ -229,6 +236,7 @@ void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv, assert(((zoi_break_iter_parts*)ii->iterator)->bio->biter != NULL); ((zoi_break_iter_parts*)ii->iterator)->key_type = key_type; + ((zoi_break_iter_parts*)ii->iterator)->index_right = 0; } U_CFUNC PHP_METHOD(IntlPartsIterator, getBreakIterator) ``` But that's not very clean either. I don't see any other ways to solve this. Fun fact, IntlPartsIterator::KEY_RIGHT is used a total of 0 times on GitHub. https://sourcegraph.com/search?q=context:global+IntlPartsIterator::KEY_RIGHT+file:%5C.php%24&patternType=literal

« previous php.bugs (#238763) next »