Change 29946 by [EMAIL PROTECTED] on 2007/01/24 13:23:35
Integrate:
[ 27744]
Subject: [PATCH] sv.c, rs.t, perlvar.pod (Coverity finding: did you
know what happens with $/=\0?)
From: [EMAIL PROTECTED] (Jarkko Hietaniemi)
Message-Id: <[EMAIL PROTECTED]>
Date: Sat, 8 Apr 2006 18:25:33 +0300 (EEST)
(although I should add that this version of Coverity is actually
raising a false positive here, albeit something still interesting)
[ 27788]
Subject: [PATCH] regexec.c: (Coverity) move NULL check even earlier
From: Jarkko Hietaniemi <[EMAIL PROTECTED]>
Message-Id: <[EMAIL PROTECTED]>
Date: Thu, 13 Apr 2006 15:39:33 +0300 (EEST)
[ 27789]
Subject: [PATCH] regexec.c: (Coverity) add NULL check
From: Jarkko Hietaniemi <[EMAIL PROTECTED]>
Message-Id: <[EMAIL PROTECTED]>
Date: Thu, 13 Apr 2006 15:52:15 +0300 (EEST)
[ 27791]
Add another NULL check thanks to Coverity.
Affected files ...
... //depot/maint-5.8/perl/pod/perlvar.pod#42 integrate
... //depot/maint-5.8/perl/regexec.c#70 integrate
... //depot/maint-5.8/perl/sv.c#306 integrate
... //depot/maint-5.8/perl/t/base/rs.t#2 integrate
Differences ...
==== //depot/maint-5.8/perl/pod/perlvar.pod#42 (text) ====
Index: perl/pod/perlvar.pod
--- perl/pod/perlvar.pod#41~28121~ 2006-05-08 08:53:23.000000000 -0700
+++ perl/pod/perlvar.pod 2007-01-24 05:23:35.000000000 -0800
@@ -387,7 +387,8 @@
not reading from a record-oriented file (or your OS doesn't have
record-oriented files), then you'll likely get a full chunk of data
with every read. If a record is larger than the record size you've
-set, you'll get the record back in pieces.
+set, you'll get the record back in pieces. Trying to set the record
+size to zero or less will cause reading in the (rest of the) whole file.
On VMS, record reads are done with the equivalent of C<sysread>,
so it's best not to mix record and non-record reads on the same
==== //depot/maint-5.8/perl/regexec.c#70 (text) ====
Index: perl/regexec.c
--- perl/regexec.c#69~29925~ 2007-01-22 14:10:59.000000000 -0800
+++ perl/regexec.c 2007-01-24 05:23:35.000000000 -0800
@@ -1619,10 +1619,10 @@
char *scream_olds = NULL;
SV* oreplsv = GvSV(PL_replgv);
const bool do_utf8 = DO_UTF8(sv);
- const I32 multiline = PL_multiline | (prog->reganch & PMf_MULTILINE);
+ I32 multiline;
#ifdef DEBUGGING
- SV * const dsv0 = PERL_DEBUG_PAD_ZERO(0);
- SV * const dsv1 = PERL_DEBUG_PAD_ZERO(1);
+ SV* dsv0;
+ SV* dsv1;
#endif
PERL_UNUSED_ARG(data);
RX_MATCH_UTF8_set(prog,do_utf8);
@@ -1640,6 +1640,13 @@
return 0;
}
+ multiline = PL_multiline | (prog->reganch & PMf_MULTILINE);
+
+#ifdef DEBUGGING
+ dsv0 = PERL_DEBUG_PAD_ZERO(0);
+ dsv1 = PERL_DEBUG_PAD_ZERO(1);
+#endif
+
minlen = prog->minlen;
if (strend - startpos < minlen) {
DEBUG_r(PerlIO_printf(Perl_debug_log,
@@ -3122,7 +3129,7 @@
/* No need to save/restore up to this paren */
I32 parenfloor = scan->flags;
- if (OP(PREVOPER(next)) == NOTHING) /* LONGJMP */
+ if (next && (OP(PREVOPER(next)) == NOTHING)) /* LONGJMP */
next += ARG(next);
cc.oldcc = PL_regcc;
PL_regcc = &cc;
@@ -3357,7 +3364,7 @@
do_branch:
{
c1 = OP(scan);
- if (OP(next) != c1) /* No choice. */
+ if (!next || OP(next) != c1) /* No choice. */
next = inner; /* Avoid recursion. */
else {
const I32 lastparen = *PL_reglastparen;
==== //depot/maint-5.8/perl/sv.c#306 (text) ====
Index: perl/sv.c
--- perl/sv.c#305~29944~ 2007-01-24 04:25:33.000000000 -0800
+++ perl/sv.c 2007-01-24 05:23:35.000000000 -0800
@@ -5650,7 +5650,6 @@
register I32 cnt;
I32 i = 0;
I32 rspara = 0;
- I32 recsize;
if (SvTHINKFIRST(sv))
sv_force_normal_flags(sv, append ? 0 : SV_COW_DROP_PV);
@@ -5690,10 +5689,10 @@
rslen = 1;
}
else if (RsSNARF(PL_rs)) {
- /* If it is a regular disk file use size from stat() as estimate
- of amount we are going to read - may result in malloc-ing
- more memory than we realy need if layers bellow reduce
- size we read (e.g. CRLF or a gzip layer)
+ /* If it is a regular disk file use size from stat() as estimate
+ of amount we are going to read -- may result in mallocing
+ more memory than we really need if the layers below reduce
+ the size we read (e.g. CRLF or a gzip layer).
*/
Stat_t st;
if (!PerlLIO_fstat(PerlIO_fileno(fp), &st) && S_ISREG(st.st_mode)) {
@@ -5708,9 +5707,10 @@
else if (RsRECORD(PL_rs)) {
I32 bytesread;
char *buffer;
+ U32 recsize;
/* Grab the size of the record we're getting */
- recsize = SvIV(SvRV(PL_rs));
+ recsize = SvUV(SvRV(PL_rs)); /* RsRECORD() guarantees > 0. */
buffer = SvGROW(sv, (STRLEN)(recsize + append + 1)) + append;
/* Go yank in */
#ifdef VMS
==== //depot/maint-5.8/perl/t/base/rs.t#2 (xtext) ====
Index: perl/t/base/rs.t
--- perl/t/base/rs.t#1~17645~ 2002-07-19 12:29:57.000000000 -0700
+++ perl/t/base/rs.t 2007-01-24 05:23:35.000000000 -0800
@@ -1,7 +1,7 @@
#!./perl
# Test $!
-print "1..16\n";
+print "1..17\n";
$teststring = "1\n12\n123\n1234\n1234\n12345\n\n123456\n1234567\n";
@@ -86,6 +86,11 @@
$bar = <TESTFILE>;
if ($bar eq "78") {print "ok 10\n";} else {print "not ok 10\n";}
+# Naughty straight number - should get the rest of the file
+$/ = \0;
+$bar = <TESTFILE>;
+if ($bar eq "90123456789012345678901234567890") {print "ok 11\n";} else {print
"not ok 11\n";}
+
close TESTFILE;
# Now for the tricky bit--full record reading
@@ -110,23 +115,23 @@
open TESTFILE, "<./foo.bar";
$/ = \10;
$bar = <TESTFILE>;
- if ($bar eq "foo\n") {print "ok 11\n";} else {print "not ok 11\n";}
+ if ($bar eq "foo\n") {print "ok 12\n";} else {print "not ok 12\n";}
$bar = <TESTFILE>;
- if ($bar eq "foobar\n") {print "ok 12\n";} else {print "not ok 12\n";}
+ if ($bar eq "foobar\n") {print "ok 13\n";} else {print "not ok 13\n";}
# can we do a short read?
$/ = \2;
$bar = <TESTFILE>;
- if ($bar eq "ba") {print "ok 13\n";} else {print "not ok 13\n";}
+ if ($bar eq "ba") {print "ok 14\n";} else {print "not ok 14\n";}
# do we get the rest of the record?
$bar = <TESTFILE>;
- if ($bar eq "z\n") {print "ok 14\n";} else {print "not ok 14\n";}
+ if ($bar eq "z\n") {print "ok 15\n";} else {print "not ok 15\n";}
close TESTFILE;
1 while unlink qw(foo.bar foo.com foo.fdl);
} else {
# Nobody else does this at the moment (well, maybe OS/390, but they can
# put their own tests in) so we just punt
- foreach $test (11..14) {print "ok $test # skipped on non-VMS system\n"};
+ foreach $test (12..15) {print "ok $test # skipped on non-VMS system\n"};
}
$/ = "\n";
@@ -142,7 +147,7 @@
else {
print "not ";
}
- print "ok 15\n";
+ print "ok 16\n";
}
{
@@ -155,7 +160,7 @@
else {
print "not ";
}
- print "ok 16\n";
+ print "ok 17\n";
}
# Get rid of the temp file
End of Patch.