diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/formatting.c | 136 |
1 files changed, 49 insertions, 87 deletions
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c index d3e3843cfab..13208526297 100644 --- a/src/backend/utils/adt/formatting.c +++ b/src/backend/utils/adt/formatting.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- * formatting.c * - * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.84.4.2 2005/03/26 00:41:45 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.84.4.3 2007/06/29 01:52:04 tgl Exp $ * * * Portions Copyright (c) 1999-2005, PostgreSQL Global Development Group @@ -73,6 +73,7 @@ #include <unistd.h> #include <math.h> #include <float.h> +#include <limits.h> #include "utils/builtins.h" #include "utils/date.h" @@ -107,8 +108,8 @@ * More is in float.c * ---------- */ -#define MAXFLOATWIDTH 64 -#define MAXDOUBLEWIDTH 128 +#define MAXFLOATWIDTH 60 +#define MAXDOUBLEWIDTH 500 /* ---------- * External (defined in PgSQL datetime.c (timestamp utils)) @@ -1471,7 +1472,7 @@ str_numth(char *dest, char *num, int type) } /* ---------- - * Convert string to upper-string. Input string is modified in place. + * Convert string to upper case. Input string is modified in place. * ---------- */ static char * @@ -1491,7 +1492,7 @@ str_toupper(char *buff) } /* ---------- - * Convert string to lower-string. Input string is modified in place. + * Convert string to lower case. Input string is modified in place. * ---------- */ static char * @@ -2019,19 +2020,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data) case DCH_TZ: if (flag == TO_CHAR && tmtcTzn(tmtc)) { - int siz = strlen(tmtcTzn(tmtc)); - if (arg == DCH_TZ) strcpy(inout, tmtcTzn(tmtc)); else { - char *p = palloc(siz); + char *p = pstrdup(tmtcTzn(tmtc)); - strcpy(p, tmtcTzn(tmtc)); strcpy(inout, str_tolower(p)); pfree(p); } - return siz - 1; + return strlen(inout) - 1; } else if (flag == FROM_CHAR) ereport(ERROR, @@ -3292,7 +3290,7 @@ static char * fill_str(char *str, int c, int max) { memset(str, c, max); - *(str + max + 1) = '\0'; + *(str + max) = '\0'; return str; } @@ -4498,10 +4496,9 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number, #define NUM_TOCHAR_prepare \ do { \ len = VARSIZE(fmt) - VARHDRSZ; \ - if (len <= 0) \ + if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ) \ return DirectFunctionCall1(textin, CStringGetDatum("")); \ - result = (text *) palloc( (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \ - memset(result, 0, (len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ ); \ + result = (text *) palloc0((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ); \ format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree); \ } while (0) @@ -4513,28 +4510,18 @@ do { \ do { \ NUM_processor(format, &Num, VARDATA(result), \ numstr, plen, sign, TO_CHAR); \ - pfree(orgnum); \ \ - if (shouldFree) \ - pfree(format); \ + if (shouldFree) \ + pfree(format); \ \ - /* - * for result is allocated max memory, which current format-picture\ - * needs, now it must be re-allocate to result real size \ + /* \ + * Convert null-terminated representation of result to standard text. \ + * The result is usually much bigger than it needs to be, but there \ + * seems little point in realloc'ing it smaller. \ */ \ - if (!(len = strlen(VARDATA(result)))) \ - { \ - pfree(result); \ - PG_RETURN_NULL(); \ - } \ - \ - result_tmp = result; \ - result = (text *) palloc( len + 1 + VARHDRSZ); \ - \ - strcpy( VARDATA(result), VARDATA(result_tmp)); \ - VARATT_SIZEP(result) = len + VARHDRSZ; \ - pfree(result_tmp); \ -} while(0) + len = strlen(VARDATA(result)); \ + VARATT_SIZEP(result) = len + VARHDRSZ; \ +} while (0) /* ------------------- * NUMERIC to_number() (convert string to numeric) @@ -4556,7 +4543,7 @@ numeric_to_number(PG_FUNCTION_ARGS) len = VARSIZE(fmt) - VARHDRSZ; - if (len <= 0) + if (len <= 0 || len >= INT_MAX/NUM_MAX_ITEM_SIZ) PG_RETURN_NULL(); format = NUM_cache(len, &Num, VARDATA(fmt), &shouldFree); @@ -4591,8 +4578,7 @@ numeric_to_char(PG_FUNCTION_ARGS) text *fmt = PG_GETARG_TEXT_P(1); NUMDesc Num; FormatNode *format; - text *result, - *result_tmp; + text *result; bool shouldFree; int len = 0, plen = 0, @@ -4615,7 +4601,6 @@ numeric_to_char(PG_FUNCTION_ARGS) numstr = orgnum = int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4, NumericGetDatum(x)))); - pfree(x); } else { @@ -4634,9 +4619,6 @@ numeric_to_char(PG_FUNCTION_ARGS) val = DatumGetNumeric(DirectFunctionCall2(numeric_mul, NumericGetDatum(value), NumericGetDatum(x))); - pfree(x); - pfree(a); - pfree(b); Num.pre += Num.multi; } @@ -4645,10 +4627,9 @@ numeric_to_char(PG_FUNCTION_ARGS) Int32GetDatum(Num.post))); orgnum = DatumGetCString(DirectFunctionCall1(numeric_out, NumericGetDatum(x))); - pfree(x); if (*orgnum == '-') - { /* < 0 */ + { sign = '-'; numstr = orgnum + 1; } @@ -4667,13 +4648,10 @@ numeric_to_char(PG_FUNCTION_ARGS) else if (len > Num.pre) { - fill_str(numstr, '#', Num.pre); + numstr = (char *) palloc(Num.pre + Num.post + 2); + fill_str(numstr, '#', Num.pre + Num.post + 1); *(numstr + Num.pre) = '.'; - fill_str(numstr + 1 + Num.pre, '#', Num.post); } - - if (IS_MULTI(&Num)) - pfree(val); } NUM_TOCHAR_finish; @@ -4691,8 +4669,7 @@ int4_to_char(PG_FUNCTION_ARGS) text *fmt = PG_GETARG_TEXT_P(1); NUMDesc Num; FormatNode *format; - text *result, - *result_tmp; + text *result; bool shouldFree; int len = 0, plen = 0, @@ -4720,40 +4697,34 @@ int4_to_char(PG_FUNCTION_ARGS) orgnum = DatumGetCString(DirectFunctionCall1(int4out, Int32GetDatum(value))); } - len = strlen(orgnum); if (*orgnum == '-') - { /* < 0 */ + { sign = '-'; - --len; + orgnum++; } else sign = '+'; + len = strlen(orgnum); if (Num.post) { - int i; - numstr = (char *) palloc(len + Num.post + 2); - strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0)); + strcpy(numstr, orgnum); *(numstr + len) = '.'; - - for (i = len + 1; i <= len + Num.post; i++) - *(numstr + i) = '0'; + memset(numstr + len + 1, '0', Num.post); *(numstr + len + Num.post + 1) = '\0'; - pfree(orgnum); - orgnum = numstr; } else - numstr = orgnum + (*orgnum == '-' ? 1 : 0); + numstr = orgnum; if (Num.pre > len) plen = Num.pre - len; else if (len > Num.pre) { - fill_str(numstr, '#', Num.pre); + numstr = (char *) palloc(Num.pre + Num.post + 2); + fill_str(numstr, '#', Num.pre + Num.post + 1); *(numstr + Num.pre) = '.'; - fill_str(numstr + 1 + Num.pre, '#', Num.post); } } @@ -4772,8 +4743,7 @@ int8_to_char(PG_FUNCTION_ARGS) text *fmt = PG_GETARG_TEXT_P(1); NUMDesc Num; FormatNode *format; - text *result, - *result_tmp; + text *result; bool shouldFree; int len = 0, plen = 0, @@ -4807,40 +4777,34 @@ int8_to_char(PG_FUNCTION_ARGS) orgnum = DatumGetCString(DirectFunctionCall1(int8out, Int64GetDatum(value))); - len = strlen(orgnum); if (*orgnum == '-') - { /* < 0 */ + { sign = '-'; - --len; + orgnum++; } else sign = '+'; + len = strlen(orgnum); if (Num.post) { - int i; - numstr = (char *) palloc(len + Num.post + 2); - strcpy(numstr, orgnum + (*orgnum == '-' ? 1 : 0)); + strcpy(numstr, orgnum); *(numstr + len) = '.'; - - for (i = len + 1; i <= len + Num.post; i++) - *(numstr + i) = '0'; + memset(numstr + len + 1, '0', Num.post); *(numstr + len + Num.post + 1) = '\0'; - pfree(orgnum); - orgnum = numstr; } else - numstr = orgnum + (*orgnum == '-' ? 1 : 0); + numstr = orgnum; if (Num.pre > len) plen = Num.pre - len; else if (len > Num.pre) { - fill_str(numstr, '#', Num.pre); + numstr = (char *) palloc(Num.pre + Num.post + 2); + fill_str(numstr, '#', Num.pre + Num.post + 1); *(numstr + Num.pre) = '.'; - fill_str(numstr + 1 + Num.pre, '#', Num.post); } } @@ -4859,8 +4823,7 @@ float4_to_char(PG_FUNCTION_ARGS) text *fmt = PG_GETARG_TEXT_P(1); NUMDesc Num; FormatNode *format; - text *result, - *result_tmp; + text *result; bool shouldFree; int len = 0, plen = 0, @@ -4919,9 +4882,9 @@ float4_to_char(PG_FUNCTION_ARGS) else if (len > Num.pre) { - fill_str(numstr, '#', Num.pre); + numstr = (char *) palloc(Num.pre + Num.post + 2); + fill_str(numstr, '#', Num.pre + Num.post + 1); *(numstr + Num.pre) = '.'; - fill_str(numstr + 1 + Num.pre, '#', Num.post); } } @@ -4940,8 +4903,7 @@ float8_to_char(PG_FUNCTION_ARGS) text *fmt = PG_GETARG_TEXT_P(1); NUMDesc Num; FormatNode *format; - text *result, - *result_tmp; + text *result; bool shouldFree; int len = 0, plen = 0, @@ -4998,9 +4960,9 @@ float8_to_char(PG_FUNCTION_ARGS) else if (len > Num.pre) { - fill_str(numstr, '#', Num.pre); + numstr = (char *) palloc(Num.pre + Num.post + 2); + fill_str(numstr, '#', Num.pre + Num.post + 1); *(numstr + Num.pre) = '.'; - fill_str(numstr + 1 + Num.pre, '#', Num.post); } } |