postgres.git / summary / log / commit / refs

commit    b0134fe84da073f5c8ed4bbfac4a7111c1f7d799
Author:   Peter Eisentraut <peter_e@gmx.net>
Date:     Mon Aug 08 15:12:59 2016 +0000

    Fix several one-byte buffer over-reads in to_number
    
    Several places in NUM_numpart_from_char(), which is called from the SQL
    function to_number(text, text), could accidentally read one byte past
    the end of the input buffer (which comes from the input text datum and
    is not null-terminated).
    
    1. One leading space character would be skipped, but there was no check
       that the input was at least one byte long.  This does not happen in
       practice, but for defensiveness, add a check anyway.
    
    2. Commit 4a3a1e2cf apparently accidentally doubled that code that skips
       one space character (so that two spaces might be skipped), but there
       was no overflow check before skipping the second byte.  Fix by
       removing that duplicate code.
    
    3. A logic error would allow a one-byte over-read when looking for a
       trailing sign (S) placeholder.
    
    In each case, the extra byte cannot be read out directly, but looking at
    it might cause a crash.
    
    The third item was discovered by Piotr Stefaniak, the first two were
    found and analyzed by Tom Lane and Peter Eisentraut.


src/backend/utils/adt/formatting.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index 74b70eff217..f34d0bd5b65 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -4138,12 +4138,12 @@ NUM_numpart_from_char(NUMProc *Np, int id, int input_len) (id == NUM_0 || id == NUM_9) ? "NUM_0/9" : id == NUM_DEC ? "NUM_DEC" : "???"); #endif - if (*Np->inout_p == ' ') - Np->inout_p++; - #define OVERLOAD_TEST (Np->inout_p >= Np->inout + input_len) #define AMOUNT_TEST(_s) (input_len-(Np->inout_p-Np->inout) >= _s) + if (OVERLOAD_TEST) + return; + if (*Np->inout_p == ' ') Np->inout_p++; @@ -4293,7 +4293,7 @@ NUM_numpart_from_char(NUMProc *Np, int id, int input_len) * next char is not digit */ if (IS_LSIGN(Np->Num) && isread && - (Np->inout_p + 1) <= Np->inout + input_len && + (Np->inout_p + 1) < Np->inout + input_len && !isdigit((unsigned char) *(Np->inout_p + 1))) { int x; [parent: e990c738b4f9]