xref: /openbsd-src/gnu/usr.bin/perl/t/op/substr.t (revision 9f11ffb7133c203312a01e4b986886bc88c7d74b)
186685b6dSsthen#!./perl
286685b6dSsthen
386685b6dSsthen#P = start of string  Q = start of substr  R = end of substr  S = end of string
486685b6dSsthen
586685b6dSsthenBEGIN {
686685b6dSsthen    chdir 't' if -d 't';
7b8851fccSafresh1    require './test.pl';
8b8851fccSafresh1    set_up_inc('../lib');
986685b6dSsthen}
1086685b6dSsthenuse warnings ;
1186685b6dSsthen
1286685b6dSsthen$a = 'abcdefxyz';
1386685b6dSsthen$SIG{__WARN__} = sub {
1486685b6dSsthen     if ($_[0] =~ /^substr outside of string/) {
1586685b6dSsthen          $w++;
1686685b6dSsthen     } elsif ($_[0] =~ /^Attempt to use reference as lvalue in substr/) {
1786685b6dSsthen          $w += 2;
1886685b6dSsthen     } elsif ($_[0] =~ /^Use of uninitialized value/) {
1986685b6dSsthen          $w += 3;
2086685b6dSsthen     } else {
2186685b6dSsthen          warn $_[0];
2286685b6dSsthen     }
2386685b6dSsthen};
2486685b6dSsthen
25*9f11ffb7Safresh1plan(400);
2686685b6dSsthen
2786685b6dSsthenrun_tests() unless caller;
2886685b6dSsthen
2986685b6dSsthenmy $krunch = "a";
3086685b6dSsthen
3186685b6dSsthensub run_tests {
3286685b6dSsthen
3386685b6dSsthen$FATAL_MSG = qr/^substr outside of string/;
3486685b6dSsthen
3586685b6dSsthenis(substr($a,0,3), 'abc');   # P=Q R S
3686685b6dSsthenis(substr($a,3,3), 'def');   # P Q R S
3786685b6dSsthenis(substr($a,6,999), 'xyz'); # P Q S R
3886685b6dSsthen$b = substr($a,999,999) ; # warn # P R Q S
3986685b6dSsthenis ($w--, 1);
4086685b6dSstheneval{substr($a,999,999) = "" ; };# P R Q S
4186685b6dSsthenlike ($@, $FATAL_MSG);
4286685b6dSsthenis(substr($a,0,-6), 'abc');  # P=Q R S
4386685b6dSsthenis(substr($a,-3,1), 'x');    # P Q R S
4486685b6dSsthensub{$b = shift}->(substr($a,999,999));
4586685b6dSsthenis ($w--, 1, 'boundless lvalue substr only warns on fetch');
4686685b6dSsthen
4786685b6dSsthensubstr($a,3,3) = 'XYZ';
4886685b6dSsthenis($a, 'abcXYZxyz' );
4986685b6dSsthensubstr($a,0,2) = '';
5086685b6dSsthenis($a, 'cXYZxyz' );
5186685b6dSsthensubstr($a,0,0) = 'ab';
5286685b6dSsthenis($a, 'abcXYZxyz' );
5386685b6dSsthensubstr($a,0,0) = '12345678';
5486685b6dSsthenis($a, '12345678abcXYZxyz' );
5586685b6dSsthensubstr($a,-3,3) = 'def';
5686685b6dSsthenis($a, '12345678abcXYZdef');
5786685b6dSsthensubstr($a,-3,3) = '<';
5886685b6dSsthenis($a, '12345678abcXYZ<' );
5986685b6dSsthensubstr($a,-1,1) = '12345678';
6086685b6dSsthenis($a, '12345678abcXYZ12345678' );
6186685b6dSsthen
6286685b6dSsthen$a = 'abcdefxyz';
6386685b6dSsthen
6486685b6dSsthenis(substr($a,6), 'xyz' );        # P Q R=S
6586685b6dSsthenis(substr($a,-3), 'xyz' );       # P Q R=S
6686685b6dSsthen$b = substr($a,999,999) ; # warning   # P R=S Q
6786685b6dSsthenis($w--, 1);
6886685b6dSstheneval{substr($a,999,999) = "" ; } ;    # P R=S Q
6986685b6dSsthenlike($@, $FATAL_MSG);
7086685b6dSsthenis(substr($a,0), 'abcdefxyz');  # P=Q R=S
7186685b6dSsthenis(substr($a,9), '');           # P Q=R=S
7286685b6dSsthenis(substr($a,-11), 'abcdefxyz'); # Q P R=S
7386685b6dSsthenis(substr($a,-9), 'abcdefxyz');  # P=Q R=S
7486685b6dSsthen
7586685b6dSsthen$a = '54321';
7686685b6dSsthen
7786685b6dSsthen$b = substr($a,-7, 1) ; # warn  # Q R P S
7886685b6dSsthenis($w--, 1);
7986685b6dSstheneval{substr($a,-7, 1) = "" ; }; # Q R P S
8086685b6dSsthenlike($@, $FATAL_MSG);
8186685b6dSsthen$b = substr($a,-7,-6) ; # warn  # Q R P S
8286685b6dSsthenis($w--, 1);
8386685b6dSstheneval{substr($a,-7,-6) = "" ; }; # Q R P S
8486685b6dSsthenlike($@, $FATAL_MSG);
8586685b6dSsthenis(substr($a,-5,-7), '');  # R P=Q S
8686685b6dSsthenis(substr($a, 2,-7), '');  # R P Q S
8786685b6dSsthenis(substr($a,-3,-7), '');  # R P Q S
8886685b6dSsthenis(substr($a, 2,-5), '');  # P=R Q S
8986685b6dSsthenis(substr($a,-3,-5), '');  # P=R Q S
9086685b6dSsthenis(substr($a, 2,-4), '');  # P R Q S
9186685b6dSsthenis(substr($a,-3,-4), '');  # P R Q S
9286685b6dSsthenis(substr($a, 5,-6), '');  # R P Q=S
9386685b6dSsthenis(substr($a, 5,-5), '');  # P=R Q S
9486685b6dSsthenis(substr($a, 5,-3), '');  # P R Q=S
9586685b6dSsthen$b = substr($a, 7,-7) ; # warn  # R P S Q
9686685b6dSsthenis($w--, 1);
9786685b6dSstheneval{substr($a, 7,-7) = "" ; }; # R P S Q
9886685b6dSsthenlike($@, $FATAL_MSG);
9986685b6dSsthen$b = substr($a, 7,-5) ; # warn  # P=R S Q
10086685b6dSsthenis($w--, 1);
10186685b6dSstheneval{substr($a, 7,-5) = "" ; }; # P=R S Q
10286685b6dSsthenlike($@, $FATAL_MSG);
10386685b6dSsthen$b = substr($a, 7,-3) ; # warn  # P Q S Q
10486685b6dSsthenis($w--, 1);
10586685b6dSstheneval{substr($a, 7,-3) = "" ; }; # P Q S Q
10686685b6dSsthenlike($@, $FATAL_MSG);
10786685b6dSsthen$b = substr($a, 7, 0) ; # warn  # P S Q=R
10886685b6dSsthenis($w--, 1);
10986685b6dSstheneval{substr($a, 7, 0) = "" ; }; # P S Q=R
11086685b6dSsthenlike($@, $FATAL_MSG);
11186685b6dSsthen
11286685b6dSsthenis(substr($a,-7,2), '');   # Q P=R S
11386685b6dSsthenis(substr($a,-7,4), '54'); # Q P R S
11486685b6dSsthenis(substr($a,-7,7), '54321');# Q P R=S
11586685b6dSsthenis(substr($a,-7,9), '54321');# Q P S R
11686685b6dSsthenis(substr($a,-5,0), '');   # P=Q=R S
11786685b6dSsthenis(substr($a,-5,3), '543');# P=Q R S
11886685b6dSsthenis(substr($a,-5,5), '54321');# P=Q R=S
11986685b6dSsthenis(substr($a,-5,7), '54321');# P=Q S R
12086685b6dSsthenis(substr($a,-3,0), '');   # P Q=R S
12186685b6dSsthenis(substr($a,-3,3), '321');# P Q R=S
12286685b6dSsthenis(substr($a,-2,3), '21'); # P Q S R
12386685b6dSsthenis(substr($a,0,-5), '');   # P=Q=R S
12486685b6dSsthenis(substr($a,2,-3), '');   # P Q=R S
12586685b6dSsthenis(substr($a,0,0), '');    # P=Q=R S
12686685b6dSsthenis(substr($a,0,5), '54321');# P=Q R=S
12786685b6dSsthenis(substr($a,0,7), '54321');# P=Q S R
12886685b6dSsthenis(substr($a,2,0), '');    # P Q=R S
12986685b6dSsthenis(substr($a,2,3), '321'); # P Q R=S
13086685b6dSsthenis(substr($a,5,0), '');    # P Q=R=S
13186685b6dSsthenis(substr($a,5,2), '');    # P Q=S R
13286685b6dSsthenis(substr($a,-7,-5), '');  # Q P=R S
13386685b6dSsthenis(substr($a,-7,-2), '543');# Q P R S
13486685b6dSsthenis(substr($a,-5,-5), '');  # P=Q=R S
13586685b6dSsthenis(substr($a,-5,-2), '543');# P=Q R S
13686685b6dSsthenis(substr($a,-3,-3), '');  # P Q=R S
13786685b6dSsthenis(substr($a,-3,-1), '32');# P Q R S
13886685b6dSsthen
13986685b6dSsthen$a = '';
14086685b6dSsthen
14186685b6dSsthenis(substr($a,-2,2), '');   # Q P=R=S
14286685b6dSsthenis(substr($a,0,0), '');    # P=Q=R=S
14386685b6dSsthenis(substr($a,0,1), '');    # P=Q=S R
14486685b6dSsthenis(substr($a,-2,3), '');   # Q P=S R
14586685b6dSsthenis(substr($a,-2), '');     # Q P=R=S
14686685b6dSsthenis(substr($a,0), '');      # P=Q=R=S
14786685b6dSsthen
14886685b6dSsthen
14986685b6dSsthenis(substr($a,0,-1), '');   # R P=Q=S
15086685b6dSsthen$b = substr($a,-2, 0) ; # warn  # Q=R P=S
15186685b6dSsthenis($w--, 1);
15286685b6dSstheneval{substr($a,-2, 0) = "" ; }; # Q=R P=S
15386685b6dSsthenlike($@, $FATAL_MSG);
15486685b6dSsthen
15586685b6dSsthen$b = substr($a,-2, 1) ; # warn  # Q R P=S
15686685b6dSsthenis($w--, 1);
15786685b6dSstheneval{substr($a,-2, 1) = "" ; }; # Q R P=S
15886685b6dSsthenlike($@, $FATAL_MSG);
15986685b6dSsthen
16086685b6dSsthen$b = substr($a,-2,-1) ; # warn  # Q R P=S
16186685b6dSsthenis($w--, 1);
16286685b6dSstheneval{substr($a,-2,-1) = "" ; }; # Q R P=S
16386685b6dSsthenlike($@, $FATAL_MSG);
16486685b6dSsthen
16586685b6dSsthen$b = substr($a,-2,-2) ; # warn  # Q=R P=S
16686685b6dSsthenis($w--, 1);
16786685b6dSstheneval{substr($a,-2,-2) = "" ; }; # Q=R P=S
16886685b6dSsthenlike($@, $FATAL_MSG);
16986685b6dSsthen
17086685b6dSsthen$b = substr($a, 1,-2) ; # warn  # R P=S Q
17186685b6dSsthenis($w--, 1);
17286685b6dSstheneval{substr($a, 1,-2) = "" ; }; # R P=S Q
17386685b6dSsthenlike($@, $FATAL_MSG);
17486685b6dSsthen
17586685b6dSsthen$b = substr($a, 1, 1) ; # warn  # P=S Q R
17686685b6dSsthenis($w--, 1);
17786685b6dSstheneval{substr($a, 1, 1) = "" ; }; # P=S Q R
17886685b6dSsthenlike($@, $FATAL_MSG);
17986685b6dSsthen
18086685b6dSsthen$b = substr($a, 1, 0) ;# warn   # P=S Q=R
18186685b6dSsthenis($w--, 1);
18286685b6dSstheneval{substr($a, 1, 0) = "" ; }; # P=S Q=R
18386685b6dSsthenlike($@, $FATAL_MSG);
18486685b6dSsthen
18586685b6dSsthen$b = substr($a,1) ; # warning   # P=R=S Q
18686685b6dSsthenis($w--, 1);
18786685b6dSstheneval{substr($a,1) = "" ; };     # P=R=S Q
18886685b6dSsthenlike($@, $FATAL_MSG);
18986685b6dSsthen
19086685b6dSsthen$b = substr($a,-7,-6) ; # warn  # Q R P S
19186685b6dSsthenis($w--, 1);
19286685b6dSstheneval{substr($a,-7,-6) = "" ; }; # Q R P S
19386685b6dSsthenlike($@, $FATAL_MSG);
19486685b6dSsthen
19586685b6dSsthenmy $a = 'zxcvbnm';
19686685b6dSsthensubstr($a,2,0) = '';
19786685b6dSsthenis($a, 'zxcvbnm');
19886685b6dSsthensubstr($a,7,0) = '';
19986685b6dSsthenis($a, 'zxcvbnm');
20086685b6dSsthensubstr($a,5,0) = '';
20186685b6dSsthenis($a, 'zxcvbnm');
20286685b6dSsthensubstr($a,0,2) = 'pq';
20386685b6dSsthenis($a, 'pqcvbnm');
20486685b6dSsthensubstr($a,2,0) = 'r';
20586685b6dSsthenis($a, 'pqrcvbnm');
20686685b6dSsthensubstr($a,8,0) = 'asd';
20786685b6dSsthenis($a, 'pqrcvbnmasd');
20886685b6dSsthensubstr($a,0,2) = 'iop';
20986685b6dSsthenis($a, 'ioprcvbnmasd');
21086685b6dSsthensubstr($a,0,5) = 'fgh';
21186685b6dSsthenis($a, 'fghvbnmasd');
21286685b6dSsthensubstr($a,3,5) = 'jkl';
21386685b6dSsthenis($a, 'fghjklsd');
21486685b6dSsthensubstr($a,3,2) = '1234';
21586685b6dSsthenis($a, 'fgh1234lsd');
21686685b6dSsthen
21786685b6dSsthen
21886685b6dSsthen# with lexicals (and in re-entered scopes)
21986685b6dSsthenfor (0,1) {
22086685b6dSsthen  my $txt;
22186685b6dSsthen  unless ($_) {
22286685b6dSsthen    $txt = "Foo";
22386685b6dSsthen    substr($txt, -1) = "X";
22486685b6dSsthen    is($txt, "FoX");
22586685b6dSsthen  }
22686685b6dSsthen  else {
22786685b6dSsthen    substr($txt, 0, 1) = "X";
22886685b6dSsthen    is($txt, "X");
22986685b6dSsthen  }
23086685b6dSsthen}
23186685b6dSsthen
23286685b6dSsthen$w = 0 ;
23386685b6dSsthen# coercion of references
23486685b6dSsthen{
23586685b6dSsthen  my $s = [];
23686685b6dSsthen  substr($s, 0, 1) = 'Foo';
23786685b6dSsthen  is (substr($s,0,7), "FooRRAY");
23886685b6dSsthen  is ($w,2);
23986685b6dSsthen  $w = 0;
24086685b6dSsthen}
24186685b6dSsthen
24286685b6dSsthen# check no spurious warnings
24386685b6dSsthenis($w, 0);
24486685b6dSsthen
24586685b6dSsthen# check new 4 arg replacement syntax
24686685b6dSsthen$a = "abcxyz";
24786685b6dSsthen$w = 0;
24886685b6dSsthenis(substr($a, 0, 3, ""), "abc");
24986685b6dSsthenis($a, "xyz");
25086685b6dSsthenis(substr($a, 0, 0, "abc"), "");
25186685b6dSsthenis($a, "abcxyz");
25286685b6dSsthenis(substr($a, 3, -1, ""), "xy");
25386685b6dSsthenis($a, "abcz");
25486685b6dSsthen
25586685b6dSsthenis(substr($a, 3, undef, "xy"), "");
25686685b6dSsthenis($a, "abcxyz");
25786685b6dSsthenis($w, 3);
25886685b6dSsthen
25986685b6dSsthen$w = 0;
26086685b6dSsthen
26186685b6dSsthenis(substr($a, 3, 9999999, ""), "xyz");
26286685b6dSsthenis($a, "abc");
26386685b6dSstheneval{substr($a, -99, 0, "") };
26486685b6dSsthenlike($@, $FATAL_MSG);
26586685b6dSstheneval{substr($a, 99, 3, "") };
26686685b6dSsthenlike($@, $FATAL_MSG);
26786685b6dSsthen
26886685b6dSsthensubstr($a, 0, length($a), "foo");
26986685b6dSsthenis ($a, "foo");
27086685b6dSsthenis ($w, 0);
27186685b6dSsthen
27286685b6dSsthen# using 4 arg substr as lvalue is a compile time error
27386685b6dSstheneval 'substr($a,0,0,"") = "abc"';
27486685b6dSsthenlike ($@, qr/Can't modify substr/);
27586685b6dSsthenis ($a, "foo");
27686685b6dSsthen
27786685b6dSsthen$a = "abcdefgh";
27886685b6dSsthenis(sub { shift }->(substr($a, 0, 4, "xxxx")), 'abcd');
27986685b6dSsthenis($a, 'xxxxefgh');
28086685b6dSsthen
28186685b6dSsthen{
28286685b6dSsthen    my $y = 10;
28386685b6dSsthen    $y = "2" . $y;
28486685b6dSsthen    is ($y, 210);
28586685b6dSsthen}
28686685b6dSsthen
28786685b6dSsthen# utf8 sanity
28886685b6dSsthen{
28986685b6dSsthen    my $x = substr("a\x{263a}b",0);
29086685b6dSsthen    is(length($x), 3);
29186685b6dSsthen    $x = substr($x,1,1);
29286685b6dSsthen    is($x, "\x{263a}");
29386685b6dSsthen    $x = $x x 2;
29486685b6dSsthen    is(length($x), 2);
29586685b6dSsthen    substr($x,0,1) = "abcd";
29686685b6dSsthen    is($x, "abcd\x{263a}");
29786685b6dSsthen    is(length($x), 5);
29886685b6dSsthen    $x = reverse $x;
29986685b6dSsthen    is(length($x), 5);
30086685b6dSsthen    is($x, "\x{263a}dcba");
30186685b6dSsthen
30286685b6dSsthen    my $z = 10;
30386685b6dSsthen    $z = "21\x{263a}" . $z;
30486685b6dSsthen    is(length($z), 5);
30586685b6dSsthen    is($z, "21\x{263a}10");
30686685b6dSsthen}
30786685b6dSsthen
30886685b6dSsthen# replacement should work on magical values
30986685b6dSsthenrequire Tie::Scalar;
31086685b6dSsthenmy %data;
31186685b6dSsthentie $data{'a'}, 'Tie::StdScalar';  # makes $data{'a'} magical
31286685b6dSsthen$data{a} = "firstlast";
31386685b6dSsthenis(substr($data{'a'}, 0, 5, ""), "first");
31486685b6dSsthenis($data{'a'}, "last");
31586685b6dSsthen
31686685b6dSsthen# more utf8
31786685b6dSsthen
31886685b6dSsthen# The following two originally from Ignasi Roca.
31986685b6dSsthen
32086685b6dSsthen$x = "\xF1\xF2\xF3";
32186685b6dSsthensubstr($x, 0, 1) = "\x{100}"; # Ignasi had \x{FF}
32286685b6dSsthenis(length($x), 3);
32386685b6dSsthenis($x, "\x{100}\xF2\xF3");
32486685b6dSsthenis(substr($x, 0, 1), "\x{100}");
32586685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
32686685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
32786685b6dSsthen
32886685b6dSsthen$x = "\xF1\xF2\xF3";
32986685b6dSsthensubstr($x, 0, 1) = "\x{100}\x{FF}"; # Ignasi had \x{FF}
33086685b6dSsthenis(length($x), 4);
33186685b6dSsthenis($x, "\x{100}\x{FF}\xF2\xF3");
33286685b6dSsthenis(substr($x, 0, 1), "\x{100}");
33386685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
33486685b6dSsthenis(substr($x, 2, 1), "\x{F2}");
33586685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
33686685b6dSsthen
33786685b6dSsthen# more utf8 lval exercise
33886685b6dSsthen
33986685b6dSsthen$x = "\xF1\xF2\xF3";
34086685b6dSsthensubstr($x, 0, 2) = "\x{100}\xFF";
34186685b6dSsthenis(length($x), 3);
34286685b6dSsthenis($x, "\x{100}\xFF\xF3");
34386685b6dSsthenis(substr($x, 0, 1), "\x{100}");
34486685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
34586685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
34686685b6dSsthen
34786685b6dSsthen$x = "\xF1\xF2\xF3";
34886685b6dSsthensubstr($x, 1, 1) = "\x{100}\xFF";
34986685b6dSsthenis(length($x), 4);
35086685b6dSsthenis($x, "\xF1\x{100}\xFF\xF3");
35186685b6dSsthenis(substr($x, 0, 1), "\x{F1}");
35286685b6dSsthenis(substr($x, 1, 1), "\x{100}");
35386685b6dSsthenis(substr($x, 2, 1), "\x{FF}");
35486685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
35586685b6dSsthen
35686685b6dSsthen$x = "\xF1\xF2\xF3";
35786685b6dSsthensubstr($x, 2, 1) = "\x{100}\xFF";
35886685b6dSsthenis(length($x), 4);
35986685b6dSsthenis($x, "\xF1\xF2\x{100}\xFF");
36086685b6dSsthenis(substr($x, 0, 1), "\x{F1}");
36186685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
36286685b6dSsthenis(substr($x, 2, 1), "\x{100}");
36386685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
36486685b6dSsthen
36586685b6dSsthen$x = "\xF1\xF2\xF3";
36686685b6dSsthensubstr($x, 3, 1) = "\x{100}\xFF";
36786685b6dSsthenis(length($x), 5);
36886685b6dSsthenis($x, "\xF1\xF2\xF3\x{100}\xFF");
36986685b6dSsthenis(substr($x, 0, 1), "\x{F1}");
37086685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
37186685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
37286685b6dSsthenis(substr($x, 3, 1), "\x{100}");
37386685b6dSsthenis(substr($x, 4, 1), "\x{FF}");
37486685b6dSsthen
37586685b6dSsthen$x = "\xF1\xF2\xF3";
37686685b6dSsthensubstr($x, -1, 1) = "\x{100}\xFF";
37786685b6dSsthenis(length($x), 4);
37886685b6dSsthenis($x, "\xF1\xF2\x{100}\xFF");
37986685b6dSsthenis(substr($x, 0, 1), "\x{F1}");
38086685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
38186685b6dSsthenis(substr($x, 2, 1), "\x{100}");
38286685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
38386685b6dSsthen
38486685b6dSsthen$x = "\xF1\xF2\xF3";
38586685b6dSsthensubstr($x, -1, 0) = "\x{100}\xFF";
38686685b6dSsthenis(length($x), 5);
38786685b6dSsthenis($x, "\xF1\xF2\x{100}\xFF\xF3");
38886685b6dSsthenis(substr($x, 0, 1), "\x{F1}");
38986685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
39086685b6dSsthenis(substr($x, 2, 1), "\x{100}");
39186685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
39286685b6dSsthenis(substr($x, 4, 1), "\x{F3}");
39386685b6dSsthen
39486685b6dSsthen$x = "\xF1\xF2\xF3";
39586685b6dSsthensubstr($x, 0, -1) = "\x{100}\xFF";
39686685b6dSsthenis(length($x), 3);
39786685b6dSsthenis($x, "\x{100}\xFF\xF3");
39886685b6dSsthenis(substr($x, 0, 1), "\x{100}");
39986685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
40086685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
40186685b6dSsthen
40286685b6dSsthen$x = "\xF1\xF2\xF3";
40386685b6dSsthensubstr($x, 0, -2) = "\x{100}\xFF";
40486685b6dSsthenis(length($x), 4);
40586685b6dSsthenis($x, "\x{100}\xFF\xF2\xF3");
40686685b6dSsthenis(substr($x, 0, 1), "\x{100}");
40786685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
40886685b6dSsthenis(substr($x, 2, 1), "\x{F2}");
40986685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
41086685b6dSsthen
41186685b6dSsthen$x = "\xF1\xF2\xF3";
41286685b6dSsthensubstr($x, 0, -3) = "\x{100}\xFF";
41386685b6dSsthenis(length($x), 5);
41486685b6dSsthenis($x, "\x{100}\xFF\xF1\xF2\xF3");
41586685b6dSsthenis(substr($x, 0, 1), "\x{100}");
41686685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
41786685b6dSsthenis(substr($x, 2, 1), "\x{F1}");
41886685b6dSsthenis(substr($x, 3, 1), "\x{F2}");
41986685b6dSsthenis(substr($x, 4, 1), "\x{F3}");
42086685b6dSsthen
42186685b6dSsthen$x = "\xF1\xF2\xF3";
42286685b6dSsthensubstr($x, 1, -1) = "\x{100}\xFF";
42386685b6dSsthenis(length($x), 4);
42486685b6dSsthenis($x, "\xF1\x{100}\xFF\xF3");
42586685b6dSsthenis(substr($x, 0, 1), "\x{F1}");
42686685b6dSsthenis(substr($x, 1, 1), "\x{100}");
42786685b6dSsthenis(substr($x, 2, 1), "\x{FF}");
42886685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
42986685b6dSsthen
43086685b6dSsthen$x = "\xF1\xF2\xF3";
43186685b6dSsthensubstr($x, -1, -1) = "\x{100}\xFF";
43286685b6dSsthenis(length($x), 5);
43386685b6dSsthenis($x, "\xF1\xF2\x{100}\xFF\xF3");
43486685b6dSsthenis(substr($x, 0, 1), "\x{F1}");
43586685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
43686685b6dSsthenis(substr($x, 2, 1), "\x{100}");
43786685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
43886685b6dSsthenis(substr($x, 4, 1), "\x{F3}");
43986685b6dSsthen
44086685b6dSsthen# And tests for already-UTF8 one
44186685b6dSsthen
44286685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
44386685b6dSsthensubstr($x, 0, 1) = "\x{100}";
44486685b6dSsthenis(length($x), 3);
44586685b6dSsthenis($x, "\x{100}\xF2\xF3");
44686685b6dSsthenis(substr($x, 0, 1), "\x{100}");
44786685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
44886685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
44986685b6dSsthen
45086685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
45186685b6dSsthensubstr($x, 0, 1) = "\x{100}\x{FF}";
45286685b6dSsthenis(length($x), 4);
45386685b6dSsthenis($x, "\x{100}\x{FF}\xF2\xF3");
45486685b6dSsthenis(substr($x, 0, 1), "\x{100}");
45586685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
45686685b6dSsthenis(substr($x, 2, 1), "\x{F2}");
45786685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
45886685b6dSsthen
45986685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
46086685b6dSsthensubstr($x, 0, 2) = "\x{100}\xFF";
46186685b6dSsthenis(length($x), 3);
46286685b6dSsthenis($x, "\x{100}\xFF\xF3");
46386685b6dSsthenis(substr($x, 0, 1), "\x{100}");
46486685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
46586685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
46686685b6dSsthen
46786685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
46886685b6dSsthensubstr($x, 1, 1) = "\x{100}\xFF";
46986685b6dSsthenis(length($x), 4);
47086685b6dSsthenis($x, "\x{101}\x{100}\xFF\xF3");
47186685b6dSsthenis(substr($x, 0, 1), "\x{101}");
47286685b6dSsthenis(substr($x, 1, 1), "\x{100}");
47386685b6dSsthenis(substr($x, 2, 1), "\x{FF}");
47486685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
47586685b6dSsthen
47686685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
47786685b6dSsthensubstr($x, 2, 1) = "\x{100}\xFF";
47886685b6dSsthenis(length($x), 4);
47986685b6dSsthenis($x, "\x{101}\xF2\x{100}\xFF");
48086685b6dSsthenis(substr($x, 0, 1), "\x{101}");
48186685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
48286685b6dSsthenis(substr($x, 2, 1), "\x{100}");
48386685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
48486685b6dSsthen
48586685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
48686685b6dSsthensubstr($x, 3, 1) = "\x{100}\xFF";
48786685b6dSsthenis(length($x), 5);
48886685b6dSsthenis($x, "\x{101}\x{F2}\x{F3}\x{100}\xFF");
48986685b6dSsthenis(substr($x, 0, 1), "\x{101}");
49086685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
49186685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
49286685b6dSsthenis(substr($x, 3, 1), "\x{100}");
49386685b6dSsthenis(substr($x, 4, 1), "\x{FF}");
49486685b6dSsthen
49586685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
49686685b6dSsthensubstr($x, -1, 1) = "\x{100}\xFF";
49786685b6dSsthenis(length($x), 4);
49886685b6dSsthenis($x, "\x{101}\xF2\x{100}\xFF");
49986685b6dSsthenis(substr($x, 0, 1), "\x{101}");
50086685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
50186685b6dSsthenis(substr($x, 2, 1), "\x{100}");
50286685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
50386685b6dSsthen
50486685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
50586685b6dSsthensubstr($x, -1, 0) = "\x{100}\xFF";
50686685b6dSsthenis(length($x), 5);
50786685b6dSsthenis($x, "\x{101}\xF2\x{100}\xFF\xF3");
50886685b6dSsthenis(substr($x, 0, 1), "\x{101}");
50986685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
51086685b6dSsthenis(substr($x, 2, 1), "\x{100}");
51186685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
51286685b6dSsthenis(substr($x, 4, 1), "\x{F3}");
51386685b6dSsthen
51486685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
51586685b6dSsthensubstr($x, 0, -1) = "\x{100}\xFF";
51686685b6dSsthenis(length($x), 3);
51786685b6dSsthenis($x, "\x{100}\xFF\xF3");
51886685b6dSsthenis(substr($x, 0, 1), "\x{100}");
51986685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
52086685b6dSsthenis(substr($x, 2, 1), "\x{F3}");
52186685b6dSsthen
52286685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
52386685b6dSsthensubstr($x, 0, -2) = "\x{100}\xFF";
52486685b6dSsthenis(length($x), 4);
52586685b6dSsthenis($x, "\x{100}\xFF\xF2\xF3");
52686685b6dSsthenis(substr($x, 0, 1), "\x{100}");
52786685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
52886685b6dSsthenis(substr($x, 2, 1), "\x{F2}");
52986685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
53086685b6dSsthen
53186685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
53286685b6dSsthensubstr($x, 0, -3) = "\x{100}\xFF";
53386685b6dSsthenis(length($x), 5);
53486685b6dSsthenis($x, "\x{100}\xFF\x{101}\x{F2}\x{F3}");
53586685b6dSsthenis(substr($x, 0, 1), "\x{100}");
53686685b6dSsthenis(substr($x, 1, 1), "\x{FF}");
53786685b6dSsthenis(substr($x, 2, 1), "\x{101}");
53886685b6dSsthenis(substr($x, 3, 1), "\x{F2}");
53986685b6dSsthenis(substr($x, 4, 1), "\x{F3}");
54086685b6dSsthen
54186685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
54286685b6dSsthensubstr($x, 1, -1) = "\x{100}\xFF";
54386685b6dSsthenis(length($x), 4);
54486685b6dSsthenis($x, "\x{101}\x{100}\xFF\xF3");
54586685b6dSsthenis(substr($x, 0, 1), "\x{101}");
54686685b6dSsthenis(substr($x, 1, 1), "\x{100}");
54786685b6dSsthenis(substr($x, 2, 1), "\x{FF}");
54886685b6dSsthenis(substr($x, 3, 1), "\x{F3}");
54986685b6dSsthen
55086685b6dSsthen$x = "\x{101}\x{F2}\x{F3}";
55186685b6dSsthensubstr($x, -1, -1) = "\x{100}\xFF";
55286685b6dSsthenis(length($x), 5);
55386685b6dSsthenis($x, "\x{101}\xF2\x{100}\xFF\xF3");
55486685b6dSsthenis(substr($x, 0, 1), "\x{101}");
55586685b6dSsthenis(substr($x, 1, 1), "\x{F2}");
55686685b6dSsthenis(substr($x, 2, 1), "\x{100}");
55786685b6dSsthenis(substr($x, 3, 1), "\x{FF}");
55886685b6dSsthenis(substr($x, 4, 1), "\x{F3}");
55986685b6dSsthen
56086685b6dSsthensubstr($x = "ab", 0, 0, "\x{100}\x{200}");
56186685b6dSsthenis($x, "\x{100}\x{200}ab");
56286685b6dSsthen
56386685b6dSsthensubstr($x = "\x{100}\x{200}", 0, 0, "ab");
56486685b6dSsthenis($x, "ab\x{100}\x{200}");
56586685b6dSsthen
56686685b6dSsthensubstr($x = "ab", 1, 0, "\x{100}\x{200}");
56786685b6dSsthenis($x, "a\x{100}\x{200}b");
56886685b6dSsthen
56986685b6dSsthensubstr($x = "\x{100}\x{200}", 1, 0, "ab");
57086685b6dSsthenis($x, "\x{100}ab\x{200}");
57186685b6dSsthen
57286685b6dSsthensubstr($x = "ab", 2, 0, "\x{100}\x{200}");
57386685b6dSsthenis($x, "ab\x{100}\x{200}");
57486685b6dSsthen
57586685b6dSsthensubstr($x = "\x{100}\x{200}", 2, 0, "ab");
57686685b6dSsthenis($x, "\x{100}\x{200}ab");
57786685b6dSsthen
57886685b6dSsthensubstr($x = "\xFFb", 0, 0, "\x{100}\x{200}");
57986685b6dSsthenis($x, "\x{100}\x{200}\xFFb");
58086685b6dSsthen
58186685b6dSsthensubstr($x = "\x{100}\x{200}", 0, 0, "\xFFb");
58286685b6dSsthenis($x, "\xFFb\x{100}\x{200}");
58386685b6dSsthen
58486685b6dSsthensubstr($x = "\xFFb", 1, 0, "\x{100}\x{200}");
58586685b6dSsthenis($x, "\xFF\x{100}\x{200}b");
58686685b6dSsthen
58786685b6dSsthensubstr($x = "\x{100}\x{200}", 1, 0, "\xFFb");
58886685b6dSsthenis($x, "\x{100}\xFFb\x{200}");
58986685b6dSsthen
59086685b6dSsthensubstr($x = "\xFFb", 2, 0, "\x{100}\x{200}");
59186685b6dSsthenis($x, "\xFFb\x{100}\x{200}");
59286685b6dSsthen
59386685b6dSsthensubstr($x = "\x{100}\x{200}", 2, 0, "\xFFb");
59486685b6dSsthenis($x, "\x{100}\x{200}\xFFb");
59586685b6dSsthen
59686685b6dSsthen# [perl #20933]
59786685b6dSsthen{
59886685b6dSsthen    my $s = "ab";
59986685b6dSsthen    my @r;
60086685b6dSsthen    $r[$_] = \ substr $s, $_, 1 for (0, 1);
60186685b6dSsthen    is(join("", map { $$_ } @r), "ab");
60286685b6dSsthen}
60386685b6dSsthen
60486685b6dSsthen# [perl #23207]
60586685b6dSsthen{
60686685b6dSsthen    sub ss {
60786685b6dSsthen	substr($_[0],0,1) ^= substr($_[0],1,1) ^=
60886685b6dSsthen	substr($_[0],0,1) ^= substr($_[0],1,1);
60986685b6dSsthen    }
61086685b6dSsthen    my $x = my $y = 'AB'; ss $x; ss $y;
61186685b6dSsthen    is($x, $y);
61286685b6dSsthen}
61386685b6dSsthen
61486685b6dSsthen# [perl #24605]
61586685b6dSsthen{
61686685b6dSsthen    my $x = "0123456789\x{500}";
61786685b6dSsthen    my $y = substr $x, 4;
61886685b6dSsthen    is(substr($x, 7, 1), "7");
61986685b6dSsthen}
62086685b6dSsthen
62186685b6dSsthen# multiple assignments to lvalue [perl #24346]
62286685b6dSsthen{
62386685b6dSsthen    my $x = "abcdef";
62486685b6dSsthen    for (substr($x,1,3)) {
62586685b6dSsthen	is($_, 'bcd');
62686685b6dSsthen	$_ = 'XX';
62786685b6dSsthen	is($_, 'XX');
62886685b6dSsthen	is($x, 'aXXef');
62986685b6dSsthen	$_ = "\xFF";
63086685b6dSsthen	is($_, "\xFF");
63186685b6dSsthen	is($x, "a\xFFef");
63286685b6dSsthen	$_ = "\xF1\xF2\xF3\xF4\xF5\xF6";
63386685b6dSsthen	is($_, "\xF1\xF2\xF3\xF4\xF5\xF6");
63486685b6dSsthen	is($x, "a\xF1\xF2\xF3\xF4\xF5\xF6ef");
63586685b6dSsthen	$_ = 'YYYY';
63686685b6dSsthen	is($_, 'YYYY');
63786685b6dSsthen	is($x, 'aYYYYef');
63886685b6dSsthen    }
63986685b6dSsthen    $x = "abcdef";
64086685b6dSsthen    for (substr($x,1)) {
64186685b6dSsthen	is($_, 'bcdef');
64286685b6dSsthen	$_ = 'XX';
64386685b6dSsthen	is($_, 'XX');
64486685b6dSsthen	is($x, 'aXX');
64586685b6dSsthen	$x .= "frompswiggle";
64686685b6dSsthen	is $_, "XXfrompswiggle";
64786685b6dSsthen    }
64886685b6dSsthen    $x = "abcdef";
64986685b6dSsthen    for (substr($x,1,-1)) {
65086685b6dSsthen	is($_, 'bcde');
65186685b6dSsthen	$_ = 'XX';
65286685b6dSsthen	is($_, 'XX');
65386685b6dSsthen	is($x, 'aXXf');
65486685b6dSsthen	$x .= "frompswiggle";
65586685b6dSsthen	is $_, "XXffrompswiggl";
65686685b6dSsthen    }
65786685b6dSsthen    $x = "abcdef";
65886685b6dSsthen    for (substr($x,-5,3)) {
65986685b6dSsthen	is($_, 'bcd');
66086685b6dSsthen	$_ = 'XX';   # now $_ is substr($x, -4, 2)
66186685b6dSsthen	is($_, 'XX');
66286685b6dSsthen	is($x, 'aXXef');
66386685b6dSsthen	$x .= "frompswiggle";
66486685b6dSsthen	is $_, "gg";
66586685b6dSsthen    }
66686685b6dSsthen    $x = "abcdef";
66786685b6dSsthen    for (substr($x,-5)) {
66886685b6dSsthen	is($_, 'bcdef');
66986685b6dSsthen	$_ = 'XX';  # now substr($x, -2)
67086685b6dSsthen	is($_, 'XX');
67186685b6dSsthen	is($x, 'aXX');
67286685b6dSsthen	$x .= "frompswiggle";
67386685b6dSsthen	is $_, "le";
67486685b6dSsthen    }
67586685b6dSsthen    $x = "abcdef";
67686685b6dSsthen    for (substr($x,-5,-1)) {
67786685b6dSsthen	is($_, 'bcde');
67886685b6dSsthen	$_ = 'XX';  # now substr($x, -3, -1)
67986685b6dSsthen	is($_, 'XX');
68086685b6dSsthen	is($x, 'aXXf');
68186685b6dSsthen	$x .= "frompswiggle";
68286685b6dSsthen	is $_, "gl";
68386685b6dSsthen    }
68486685b6dSsthen}
68586685b6dSsthen
686b8851fccSafresh1# Also part of perl #24346; scalar(substr...) should not affect lvalueness
687b8851fccSafresh1{
688b8851fccSafresh1    my $str = "abcdef";
689b8851fccSafresh1    sub { $_[0] = 'dea' }->( scalar substr $str, 3, 2 );
690b8851fccSafresh1    is $str, 'abcdeaf', 'scalar does not affect lvalueness of substr';
691b8851fccSafresh1}
692b8851fccSafresh1
69386685b6dSsthen# [perl #24200] string corruption with lvalue sub
69486685b6dSsthen
69586685b6dSsthen{
69686685b6dSsthen    sub bar: lvalue { substr $krunch, 0 }
69786685b6dSsthen    bar = "XXX";
69886685b6dSsthen    is(bar, 'XXX');
69986685b6dSsthen    $krunch = '123456789';
70086685b6dSsthen    is(bar, '123456789');
70186685b6dSsthen}
70286685b6dSsthen
70386685b6dSsthen# [perl #29149]
70486685b6dSsthen{
70586685b6dSsthen    my $text  = "0123456789\xED ";
70686685b6dSsthen    utf8::upgrade($text);
70786685b6dSsthen    my $pos = 5;
70886685b6dSsthen    pos($text) = $pos;
70986685b6dSsthen    my $a = substr($text, $pos, $pos);
71086685b6dSsthen    is(substr($text,$pos,1), $pos);
71186685b6dSsthen
71286685b6dSsthen}
71386685b6dSsthen
71486685b6dSsthen# [perl #34976] incorrect caching of utf8 substr length
71586685b6dSsthen{
71686685b6dSsthen    my  $a = "abcd\x{100}";
71786685b6dSsthen    is(substr($a,1,2), 'bc');
71886685b6dSsthen    is(substr($a,1,1), 'b');
71986685b6dSsthen}
72086685b6dSsthen
72186685b6dSsthen# [perl #62646] offsets exceeding 32 bits on 64-bit system
72286685b6dSsthenSKIP: {
72386685b6dSsthen    skip("32-bit system", 24) unless ~0 > 0xffffffff;
72486685b6dSsthen    my $a = "abc";
72586685b6dSsthen    my $s;
72686685b6dSsthen    my $r;
72786685b6dSsthen
72886685b6dSsthen    utf8::downgrade($a);
72986685b6dSsthen    for (1..2) {
73086685b6dSsthen	$w = 0;
73186685b6dSsthen	$r = substr($a, 0xffffffff, 1);
73286685b6dSsthen	is($r, undef);
73386685b6dSsthen	is($w, 1);
73486685b6dSsthen
73586685b6dSsthen	$w = 0;
73686685b6dSsthen	$r = substr($a, 0xffffffff+1, 1);
73786685b6dSsthen	is($r, undef);
73886685b6dSsthen	is($w, 1);
73986685b6dSsthen
74086685b6dSsthen	$w = 0;
74186685b6dSsthen	ok( !eval { $r = substr($s=$a, 0xffffffff, 1, "_"); 1 } );
74286685b6dSsthen	is($r, undef);
74386685b6dSsthen	is($s, $a);
74486685b6dSsthen	is($w, 0);
74586685b6dSsthen
74686685b6dSsthen	$w = 0;
74786685b6dSsthen	ok( !eval { $r = substr($s=$a, 0xffffffff+1, 1, "_"); 1 } );
74886685b6dSsthen	is($r, undef);
74986685b6dSsthen	is($s, $a);
75086685b6dSsthen	is($w, 0);
75186685b6dSsthen
75286685b6dSsthen	utf8::upgrade($a);
75386685b6dSsthen    }
75486685b6dSsthen}
75586685b6dSsthen
75686685b6dSsthen# [perl #77692] UTF8 cache not being reset when TARG is reused
75786685b6dSsthenok eval {
75886685b6dSsthen local ${^UTF8CACHE} = -1;
75986685b6dSsthen for my $i (0..1)
76086685b6dSsthen {
76186685b6dSsthen   my $dummy = length(substr("\x{100}",0,$i));
76286685b6dSsthen }
76386685b6dSsthen 1
76486685b6dSsthen}, 'UTF8 cache is reset when TARG is reused [perl #77692]';
76586685b6dSsthen
76686685b6dSsthen{
76786685b6dSsthen    use utf8;
76886685b6dSsthen    use open qw( :utf8 :std );
76986685b6dSsthen    no warnings 'once';
77086685b6dSsthen
77186685b6dSsthen    my $t = "";
77286685b6dSsthen    substr $t, 0, 0, *ワルド;
77386685b6dSsthen    is($t, "*main::ワルド", "substr works on UTF-8 globs");
77486685b6dSsthen
77586685b6dSsthen    $t = "The World!";
77686685b6dSsthen    substr $t, 0, 9, *ザ::ワルド;
77786685b6dSsthen    is($t, "*ザ::ワルド!", "substr works on a UTF-8 glob + stash");
77886685b6dSsthen}
77986685b6dSsthen
78086685b6dSsthen{
78186685b6dSsthen    my $x = *foo;
78286685b6dSsthen    my $y = \substr *foo, 0, 0;
78386685b6dSsthen    is ref \$x, 'GLOB', '\substr does not coerce its glob arg just yet';
78486685b6dSsthen    $x = \"foo";
78586685b6dSsthen    $y = \substr *foo, 0, 0;
78686685b6dSsthen    is ref \$x, 'REF', '\substr does not coerce its ref arg just yet';
78786685b6dSsthen}
78886685b6dSsthen
789e9ce3842Safresh1# Test that UTF8-ness of magic var changing does not confuse substr lvalue
790e9ce3842Safresh1# assignment.
791e9ce3842Safresh1# We use overloading for our magic var, but a typeglob would work, too.
792e9ce3842Safresh1package o {
793e9ce3842Safresh1    use overload '""' => sub { ++our $count; $_[0][0] }
794e9ce3842Safresh1}
795e9ce3842Safresh1my $refee = bless ["\x{100}a"], o::;
796e9ce3842Safresh1my $substr = \substr $refee, -2;	# UTF8 flag still off for $$substr.
797e9ce3842Safresh1$$substr = "b";				# UTF8 flag turns on when setsubstr
798e9ce3842Safresh1is $refee, "b",				# magic stringifies $$substr.
799e9ce3842Safresh1     'substr lvalue assignment when stringification turns on UTF8ness';
800e9ce3842Safresh1
801e9ce3842Safresh1# Test that changing UTF8-ness does not confuse 4-arg substr.
802e9ce3842Safresh1$refee = bless [], "\x{100}a";
803e9ce3842Safresh1# stringify without returning on UTF8 flag on $refee:
804e9ce3842Safresh1my $string = $refee; $string = "$string";
805e9ce3842Safresh1substr $refee, 0, 0, "\xff";
806e9ce3842Safresh1is $refee, "\xff$string",
807e9ce3842Safresh1  '4-arg substr with target UTF8ness turning on when stringified';
808e9ce3842Safresh1$refee = bless [], "\x{100}";
809e9ce3842Safresh1() = "$refee"; # UTF8 flag now on
810e9ce3842Safresh1bless $refee, "\xff";
811e9ce3842Safresh1$string = $refee; $string = "$string";
812e9ce3842Safresh1substr $refee, 0, 0, "\xff";
813e9ce3842Safresh1is $refee, "\xff$string",
814e9ce3842Safresh1  '4-arg substr with target UTF8ness turning off when stringified';
815e9ce3842Safresh1
816e9ce3842Safresh1# Overload count
817e9ce3842Safresh1$refee = bless ["foo"], o::;
818e9ce3842Safresh1$o::count = 0;
819e9ce3842Safresh1substr $refee, 0, 0, "";
820e9ce3842Safresh1is $o::count, 1, '4-arg substr calls overloading once on the target';
821e9ce3842Safresh1$refee = bless ["\x{100}"], o::;
822e9ce3842Safresh1() = "$refee"; # turn UTF8 flag on
823e9ce3842Safresh1$o::count = 0;
824e9ce3842Safresh1() = substr $refee, 0;
825e9ce3842Safresh1is $o::count, 1, 'rvalue substr calls overloading once on utf8 target';
826e9ce3842Safresh1$o::count = 0;
827e9ce3842Safresh1$refee = "";
828e9ce3842Safresh1${\substr $refee, 0} = bless ["\x{100}"], o::;
829e9ce3842Safresh1is $o::count, 1, 'assigning utf8 overload to substr lvalue calls ovld 1ce';
830e9ce3842Safresh1
831e9ce3842Safresh1# [perl #7678] core dump with substr reference and localisation
832e9ce3842Safresh1{$b="abcde"; local $k; *k=\substr($b, 2, 1);}
833e9ce3842Safresh1
834*9f11ffb7Safresh1# [perl #128260] assertion failure with \substr %h, \substr @h
835*9f11ffb7Safresh1{
836*9f11ffb7Safresh1    my %h = 1..100;
837*9f11ffb7Safresh1    my @a = 1..100;
838*9f11ffb7Safresh1    is ${\substr %h, 0}, scalar %h, '\substr %h';
839*9f11ffb7Safresh1    is ${\substr @a, 0}, scalar @a, '\substr @a';
840*9f11ffb7Safresh1}
841*9f11ffb7Safresh1
84286685b6dSsthen} # sub run_tests - put tests above this line that can run in threads
84386685b6dSsthen
84486685b6dSsthen
84586685b6dSsthenmy $destroyed;
84686685b6dSsthen{ package Class; DESTROY { ++$destroyed; } }
84786685b6dSsthen
84886685b6dSsthen$destroyed = 0;
84986685b6dSsthen{
85086685b6dSsthen    my $x = '';
85186685b6dSsthen    substr($x,0,1) = "";
85286685b6dSsthen    $x = bless({}, 'Class');
85386685b6dSsthen}
85486685b6dSsthenis($destroyed, 1, 'Timely scalar destruction with lvalue substr');
85586685b6dSsthen
85686685b6dSsthen{
85786685b6dSsthen    my $result_3363;
85886685b6dSsthen    sub a_3363 {
85986685b6dSsthen        my ($word, $replace) = @_;
86086685b6dSsthen        my $ref = \substr($word, 0, 1);
86186685b6dSsthen        $$ref = $replace;
86286685b6dSsthen        if ($replace eq "b") {
86386685b6dSsthen            $result_3363 = $word;
86486685b6dSsthen        } else {
86586685b6dSsthen            a_3363($word, "b");
86686685b6dSsthen        }
86786685b6dSsthen    }
86886685b6dSsthen    a_3363($_, "v") for "test";
86986685b6dSsthen
87086685b6dSsthen    is($result_3363, "best", "ref-to-substr retains lvalue-ness under recursion [perl #3363]");
87186685b6dSsthen}
872*9f11ffb7Safresh1
873*9f11ffb7Safresh1# failed with ASAN
874*9f11ffb7Safresh1fresh_perl_is('$0 = "/usr/bin/perl"; substr($0, 0, 0, $0)', '', {}, "(perl #129340) substr() with source in target");
875*9f11ffb7Safresh1
876*9f11ffb7Safresh1
877*9f11ffb7Safresh1# [perl #130624] - heap-use-after-free, observable under asan
878*9f11ffb7Safresh1{
879*9f11ffb7Safresh1    my $x = "\xE9zzzz";
880*9f11ffb7Safresh1    my $y = "\x{100}";
881*9f11ffb7Safresh1    my $z = substr $x, 0, 1, $y;
882*9f11ffb7Safresh1    is $z, "\xE9",        "RT#130624: heap-use-after-free in 4-arg substr (ret)";
883*9f11ffb7Safresh1    is $x, "\x{100}zzzz", "RT#130624: heap-use-after-free in 4-arg substr (targ)";
884*9f11ffb7Safresh1}
885*9f11ffb7Safresh1
886*9f11ffb7Safresh1{
887*9f11ffb7Safresh1    our @ta;
888*9f11ffb7Safresh1    $#ta = -1;
889*9f11ffb7Safresh1    substr($#ta, 0, 2) = 23;
890*9f11ffb7Safresh1    is $#ta, 23;
891*9f11ffb7Safresh1    $#ta = -1;
892*9f11ffb7Safresh1    substr($#ta, 0, 2) =~ s/\A..\z/23/s;
893*9f11ffb7Safresh1    is $#ta, 23;
894*9f11ffb7Safresh1    $#ta = -1;
895*9f11ffb7Safresh1    substr($#ta, 0, 2, 23);
896*9f11ffb7Safresh1    is $#ta, 23;
897*9f11ffb7Safresh1    sub ta_tindex :lvalue { $#ta }
898*9f11ffb7Safresh1    $#ta = -1;
899*9f11ffb7Safresh1    ta_tindex() = 23;
900*9f11ffb7Safresh1    is $#ta, 23;
901*9f11ffb7Safresh1    $#ta = -1;
902*9f11ffb7Safresh1    substr(ta_tindex(), 0, 2) = 23;
903*9f11ffb7Safresh1    is $#ta, 23;
904*9f11ffb7Safresh1    $#ta = -1;
905*9f11ffb7Safresh1    substr(ta_tindex(), 0, 2) =~ s/\A..\z/23/s;
906*9f11ffb7Safresh1    is $#ta, 23;
907*9f11ffb7Safresh1    $#ta = -1;
908*9f11ffb7Safresh1    substr(ta_tindex(), 0, 2, 23);
909*9f11ffb7Safresh1    is $#ta, 23;
910*9f11ffb7Safresh1}
911*9f11ffb7Safresh1
912*9f11ffb7Safresh1{ # [perl #132527]
913*9f11ffb7Safresh1    use feature 'refaliasing';
914*9f11ffb7Safresh1    no warnings 'experimental::refaliasing';
915*9f11ffb7Safresh1    my %h;
916*9f11ffb7Safresh1    \$h{foo} = \(my $bar = "baz");
917*9f11ffb7Safresh1    substr delete $h{foo}, 1, 1, o=>;
918*9f11ffb7Safresh1    is $bar, boz => 'first arg to 4-arg substr is loose lvalue context';
919*9f11ffb7Safresh1}
920*9f11ffb7Safresh1
921*9f11ffb7Safresh11;
922