mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-30 21:01:20 +02:00
Repair problems with to_char() overrunning its input string.
From Karel Zak.
This commit is contained in:
parent
5ac2d7c0eb
commit
5840b89373
@ -1,7 +1,7 @@
|
|||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
* formatting.c
|
* formatting.c
|
||||||
*
|
*
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.67 2003/08/25 16:13:27 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.68 2003/09/03 14:59:41 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1999-2003, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1999-2003, PostgreSQL Global Development Group
|
||||||
@ -1294,6 +1294,16 @@ DCH_processor(FormatNode *node, char *inout, int flag, void *data)
|
|||||||
|
|
||||||
for (n = node, s = inout; n->type != NODE_TYPE_END; n++)
|
for (n = node, s = inout; n->type != NODE_TYPE_END; n++)
|
||||||
{
|
{
|
||||||
|
if (flag == FROM_CHAR && *s=='\0')
|
||||||
|
/*
|
||||||
|
* The input string is shorter than format picture,
|
||||||
|
* so it's good time to break this loop...
|
||||||
|
*
|
||||||
|
* Note: this isn't relevant for TO_CHAR mode, beacuse
|
||||||
|
* it use 'inout' allocated by format picture length.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
|
||||||
if (n->type == NODE_TYPE_ACTION)
|
if (n->type == NODE_TYPE_ACTION)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
@ -1330,7 +1340,6 @@ DCH_processor(FormatNode *node, char *inout, int flag, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
++s; /* ! */
|
++s; /* ! */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flag == TO_CHAR)
|
if (flag == TO_CHAR)
|
||||||
@ -2715,10 +2724,10 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
|||||||
{
|
{
|
||||||
FormatNode *format;
|
FormatNode *format;
|
||||||
struct tm *tm = NULL;
|
struct tm *tm = NULL;
|
||||||
char *str_fmt,
|
char *fmt_str,
|
||||||
*result;
|
*result;
|
||||||
bool incache;
|
bool incache;
|
||||||
int len = VARSIZE(fmt) - VARHDRSZ;
|
int fmt_len = VARSIZE(fmt) - VARHDRSZ;
|
||||||
|
|
||||||
tm = tmtcTm(tmtc);
|
tm = tmtcTm(tmtc);
|
||||||
tm->tm_wday = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1) % 7;
|
tm->tm_wday = (date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + 1) % 7;
|
||||||
@ -2727,29 +2736,28 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
|||||||
/*
|
/*
|
||||||
* Convert fmt to C string
|
* Convert fmt to C string
|
||||||
*/
|
*/
|
||||||
str_fmt = (char *) palloc(len + 1);
|
fmt_str = (char *) palloc(fmt_len + 1);
|
||||||
memcpy(str_fmt, VARDATA(fmt), len);
|
memcpy(fmt_str, VARDATA(fmt), fmt_len);
|
||||||
*(str_fmt + len) = '\0';
|
*(fmt_str + fmt_len) = '\0';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate result
|
* Allocate result
|
||||||
*/
|
*/
|
||||||
result = palloc((len * DCH_MAX_ITEM_SIZ) + 1);
|
result = palloc((fmt_len * DCH_MAX_ITEM_SIZ) + 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate new memory if format picture is bigger than static cache
|
* Allocate new memory if format picture is bigger than static cache
|
||||||
* and not use cache (call parser always) - incache=FALSE show this
|
* and not use cache (call parser always)
|
||||||
* variant
|
|
||||||
*/
|
*/
|
||||||
if (len > DCH_CACHE_SIZE)
|
if (fmt_len > DCH_CACHE_SIZE)
|
||||||
{
|
{
|
||||||
format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode));
|
format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode));
|
||||||
incache = FALSE;
|
incache = FALSE;
|
||||||
|
|
||||||
parse_format(format, str_fmt, DCH_keywords,
|
parse_format(format, fmt_str, DCH_keywords,
|
||||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||||
|
|
||||||
(format + len)->type = NODE_TYPE_END; /* Paranoia? */
|
(format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2758,25 +2766,24 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
|||||||
* Use cache buffers
|
* Use cache buffers
|
||||||
*/
|
*/
|
||||||
DCHCacheEntry *ent;
|
DCHCacheEntry *ent;
|
||||||
|
|
||||||
incache = TRUE;
|
incache = TRUE;
|
||||||
|
|
||||||
if ((ent = DCH_cache_search(str_fmt)) == NULL)
|
if ((ent = DCH_cache_search(fmt_str)) == NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
ent = DCH_cache_getnew(str_fmt);
|
ent = DCH_cache_getnew(fmt_str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not in the cache, must run parser and save a new
|
* Not in the cache, must run parser and save a new
|
||||||
* format-picture to the cache.
|
* format-picture to the cache.
|
||||||
*/
|
*/
|
||||||
parse_format(ent->format, str_fmt, DCH_keywords,
|
parse_format(ent->format, fmt_str, DCH_keywords,
|
||||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||||
|
|
||||||
(ent->format + len)->type = NODE_TYPE_END; /* Paranoia? */
|
(ent->format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||||
|
|
||||||
#ifdef DEBUG_TO_FROM_CHAR
|
#ifdef DEBUG_TO_FROM_CHAR
|
||||||
/* dump_node(ent->format, len); */
|
/* dump_node(ent->format, fmt_len); */
|
||||||
/* dump_index(DCH_keywords, DCH_index); */
|
/* dump_index(DCH_keywords, DCH_index); */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2788,22 +2795,27 @@ datetime_to_char_body(TmToChar *tmtc, text *fmt)
|
|||||||
if (!incache)
|
if (!incache)
|
||||||
pfree(format);
|
pfree(format);
|
||||||
|
|
||||||
pfree(str_fmt);
|
pfree(fmt_str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* for result is allocated max memory, which current format-picture
|
* for result is allocated max memory, which current format-picture
|
||||||
* needs, now it allocate result with real size
|
* needs, now it allocate result with real size
|
||||||
*/
|
*/
|
||||||
if (!(len = strlen(result)))
|
if (result && *result)
|
||||||
pfree(result);
|
{
|
||||||
else
|
int len = strlen(result);
|
||||||
|
|
||||||
|
if (len)
|
||||||
{
|
{
|
||||||
text *res = (text *) palloc(len + 1 + VARHDRSZ);
|
text *res = (text *) palloc(len + 1 + VARHDRSZ);
|
||||||
|
|
||||||
memcpy(VARDATA(res), result, len);
|
memcpy(VARDATA(res), result, len);
|
||||||
VARATT_SIZEP(res) = len + VARHDRSZ;
|
VARATT_SIZEP(res) = len + VARHDRSZ;
|
||||||
|
pfree(result);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
pfree(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2953,39 +2965,39 @@ do_to_timestamp(text *date_txt, text *fmt,
|
|||||||
{
|
{
|
||||||
FormatNode *format;
|
FormatNode *format;
|
||||||
TmFromChar tmfc;
|
TmFromChar tmfc;
|
||||||
bool incache;
|
int fmt_len;
|
||||||
char *str;
|
|
||||||
char *date_str;
|
|
||||||
int len,
|
|
||||||
date_len;
|
|
||||||
|
|
||||||
ZERO_tm(tm);
|
ZERO_tm(tm);
|
||||||
*fsec = 0;
|
*fsec = 0;
|
||||||
|
|
||||||
ZERO_tmfc(&tmfc);
|
ZERO_tmfc(&tmfc);
|
||||||
|
|
||||||
len = VARSIZE(fmt) - VARHDRSZ;
|
fmt_len = VARSIZE(fmt) - VARHDRSZ;
|
||||||
|
|
||||||
if (len)
|
if (fmt_len)
|
||||||
{
|
{
|
||||||
str = (char *) palloc(len + 1);
|
int date_len;
|
||||||
memcpy(str, VARDATA(fmt), len);
|
char *fmt_str;
|
||||||
*(str + len) = '\0';
|
char *date_str;
|
||||||
|
bool incache;
|
||||||
|
|
||||||
|
fmt_str = (char *) palloc(fmt_len + 1);
|
||||||
|
memcpy(fmt_str, VARDATA(fmt), fmt_len);
|
||||||
|
*(fmt_str + fmt_len) = '\0';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate new memory if format picture is bigger than static
|
* Allocate new memory if format picture is bigger than static
|
||||||
* cache and not use cache (call parser always) - incache=FALSE
|
* cache and not use cache (call parser always)
|
||||||
* show this variant
|
|
||||||
*/
|
*/
|
||||||
if (len > DCH_CACHE_SIZE)
|
if (fmt_len > DCH_CACHE_SIZE)
|
||||||
{
|
{
|
||||||
format = (FormatNode *) palloc((len + 1) * sizeof(FormatNode));
|
format = (FormatNode *) palloc((fmt_len + 1) * sizeof(FormatNode));
|
||||||
incache = FALSE;
|
incache = FALSE;
|
||||||
|
|
||||||
parse_format(format, str, DCH_keywords,
|
parse_format(format, fmt_str, DCH_keywords,
|
||||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||||
|
|
||||||
(format + len)->type = NODE_TYPE_END; /* Paranoia? */
|
(format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2993,24 +3005,23 @@ do_to_timestamp(text *date_txt, text *fmt,
|
|||||||
* Use cache buffers
|
* Use cache buffers
|
||||||
*/
|
*/
|
||||||
DCHCacheEntry *ent;
|
DCHCacheEntry *ent;
|
||||||
|
incache = TRUE;
|
||||||
|
|
||||||
incache = 0;
|
if ((ent = DCH_cache_search(fmt_str)) == NULL)
|
||||||
|
|
||||||
if ((ent = DCH_cache_search(str)) == NULL)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
ent = DCH_cache_getnew(str);
|
ent = DCH_cache_getnew(fmt_str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Not in the cache, must run parser and save a new
|
* Not in the cache, must run parser and save a new
|
||||||
* format-picture to the cache.
|
* format-picture to the cache.
|
||||||
*/
|
*/
|
||||||
parse_format(ent->format, str, DCH_keywords,
|
parse_format(ent->format, fmt_str, DCH_keywords,
|
||||||
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
DCH_suff, DCH_index, DCH_TYPE, NULL);
|
||||||
|
|
||||||
(ent->format + len)->type = NODE_TYPE_END; /* Paranoia? */
|
(ent->format + fmt_len)->type = NODE_TYPE_END; /* Paranoia? */
|
||||||
#ifdef DEBUG_TO_FROM_CHAR
|
#ifdef DEBUG_TO_FROM_CHAR
|
||||||
/* dump_node(ent->format, len); */
|
/* dump_node(ent->format, fmt_len); */
|
||||||
/* dump_index(DCH_keywords, DCH_index); */
|
/* dump_index(DCH_keywords, DCH_index); */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -3021,7 +3032,7 @@ do_to_timestamp(text *date_txt, text *fmt,
|
|||||||
* Call action for each node in FormatNode tree
|
* Call action for each node in FormatNode tree
|
||||||
*/
|
*/
|
||||||
#ifdef DEBUG_TO_FROM_CHAR
|
#ifdef DEBUG_TO_FROM_CHAR
|
||||||
/* dump_node(format, len); */
|
/* dump_node(format, fmt_len); */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3035,8 +3046,8 @@ do_to_timestamp(text *date_txt, text *fmt,
|
|||||||
DCH_processor(format, date_str, FROM_CHAR, (void *) &tmfc);
|
DCH_processor(format, date_str, FROM_CHAR, (void *) &tmfc);
|
||||||
|
|
||||||
pfree(date_str);
|
pfree(date_str);
|
||||||
pfree(str);
|
pfree(fmt_str);
|
||||||
if (incache)
|
if (!incache)
|
||||||
pfree(format);
|
pfree(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user