Porters,
I have found a bug in Encode.xs that may cause "Out of Memory!" error
in certain rare conditions. That is, when the memory allocator routine
is called with no string processed, it asks perl for bogus (and random)
amount of memory via SvGROW.
I found this by accident when I was checking with ucmlint, a new
script to be added under bin/ to check the integrity of ucm files.
> perl5.7.3 -Mblib bin/ucmlint -e ucm/8859-10.ucm
[snip]
SvLEN(dst)=3, SvCUR(dst)=2. 1 bytes unused(33.333333 %)
code=1 @ s=0/0/1 d=0/0/2
more=671968054, sdone=0, sleft=1, SvLEN(dst)=3
Out of memory!
It was a simple bug and my profiler has found it really quickly. All
we have to do is initialize the value of "more" to 0 upon declaration.
Before the fix
> perl5.7.3 bin/ucmlint -e ucm/8859-10.ucm
Out of memory!
After the fix
> perl5.7.3 -Mblib bin/ucmlint -e ucm/8859-10.ucm
ucm/8859-10.ucm: no error found
Please apply the patch below ASAP. I will release 1.32 soon after I
check with Andy's incident report.
Dan the Encode Maintainer
--- Encode.xs 2002/04/04 19:50:52 1.20
+++ Encode.xs 2002/04/09 18:22:47
@@ -6,7 +6,7 @@
#include "encode.h"
#include "def_t.h"
-#define ENCODE_XS_PROFILE 0 /* set 1 to profile.
+#define ENCODE_XS_PROFILE 0 /* set 1 or more to profile.
t/encoding.t dumps core because of
Perl_warner and PerlIO don't work well */
@@ -520,11 +520,17 @@
switch (code) {
case ENCODE_NOSPACE:
{
- STRLEN more, sleft;
+ STRLEN more = 0; /* make sure you initialize! */
+ STRLEN sleft;
sdone += slen;
ddone += dlen;
sleft = tlen - sdone;
- if (sdone) { /* has src ever been processed ? */
+#if ENCODE_XS_PROFILE >= 2
+ Perl_warn(aTHX_
+ "more=%d, sdone=%d, sleft=%d, SvLEN(dst)=%d\n",
+ more, sdone, sleft, SvLEN(dst));
+#endif
+ if (sdone != 0) { /* has src ever been processed ? */
#if ENCODE_XS_USEFP == 2
more = (1.0*tlen*SvLEN(dst)+sdone-1)/sdone
- SvLEN(dst);