perl-unicode

[Encode] Memory Allocator bug in Encode.xs found and fixed

2002-04-09 11:29:52
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);

<Prev in Thread] Current Thread [Next in Thread>
  • [Encode] Memory Allocator bug in Encode.xs found and fixed, Dan Kogai <=