(perl #131562) correct large line numbers copying eval lines on #line
authorTony Cook <tony@develop-help.com>
Wed, 23 Aug 2017 04:18:26 +0000 (14:18 +1000)
committerTony Cook <tony@develop-help.com>
Mon, 21 Jan 2019 03:40:02 +0000 (14:40 +1100)
Previously this used I32 for line numbers, which takes half the range
of line_t and folds it into negative numbers, leading to trying to store
the lines at negative indexes.

The while loop was also modified to stop storing if/when the line number
no longer fits into cop_line, or no longer fits into SSize_t (as a
positive number) since the index parameter to av_store() is a SSize_t.

toke.c

diff --git a/toke.c b/toke.c
index de4ab2e..5a3fe78 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -1829,14 +1829,14 @@ S_incline(pTHX_ const char *s, const char *end)
                    }
                    else if (GvAV(cfgv)) {
                        AV * const av = GvAV(cfgv);
-                       const I32 start = CopLINE(PL_curcop)+1;
-                       I32 items = AvFILLp(av) - start;
+                       const line_t start = CopLINE(PL_curcop)+1;
+                       SSize_t items = AvFILLp(av) - start;
                        if (items > 0) {
                            AV * const av2 = GvAVn(gv2);
                            SV **svp = AvARRAY(av) + start;
-                           I32 l = (I32)line_num+1;
-                           while (items--)
-                               av_store(av2, l++, SvREFCNT_inc(*svp++));
+                           Size_t l = line_num+1;
+                           while (items-- && l < SSize_t_MAX && l == (line_t)l)
+                               av_store(av2, (SSize_t)l++, SvREFCNT_inc(*svp++));
                        }
                    }
                }