aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2016-08-08 11:12:59 -0400
committerPeter Eisentraut <peter_e@gmx.net>2016-08-08 11:13:51 -0400
commitd555d26429568e1a95f75c1a751933ebb63b82c6 (patch)
tree6165ea79e9b47a394b407d7308238b983d3d060b
parent5b1da944c3026bb253f0700a758b5db3db06a223 (diff)
downloadpostgresql-d555d26429568e1a95f75c1a751933ebb63b82c6.tar.gz
postgresql-d555d26429568e1a95f75c1a751933ebb63b82c6.zip
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.
-rw-r--r--src/backend/utils/adt/formatting.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 06a3e5fb237..54368246110 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -4119,12 +4119,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++;
@@ -4274,7 +4274,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;