Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit56d2bee

Browse files
committed
to_char(): prevent writing beyond the allocated buffer
Previously very long localized month and weekday strings couldoverflow the allocated buffers, causing a server crash.Reported and patch reviewed by Noah Misch. Backpatch to allsupported versions.Security:CVE-2015-0241
1 parent1628a0b commit56d2bee

File tree

1 file changed

+125
-14
lines changed

1 file changed

+125
-14
lines changed

‎src/backend/utils/adt/formatting.c

Lines changed: 125 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
* Maximal length of one node
111111
* ----------
112112
*/
113-
#defineDCH_MAX_ITEM_SIZ9/* maxjulian day*/
113+
#defineDCH_MAX_ITEM_SIZ 12/* maxlocalized day name*/
114114
#defineNUM_MAX_ITEM_SIZ8/* roman number (RN has 15 chars)*/
115115

116116
/* ----------
@@ -518,10 +518,12 @@ do { \
518518
* Suffixes definition for DATE-TIME TO/FROM CHAR
519519
* ----------
520520
*/
521+
#defineTM_SUFFIX_LEN2
522+
521523
staticconstKeySuffixDCH_suff[]= {
522524
{"FM",2,DCH_S_FM,SUFFTYPE_PREFIX},
523525
{"fm",2,DCH_S_FM,SUFFTYPE_PREFIX},
524-
{"TM",2,DCH_S_TM,SUFFTYPE_PREFIX},
526+
{"TM",TM_SUFFIX_LEN,DCH_S_TM,SUFFTYPE_PREFIX},
525527
{"tm",2,DCH_S_TM,SUFFTYPE_PREFIX},
526528
{"TH",2,DCH_S_TH,SUFFTYPE_POSTFIX},
527529
{"th",2,DCH_S_th,SUFFTYPE_POSTFIX},
@@ -530,6 +532,7 @@ static const KeySuffix DCH_suff[] = {
530532
{NULL,0,0,0}
531533
};
532534

535+
533536
/* ----------
534537
* Format-pictures (KeyWord).
535538
*
@@ -2537,7 +2540,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25372540
if (!tm->tm_mon)
25382541
break;
25392542
if (S_TM(n->suffix))
2540-
strcpy(s,str_toupper_z(localized_full_months[tm->tm_mon-1],collid));
2543+
{
2544+
char*str=str_toupper_z(localized_full_months[tm->tm_mon-1],collid);
2545+
2546+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2547+
strcpy(s,str);
2548+
else
2549+
ereport(ERROR,
2550+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2551+
errmsg("localized string format value too long")));
2552+
}
25412553
else
25422554
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
25432555
asc_toupper_z(months_full[tm->tm_mon-1]));
@@ -2548,7 +2560,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25482560
if (!tm->tm_mon)
25492561
break;
25502562
if (S_TM(n->suffix))
2551-
strcpy(s,str_initcap_z(localized_full_months[tm->tm_mon-1],collid));
2563+
{
2564+
char*str=str_initcap_z(localized_full_months[tm->tm_mon-1],collid);
2565+
2566+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2567+
strcpy(s,str);
2568+
else
2569+
ereport(ERROR,
2570+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2571+
errmsg("localized string format value too long")));
2572+
}
25522573
else
25532574
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
25542575
months_full[tm->tm_mon-1]);
@@ -2559,7 +2580,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25592580
if (!tm->tm_mon)
25602581
break;
25612582
if (S_TM(n->suffix))
2562-
strcpy(s,str_tolower_z(localized_full_months[tm->tm_mon-1],collid));
2583+
{
2584+
char*str=str_tolower_z(localized_full_months[tm->tm_mon-1],collid);
2585+
2586+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2587+
strcpy(s,str);
2588+
else
2589+
ereport(ERROR,
2590+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2591+
errmsg("localized string format value too long")));
2592+
}
25632593
else
25642594
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
25652595
asc_tolower_z(months_full[tm->tm_mon-1]));
@@ -2570,7 +2600,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25702600
if (!tm->tm_mon)
25712601
break;
25722602
if (S_TM(n->suffix))
2573-
strcpy(s,str_toupper_z(localized_abbrev_months[tm->tm_mon-1],collid));
2603+
{
2604+
char*str=str_toupper_z(localized_abbrev_months[tm->tm_mon-1],collid);
2605+
2606+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2607+
strcpy(s,str);
2608+
else
2609+
ereport(ERROR,
2610+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2611+
errmsg("localized string format value too long")));
2612+
}
25742613
else
25752614
strcpy(s,asc_toupper_z(months[tm->tm_mon-1]));
25762615
s+=strlen(s);
@@ -2580,7 +2619,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25802619
if (!tm->tm_mon)
25812620
break;
25822621
if (S_TM(n->suffix))
2583-
strcpy(s,str_initcap_z(localized_abbrev_months[tm->tm_mon-1],collid));
2622+
{
2623+
char*str=str_initcap_z(localized_abbrev_months[tm->tm_mon-1],collid);
2624+
2625+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2626+
strcpy(s,str);
2627+
else
2628+
ereport(ERROR,
2629+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2630+
errmsg("localized string format value too long")));
2631+
}
25842632
else
25852633
strcpy(s,months[tm->tm_mon-1]);
25862634
s+=strlen(s);
@@ -2590,7 +2638,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
25902638
if (!tm->tm_mon)
25912639
break;
25922640
if (S_TM(n->suffix))
2593-
strcpy(s,str_tolower_z(localized_abbrev_months[tm->tm_mon-1],collid));
2641+
{
2642+
char*str=str_tolower_z(localized_abbrev_months[tm->tm_mon-1],collid);
2643+
2644+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2645+
strcpy(s,str);
2646+
else
2647+
ereport(ERROR,
2648+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2649+
errmsg("localized string format value too long")));
2650+
}
25942651
else
25952652
strcpy(s,asc_tolower_z(months[tm->tm_mon-1]));
25962653
s+=strlen(s);
@@ -2604,7 +2661,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
26042661
caseDCH_DAY:
26052662
INVALID_FOR_INTERVAL;
26062663
if (S_TM(n->suffix))
2607-
strcpy(s,str_toupper_z(localized_full_days[tm->tm_wday],collid));
2664+
{
2665+
char*str=str_toupper_z(localized_full_days[tm->tm_wday],collid);
2666+
2667+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2668+
strcpy(s,str);
2669+
else
2670+
ereport(ERROR,
2671+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2672+
errmsg("localized string format value too long")));
2673+
}
26082674
else
26092675
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
26102676
asc_toupper_z(days[tm->tm_wday]));
@@ -2613,7 +2679,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
26132679
caseDCH_Day:
26142680
INVALID_FOR_INTERVAL;
26152681
if (S_TM(n->suffix))
2616-
strcpy(s,str_initcap_z(localized_full_days[tm->tm_wday],collid));
2682+
{
2683+
char*str=str_initcap_z(localized_full_days[tm->tm_wday],collid);
2684+
2685+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2686+
strcpy(s,str);
2687+
else
2688+
ereport(ERROR,
2689+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2690+
errmsg("localized string format value too long")));
2691+
}
26172692
else
26182693
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
26192694
days[tm->tm_wday]);
@@ -2622,7 +2697,16 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
26222697
caseDCH_day:
26232698
INVALID_FOR_INTERVAL;
26242699
if (S_TM(n->suffix))
2625-
strcpy(s,str_tolower_z(localized_full_days[tm->tm_wday],collid));
2700+
{
2701+
char*str=str_tolower_z(localized_full_days[tm->tm_wday],collid);
2702+
2703+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2704+
strcpy(s,str);
2705+
else
2706+
ereport(ERROR,
2707+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2708+
errmsg("localized string format value too long")));
2709+
}
26262710
else
26272711
sprintf(s,"%*s",S_FM(n->suffix) ?0 :-9,
26282712
asc_tolower_z(days[tm->tm_wday]));
@@ -2631,23 +2715,50 @@ DCH_to_char(FormatNode *node, bool is_interval, TmToChar *in, char *out, Oid col
26312715
caseDCH_DY:
26322716
INVALID_FOR_INTERVAL;
26332717
if (S_TM(n->suffix))
2634-
strcpy(s,str_toupper_z(localized_abbrev_days[tm->tm_wday],collid));
2718+
{
2719+
char*str=str_toupper_z(localized_abbrev_days[tm->tm_wday],collid);
2720+
2721+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2722+
strcpy(s,str);
2723+
else
2724+
ereport(ERROR,
2725+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2726+
errmsg("localized string format value too long")));
2727+
}
26352728
else
26362729
strcpy(s,asc_toupper_z(days_short[tm->tm_wday]));
26372730
s+=strlen(s);
26382731
break;
26392732
caseDCH_Dy:
26402733
INVALID_FOR_INTERVAL;
26412734
if (S_TM(n->suffix))
2642-
strcpy(s,str_initcap_z(localized_abbrev_days[tm->tm_wday],collid));
2735+
{
2736+
char*str=str_initcap_z(localized_abbrev_days[tm->tm_wday],collid);
2737+
2738+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2739+
strcpy(s,str);
2740+
else
2741+
ereport(ERROR,
2742+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2743+
errmsg("localized string format value too long")));
2744+
}
26432745
else
26442746
strcpy(s,days_short[tm->tm_wday]);
26452747
s+=strlen(s);
26462748
break;
26472749
caseDCH_dy:
26482750
INVALID_FOR_INTERVAL;
26492751
if (S_TM(n->suffix))
2650-
strcpy(s,str_tolower_z(localized_abbrev_days[tm->tm_wday],collid));
2752+
{
2753+
char*str=str_tolower_z(localized_abbrev_days[tm->tm_wday],collid);
2754+
2755+
if (strlen(str)< (n->key->len+TM_SUFFIX_LEN)*DCH_MAX_ITEM_SIZ)
2756+
strcpy(s,str);
2757+
else
2758+
ereport(ERROR,
2759+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2760+
errmsg("localized string format value too long")));
2761+
}
26512762
else
26522763
strcpy(s,asc_tolower_z(days_short[tm->tm_wday]));
26532764
s+=strlen(s);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp