From: Nicholas Clark <nick@ccl4.org>
Date: Sun, 1 Nov 2009 20:47:47 +0000 (+0000)
Subject: S_utf16_textfilter() was not returning EOF correctly in some situations.
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=d2d1d4de13bedc11af82b2ca4fd580671530195c;p=p5sagit%2Fp5-mst-13.2.git

S_utf16_textfilter() was not returning EOF correctly in some situations.
---

diff --git a/t/comp/utf.t b/t/comp/utf.t
index d59ba2d..1e0e68a 100644
--- a/t/comp/utf.t
+++ b/t/comp/utf.t
@@ -1,6 +1,6 @@
 #!./perl -w
 
-print "1..3980\n";
+print "1..4016\n";
 my $test = 0;
 
 my %templates = (
@@ -54,6 +54,9 @@ for my $bom (0, 1) {
 	for my $nl (1, 0) {
 	    for my $value (123, 1234, 12345) {
 		test($enc, $value, $value, $bom, $nl, $value);
+		# This has the unfortunate side effect of causing an infinite
+		# loop without the bug fix it corresponds to:
+		test($enc, "($value)", $value, $bom, $nl, "($value)");
 	    }
 	    next if $enc eq 'utf8';
 	    # Arguably a bug that currently string literals from UTF-8 file
diff --git a/toke.c b/toke.c
index 61ac8ae..bd20434 100644
--- a/toke.c
+++ b/toke.c
@@ -12791,6 +12791,7 @@ S_utf16_textfilter(pTHX_ int idx, SV *sv, int maxlen)
     SV *const utf8_buffer = filter;
     IV status = IoPAGE(filter);
     const bool reverse = IoLINES(filter);
+    I32 retval;
 
     /* As we're automatically added, at the lowest level, and hence only called
        from this file, we can be sure that we're not called in block mode. Hence
@@ -12823,7 +12824,10 @@ S_utf16_textfilter(pTHX_ int idx, SV *sv, int maxlen)
 	    nl = SvEND(utf8_buffer);
 	}
 	if (nl) {
-	    sv_catpvn(sv, SvPVX(utf8_buffer), nl - SvPVX(utf8_buffer));
+	    STRLEN got = nl - SvPVX(utf8_buffer);
+	    /* Did we have anything to append?  */
+	    retval = got != 0;
+	    sv_catpvn(sv, SvPVX(utf8_buffer), got);
 	    /* Everything else in this code works just fine if SVp_POK isn't
 	       set.  This, however, needs it, and we need it to work, else
 	       we loop infinitely because the buffer is never consumed.  */
@@ -12894,7 +12898,7 @@ S_utf16_textfilter(pTHX_ int idx, SV *sv, int maxlen)
 			  status,
 			  (UV)SvCUR(utf16_buffer), (UV)SvCUR(utf8_buffer)));
     DEBUG_P({ sv_dump(utf8_buffer); sv_dump(sv);});
-    return SvCUR(sv);
+    return retval;
 }
 
 static U8 *