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

Commit2cdec8b

Browse files
committed
Fix core dump due to null-pointer dereference in to_char() when datetime
format codes are misapplied to a numeric argument. (The code still producesa pretty bogus error message in such cases, but I'll settle for stopping thecrash for now.) Per bug #4700 from Sergey Burladyan.Problem exists in all supported branches, so patch all the way back.In HEAD, also clean up some ugly coding in the nearby cache managementcode.
1 parente04810e commit2cdec8b

File tree

1 file changed

+24
-35
lines changed

1 file changed

+24
-35
lines changed

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

Lines changed: 24 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.154 2009/02/07 14:16:45 momjian Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/formatting.c,v 1.155 2009/03/12 00:53:25 tgl Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2009, PostgreSQL Global Development Group
@@ -392,12 +392,10 @@ static intDCHCounter = 0;
392392

393393
/* global cache for --- number part */
394394
staticNUMCacheEntryNUMCache[NUM_CACHE_FIELDS+1];
395-
staticNUMCacheEntry*last_NUMCacheEntry;
396395

397396
staticintn_NUMCache=0;/* number of entries */
398397
staticintNUMCounter=0;
399-
400-
#defineMAX_INT32(2147483600)
398+
staticNUMCacheEntry*last_NUMCacheEntry=NUMCache+0;
401399

402400
/* ----------
403401
* For char->date/time conversion
@@ -2765,10 +2763,10 @@ DCH_from_char(FormatNode *node, char *in, TmFromChar *out)
27652763
staticDCHCacheEntry*
27662764
DCH_cache_getnew(char*str)
27672765
{
2768-
DCHCacheEntry*ent=NULL;
2766+
DCHCacheEntry*ent;
27692767

2770-
/* counteroverload check - paranoia? */
2771-
if (DCHCounter+DCH_CACHE_FIELDS>=MAX_INT32)
2768+
/* counteroverflow check - paranoia? */
2769+
if (DCHCounter>= (INT_MAX-DCH_CACHE_FIELDS-1))
27722770
{
27732771
DCHCounter=0;
27742772

@@ -2777,7 +2775,7 @@ DCH_cache_getnew(char *str)
27772775
}
27782776

27792777
/*
2780-
*Cacheis full - needsremoveany older entry
2778+
*If cacheis full,removeoldest entry
27812779
*/
27822780
if (n_DCHCache>DCH_CACHE_FIELDS)
27832781
{
@@ -2786,7 +2784,7 @@ DCH_cache_getnew(char *str)
27862784
#ifdefDEBUG_TO_FROM_CHAR
27872785
elog(DEBUG_elog_output,"cache is full (%d)",n_DCHCache);
27882786
#endif
2789-
for (ent=DCHCache;ent <= (DCHCache+DCH_CACHE_FIELDS);ent++)
2787+
for (ent=DCHCache+1;ent <= (DCHCache+DCH_CACHE_FIELDS);ent++)
27902788
{
27912789
if (ent->age<old->age)
27922790
old=ent;
@@ -2811,35 +2809,30 @@ DCH_cache_getnew(char *str)
28112809
++n_DCHCache;
28122810
returnent;
28132811
}
2814-
2815-
returnNULL;/* never */
28162812
}
28172813

28182814
staticDCHCacheEntry*
28192815
DCH_cache_search(char*str)
28202816
{
2821-
inti=0;
2817+
inti;
28222818
DCHCacheEntry*ent;
28232819

2824-
/* counteroverload check - paranoia? */
2825-
if (DCHCounter+DCH_CACHE_FIELDS>=MAX_INT32)
2820+
/* counteroverflow check - paranoia? */
2821+
if (DCHCounter>= (INT_MAX-DCH_CACHE_FIELDS-1))
28262822
{
28272823
DCHCounter=0;
28282824

28292825
for (ent=DCHCache;ent <= (DCHCache+DCH_CACHE_FIELDS);ent++)
28302826
ent->age= (++DCHCounter);
28312827
}
28322828

2833-
for (ent=DCHCache;ent<= (DCHCache+DCH_CACHE_FIELDS);ent++)
2829+
for (i=0,ent=DCHCache;i<n_DCHCache;i++,ent++)
28342830
{
2835-
if (i==n_DCHCache)
2836-
break;
28372831
if (strcmp(ent->str,str)==0)
28382832
{
28392833
ent->age= (++DCHCounter);
28402834
returnent;
28412835
}
2842-
i++;
28432836
}
28442837

28452838
returnNULL;
@@ -3371,10 +3364,10 @@ do { \
33713364
staticNUMCacheEntry*
33723365
NUM_cache_getnew(char*str)
33733366
{
3374-
NUMCacheEntry*ent=NULL;
3367+
NUMCacheEntry*ent;
33753368

3376-
/* counteroverload check - paranoia? */
3377-
if (NUMCounter+NUM_CACHE_FIELDS>=MAX_INT32)
3369+
/* counteroverflow check - paranoia? */
3370+
if (NUMCounter>= (INT_MAX-NUM_CACHE_FIELDS-1))
33783371
{
33793372
NUMCounter=0;
33803373

@@ -3383,7 +3376,7 @@ NUM_cache_getnew(char *str)
33833376
}
33843377

33853378
/*
3386-
*Cacheis full - needsremoveany older entry
3379+
*If cacheis full,removeoldest entry
33873380
*/
33883381
if (n_NUMCache>NUM_CACHE_FIELDS)
33893382
{
@@ -3392,13 +3385,13 @@ NUM_cache_getnew(char *str)
33923385
#ifdefDEBUG_TO_FROM_CHAR
33933386
elog(DEBUG_elog_output,"Cache is full (%d)",n_NUMCache);
33943387
#endif
3395-
33963388
for (ent=NUMCache;ent <= (NUMCache+NUM_CACHE_FIELDS);ent++)
33973389
{
33983390
/*
3399-
* entry removed via NUM_cache_remove() can be used here
3391+
* entry removed via NUM_cache_remove() can be used here,
3392+
* which is why it's worth scanning first entry again
34003393
*/
3401-
if (*ent->str=='\0')
3394+
if (ent->str[0]=='\0')
34023395
{
34033396
old=ent;
34043397
break;
@@ -3412,7 +3405,6 @@ NUM_cache_getnew(char *str)
34123405
StrNCpy(old->str,str,NUM_CACHE_SIZE+1);
34133406
/* old->format fill parser */
34143407
old->age= (++NUMCounter);
3415-
34163408
ent=old;
34173409
}
34183410
else
@@ -3430,35 +3422,32 @@ NUM_cache_getnew(char *str)
34303422
zeroize_NUM(&ent->Num);
34313423

34323424
last_NUMCacheEntry=ent;
3433-
returnent;/* never */
3425+
returnent;
34343426
}
34353427

34363428
staticNUMCacheEntry*
34373429
NUM_cache_search(char*str)
34383430
{
3439-
inti=0;
3431+
inti;
34403432
NUMCacheEntry*ent;
34413433

3442-
/* counteroverload check - paranoia? */
3443-
if (NUMCounter+NUM_CACHE_FIELDS>=MAX_INT32)
3434+
/* counteroverflow check - paranoia? */
3435+
if (NUMCounter>= (INT_MAX-NUM_CACHE_FIELDS-1))
34443436
{
34453437
NUMCounter=0;
34463438

34473439
for (ent=NUMCache;ent <= (NUMCache+NUM_CACHE_FIELDS);ent++)
34483440
ent->age= (++NUMCounter);
34493441
}
34503442

3451-
for (ent=NUMCache;ent<= (NUMCache+NUM_CACHE_FIELDS);ent++)
3443+
for (i=0,ent=NUMCache;i<n_NUMCache;i++,ent++)
34523444
{
3453-
if (i==n_NUMCache)
3454-
break;
34553445
if (strcmp(ent->str,str)==0)
34563446
{
34573447
ent->age= (++NUMCounter);
34583448
last_NUMCacheEntry=ent;
34593449
returnent;
34603450
}
3461-
i++;
34623451
}
34633452

34643453
returnNULL;
@@ -3470,7 +3459,7 @@ NUM_cache_remove(NUMCacheEntry *ent)
34703459
#ifdefDEBUG_TO_FROM_CHAR
34713460
elog(DEBUG_elog_output,"REMOVING ENTRY (%s)",ent->str);
34723461
#endif
3473-
*ent->str='\0';
3462+
ent->str[0]='\0';
34743463
ent->age=0;
34753464
}
34763465

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp