On Fri, Jul 25, 2008 at 7:40 AM, Peter Gibbs <[EMAIL PROTECTED]> wrote:
>
> ----- 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 '.':
>
>

Not only that does that avoid the segfault, the tcl spec test
equivalent to the first test passes. Woot.

The second is still failing, but probably due to unicode issues - but
it's now just failing, not segfaulting.

Once we get a core parrot test for this, we can close out the ticket. Thanks!


-- 
Will "Coke" Coleda

Reply via email to