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

Commit630684d

Browse files
committed
Improve documentation of ParseDateTime(). Reorder tests to prevent
writing one more value into return arrays than will fit. This ispotentially a stack smash, though I do not think it is a problem incurrent uses of the routine, since a failure return causes elog anyway.
1 parent9d41073 commit630684d

File tree

2 files changed

+39
-24
lines changed

2 files changed

+39
-24
lines changed

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

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.111 2003/08/0517:39:19 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.112 2003/08/0518:30:21 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -699,30 +699,54 @@ TrimTrailingZeros(char *str)
699699

700700

701701
/* ParseDateTime()
702-
* Break string into tokens based on a date/time context.
702+
*Break string into tokens based on a date/time context.
703+
*Returns 0 if successful, -1 if bogus input detected.
704+
*
705+
* timestr - the input string
706+
* lowstr - workspace for field string storage (must be large enough for
707+
*a copy of the input string, including trailing null)
708+
* field[] - pointers to field strings are returned in this array
709+
* ftype[] - field type indicators are returned in this array
710+
* maxfields - dimensions of the above two arrays
711+
* *numfields - set to the actual number of fields detected
712+
*
713+
* The fields extracted from the input are stored as separate, null-terminated
714+
* strings in the workspace at lowstr. Any text is converted to lower case.
715+
*
703716
* Several field types are assigned:
704717
*DTK_NUMBER - digits and (possibly) a decimal point
705718
*DTK_DATE - digits and two delimiters, or digits and text
706719
*DTK_TIME - digits, colon delimiters, and possibly a decimal point
707720
*DTK_STRING - text (no digits)
708721
*DTK_SPECIAL - leading "+" or "-" followed by text
709722
*DTK_TZ - leading "+" or "-" followed by digits
723+
*
710724
* Note that some field types can hold unexpected items:
711725
*DTK_NUMBER can hold date fields (yy.ddd)
712726
*DTK_STRING can hold months (January) and time zones (PST)
713727
*DTK_DATE can hold Posix time zones (GMT-8)
714728
*/
715729
int
716-
ParseDateTime(char*timestr,char*lowstr,
730+
ParseDateTime(constchar*timestr,char*lowstr,
717731
char**field,int*ftype,intmaxfields,int*numfields)
718732
{
719733
intnf=0;
720-
char*cp=timestr;
734+
constchar*cp=timestr;
721735
char*lp=lowstr;
722736

723737
/* outer loop through fields */
724738
while (*cp!='\0')
725739
{
740+
/* Ignore spaces between fields */
741+
if (isspace((unsignedchar)*cp))
742+
{
743+
cp++;
744+
continue;
745+
}
746+
747+
/* Record start of current field */
748+
if (nf >=maxfields)
749+
return-1;
726750
field[nf]=lp;
727751

728752
/* leading digit? then date or time */
@@ -745,32 +769,32 @@ ParseDateTime(char *timestr, char *lowstr,
745769
elseif ((*cp=='-')|| (*cp=='/')|| (*cp=='.'))
746770
{
747771
/* save delimiting character to use later */
748-
char*dp=cp;
772+
chardelim=*cp;
749773

750774
*lp++=*cp++;
751775
/* second field is all digits? then no embedded text month */
752776
if (isdigit((unsignedchar)*cp))
753777
{
754-
ftype[nf]= ((*dp=='.') ?DTK_NUMBER :DTK_DATE);
778+
ftype[nf]= ((delim=='.') ?DTK_NUMBER :DTK_DATE);
755779
while (isdigit((unsignedchar)*cp))
756780
*lp++=*cp++;
757781

758782
/*
759783
* insist that the delimiters match to get a
760784
* three-field date.
761785
*/
762-
if (*cp==*dp)
786+
if (*cp==delim)
763787
{
764788
ftype[nf]=DTK_DATE;
765789
*lp++=*cp++;
766-
while (isdigit((unsignedchar)*cp)|| (*cp==*dp))
790+
while (isdigit((unsignedchar)*cp)|| (*cp==delim))
767791
*lp++=*cp++;
768792
}
769793
}
770794
else
771795
{
772796
ftype[nf]=DTK_DATE;
773-
while (isalnum((unsignedchar)*cp)|| (*cp==*dp))
797+
while (isalnum((unsignedchar)*cp)|| (*cp==delim))
774798
*lp++=tolower((unsignedchar)*cp++);
775799
}
776800
}
@@ -809,20 +833,14 @@ ParseDateTime(char *timestr, char *lowstr,
809833
*/
810834
if ((*cp=='-')|| (*cp=='/')|| (*cp=='.'))
811835
{
812-
char*dp=cp;
836+
chardelim=*cp;
813837

814838
ftype[nf]=DTK_DATE;
815839
*lp++=*cp++;
816-
while (isdigit((unsignedchar)*cp)|| (*cp==*dp))
840+
while (isdigit((unsignedchar)*cp)|| (*cp==delim))
817841
*lp++=*cp++;
818842
}
819843
}
820-
/* skip leading spaces */
821-
elseif (isspace((unsignedchar)*cp))
822-
{
823-
cp++;
824-
continue;
825-
}
826844
/* sign? then special or numeric timezone */
827845
elseif ((*cp=='+')|| (*cp=='-'))
828846
{
@@ -851,12 +869,11 @@ ParseDateTime(char *timestr, char *lowstr,
851869
else
852870
return-1;
853871
}
854-
/* ignore punctuation but use as delimiter */
872+
/* ignoreotherpunctuation but use as delimiter */
855873
elseif (ispunct((unsignedchar)*cp))
856874
{
857875
cp++;
858876
continue;
859-
860877
}
861878
/* otherwise, something is not right... */
862879
else
@@ -865,14 +882,12 @@ ParseDateTime(char *timestr, char *lowstr,
865882
/* force in a delimiter after each field */
866883
*lp++='\0';
867884
nf++;
868-
if (nf>MAXDATEFIELDS)
869-
return-1;
870885
}
871886

872887
*numfields=nf;
873888

874889
return0;
875-
}/* ParseDateTime() */
890+
}
876891

877892

878893
/* DecodeDateTime()

‎src/include/utils/datetime.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
1010
* Portions Copyright (c) 1994, Regents of the University of California
1111
*
12-
* $Id: datetime.h,v 1.43 2003/08/04 02:40:15 momjian Exp $
12+
* $Id: datetime.h,v 1.44 2003/08/05 18:30:21 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -277,7 +277,7 @@ extern void GetCurrentTimeUsec(struct tm * tm, fsec_t *fsec, int *tzp);
277277
externvoidj2date(intjd,int*year,int*month,int*day);
278278
externintdate2j(intyear,intmonth,intday);
279279

280-
externintParseDateTime(char*timestr,char*lowstr,
280+
externintParseDateTime(constchar*timestr,char*lowstr,
281281
char**field,int*ftype,
282282
intmaxfields,int*numfields);
283283
externintDecodeDateTime(char**field,int*ftype,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp