Skip to content

Commit a98fcf3

Browse files
committed
utf8_hop_forward: Do nothing if distance is 0
There is a subtle difference here with existing behavior. Most of the time a zero hop already does nothing; but if the initial conditions were that we were starting the hop past the edge, a runtime error was raised, even though the action was a no-op. Its arguable what to do in this case, but I believe the new behavior is more correct, and it paves the way for future commits where it is more clearly more correct. This adds a conditional and indents the code within the new block, removing now-redundant conditionals.
1 parent 959e6a9 commit a98fcf3

File tree

1 file changed

+20
-22
lines changed

1 file changed

+20
-22
lines changed

inline.h

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,33 +2673,31 @@ Perl_utf8_hop_forward(const U8 *s, SSize_t off, const U8 *end)
26732673
PERL_ARGS_ASSERT_UTF8_HOP_FORWARD;
26742674
assert(off >= 0);
26752675

2676-
if (UNLIKELY(s >= end)) {
2677-
if (s == end) {
2678-
return (U8 *) end;
2676+
if (off != 0) {
2677+
if (UNLIKELY(s >= end)) {
2678+
Perl_croak_nocontext("panic: Start of forward hop (0x%p) is %zd"
2679+
" bytes beyond legal end position (0x%p)",
2680+
s, 1 + s - end, end);
26792681
}
26802682

2681-
Perl_croak_nocontext("panic: Start of forward hop (0x%p) is %zd bytes"
2682-
" beyond legal end position (0x%p)",
2683-
s, 1 + s - end, end);
2684-
}
2685-
2686-
if (off && UNLIKELY(UTF8_IS_CONTINUATION(*s))) {
2687-
/* Get to next non-continuation byte */
2688-
do {
2689-
s++;
2683+
if (UNLIKELY(UTF8_IS_CONTINUATION(*s))) {
2684+
/* Get to next non-continuation byte */
2685+
do {
2686+
s++;
2687+
}
2688+
while (s < end && UTF8_IS_CONTINUATION(*s));
2689+
off--;
26902690
}
2691-
while (s < end && UTF8_IS_CONTINUATION(*s));
2692-
off--;
2693-
}
26942691

2695-
while (off-- && s < end) {
2696-
STRLEN skip = UTF8SKIP(s);
2697-
if ((STRLEN)(end - s) <= skip) {
2698-
GCC_DIAG_IGNORE(-Wcast-qual)
2699-
return (U8 *)end;
2700-
GCC_DIAG_RESTORE
2692+
while (off-- && s < end) {
2693+
STRLEN skip = UTF8SKIP(s);
2694+
if ((STRLEN)(end - s) <= skip) {
2695+
GCC_DIAG_IGNORE(-Wcast-qual)
2696+
return (U8 *)end;
2697+
GCC_DIAG_RESTORE
2698+
}
2699+
s += skip;
27012700
}
2702-
s += skip;
27032701
}
27042702

27052703
GCC_DIAG_IGNORE(-Wcast-qual)

0 commit comments

Comments
 (0)