----- Original Message ----- From: "Christoph Otto" <[EMAIL PROTECTED]>
To: <perl6-internals@perl.org>
Sent: Friday, July 25, 2008 10:29 AM
Subject: Re: [perl #57260] [BUG] Segfaults in sprintf opcode


Will Coleda (via RT) wrote:
# New Ticket Created by Will Coleda # Please include the string: [perl #57260] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=57260 >


Tripped over these trying to run some spec tests for Tcl. I have no
idea what $S0 should have after the invocation, but the current
segfaults are undoubtedly incorrect.
>

If someone wants to fix this, the following works as a minimal test case.

.sub kaboom
    $P0 = new 'ResizableIntegerArray'
    push $P0, -1
    push $P0, 1
    $S0 = sprintf "%*c", $P0
.end

According to 'man sprintf', a negative field length is equivalent to a minus option and the absolute length. The following patch has been applied in revision 29735.
Appropriate tests to be added later.

Regards
Peter Gibbs

Index: src/spf_render.c
===================================================================
--- src/spf_render.c    (revision 29734)
+++ src/spf_render.c    (working copy)
@@ -310,6 +310,7 @@
    INTVAL len     = 0;
    INTVAL old     = 0;
    INTVAL pat_len = (INTVAL)string_length(interp, pat);
+    HUGEINTVAL num;

/* start with a buffer; double the pattern length to avoid realloc #1 */ STRING *targ = string_make_empty(interp, enum_stringrep_one, pat_len << 1);
@@ -492,8 +493,14 @@

                        case '*':
                            info.flags |= FLAG_WIDTH;
-                            info.width = (UINTVAL)obj->getint(interp,
-                                                      SIZE_XVAL, obj);
+                            num = obj->getint(interp, SIZE_XVAL, obj);
+                            if (num < 0) {
+                                info.flags |= FLAG_MINUS;
+                                info.width = -num;
+                            }
+                            else {
+                                info.width = num;
+                            }
                            /* fall through */

                        case '.':

Reply via email to