[php-src] Issue #7734: IntlPartsIterator key is wrong for KEY_LEFT/KEY_RIGHT
| From: | iluuu1994 | 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