47
47
#include "catfunc.h"
48
48
#include "pgapifunc.h"
49
49
50
+ #include "secure_sscanf.h"
51
+
50
52
CSTR NAN_STRING = "NaN" ;
51
53
CSTR INFINITY_STRING = "Infinity" ;
52
54
CSTR MINFINITY_STRING = "-Infinity" ;
@@ -255,14 +257,16 @@ static SQLLEN pg_bin2whex(const char *src, SQLWCHAR *dst, SQLLEN length);
255
257
#else
256
258
static ODBCINT64 ATOI64 (const char * val )
257
259
{
260
+ int status ;
258
261
ODBCINT64 ll ;
259
- sscanf (val , "%lld" , & ll );
262
+ secure_sscanf (val , & status , "%lld" , ARG_LLONG ( & ll ) );
260
263
return ll ;
261
264
}
262
265
static unsigned ODBCINT64 ATOI64U (const char * val )
263
266
{
267
+ int status ;
264
268
unsigned ODBCINT64 ll ;
265
- sscanf (val , "%llu" , & ll );
269
+ secure_sscanf (val , & status , "%llu" , ARG_ULLONG ( & ll ) );
266
270
return ll ;
267
271
}
268
272
#endif /* HAVE_STRTOLL */
@@ -283,6 +287,7 @@ timestamp2stime(const char *str, SIMPLE_TIME *st, BOOL *bZone, int *zone)
283
287
char rest [64 ], bc [16 ],
284
288
* ptr ;
285
289
int scnt ,
290
+ status ,
286
291
i ;
287
292
int y , m , d , hh , mm , ss ;
288
293
#ifdef TIMEZONE_GLOBAL
@@ -296,7 +301,10 @@ timestamp2stime(const char *str, SIMPLE_TIME *st, BOOL *bZone, int *zone)
296
301
st -> infinity = 0 ;
297
302
rest [0 ] = '\0' ;
298
303
bc [0 ] = '\0' ;
299
- if ((scnt = sscanf (str , "%4d-%2d-%2d %2d:%2d:%2d%31s %15s" , & y , & m , & d , & hh , & mm , & ss , rest , bc )) < 6 )
304
+ if ((scnt = secure_sscanf (str , & status , "%4d-%2d-%2d %2d:%2d:%2d%31s %15s" ,
305
+ ARG_INT (& y ), ARG_INT (& m ), ARG_INT (& d ),
306
+ ARG_INT (& hh ), ARG_INT (& mm ), ARG_INT (& ss ),
307
+ ARG_STR (& rest , sizeof (rest )), ARG_STR (& bc , sizeof (bc )))) < 6 )
300
308
{
301
309
if (scnt == 3 ) /* date */
302
310
{
@@ -308,7 +316,9 @@ timestamp2stime(const char *str, SIMPLE_TIME *st, BOOL *bZone, int *zone)
308
316
st -> ss = 0 ;
309
317
return TRUE;
310
318
}
311
- if ((scnt = sscanf (str , "%2d:%2d:%2d%31s %15s" , & hh , & mm , & ss , rest , bc )) < 3 )
319
+ if ((scnt = secure_sscanf (str , & status , "%2d:%2d:%2d%31s %15s" ,
320
+ ARG_INT (& hh ), ARG_INT (& mm ), ARG_INT (& ss ),
321
+ ARG_STR (& rest , sizeof (rest )), ARG_STR (& bc , sizeof (bc )))) < 3 )
312
322
return FALSE;
313
323
else
314
324
{
@@ -573,9 +583,11 @@ interval2istruct(SQLSMALLINT ctype, int precision, const char *str, SQL_INTERVAL
573
583
int scnt , years , mons , days , hours , minutes , seconds ;
574
584
BOOL sign ;
575
585
SQLINTERVAL itype = interval2itype (ctype );
586
+ int status = 0 ;
576
587
577
588
pg_memset (st , 0 , sizeof (SQL_INTERVAL_STRUCT ));
578
- if ((scnt = sscanf (str , "%d-%d" , & years , & mons )) >=2 )
589
+ if ((scnt = secure_sscanf (str , & status , "%d-%d" ,
590
+ ARG_INT (& years ), ARG_INT (& mons ))) >=2 )
579
591
{
580
592
if (SQL_IS_YEAR_TO_MONTH == itype )
581
593
{
@@ -588,7 +600,11 @@ interval2istruct(SQLSMALLINT ctype, int precision, const char *str, SQL_INTERVAL
588
600
}
589
601
return FALSE;
590
602
}
591
- else if (scnt = sscanf (str , "%d %02d:%02d:%02d.%09s" , & days , & hours , & minutes , & seconds , lit2 ), 5 == scnt || 4 == scnt )
603
+ else if (scnt = secure_sscanf (str , & status , "%d %02d:%02d:%02d.%09s" ,
604
+ ARG_INT (& days ), ARG_INT (& hours ),
605
+ ARG_INT (& minutes ), ARG_INT (& seconds ),
606
+ ARG_STR (& lit2 , sizeof (lit2 ))
607
+ ), 5 == scnt || 4 == scnt )
592
608
{
593
609
sign = days < 0 ? SQL_TRUE : SQL_FALSE ;
594
610
st -> interval_type = itype ;
@@ -601,7 +617,9 @@ interval2istruct(SQLSMALLINT ctype, int precision, const char *str, SQL_INTERVAL
601
617
st -> intval .day_second .fraction = getPrecisionPart (precision , lit2 );
602
618
return TRUE;
603
619
}
604
- else if ((scnt = sscanf (str , "%d %10s %d %10s" , & years , lit1 , & mons , lit2 )) >=4 )
620
+ else if ((scnt = secure_sscanf (str , & status , "%d %10s %d %10s" ,
621
+ ARG_INT (& years ), ARG_STR (& lit1 , sizeof (lit1 )),
622
+ ARG_INT (& mons ), ARG_STR (& lit2 , sizeof (lit2 )))) >=4 )
605
623
{
606
624
if (strnicmp (lit1 , "year" , 4 ) == 0 &&
607
625
strnicmp (lit2 , "mon" , 2 ) == 0 &&
@@ -617,7 +635,9 @@ interval2istruct(SQLSMALLINT ctype, int precision, const char *str, SQL_INTERVAL
617
635
}
618
636
return FALSE;
619
637
}
620
- if ((scnt = sscanf (str , "%d %10s %d" , & years , lit1 , & days )) == 2 )
638
+ if ((scnt = secure_sscanf (str , & status , "%d %10s %d" ,
639
+ ARG_INT (& years ), ARG_STR (& lit1 , sizeof (lit1 )),
640
+ ARG_INT (& days ))) == 2 )
621
641
{
622
642
sign = years < 0 ? SQL_TRUE : SQL_FALSE ;
623
643
if (SQL_IS_YEAR == itype &&
@@ -654,7 +674,10 @@ interval2istruct(SQLSMALLINT ctype, int precision, const char *str, SQL_INTERVAL
654
674
/* these formats should've been handled above already */
655
675
return FALSE;
656
676
}
657
- scnt = sscanf (str , "%d %10s %02d:%02d:%02d.%09s" , & days , lit1 , & hours , & minutes , & seconds , lit2 );
677
+ scnt = secure_sscanf (str , & status , "%d %10s %02d:%02d:%02d.%09s" ,
678
+ ARG_INT (& days ), ARG_STR (& lit1 , sizeof (lit1 )),
679
+ ARG_INT (& hours ), ARG_INT (& minutes ), ARG_INT (& seconds ),
680
+ ARG_STR (& lit2 , sizeof (lit2 )));
658
681
if (scnt == 5 || scnt == 6 )
659
682
{
660
683
if (strnicmp (lit1 , "day" , 3 ) != 0 )
@@ -671,7 +694,9 @@ interval2istruct(SQLSMALLINT ctype, int precision, const char *str, SQL_INTERVAL
671
694
st -> intval .day_second .fraction = getPrecisionPart (precision , lit2 );
672
695
return TRUE;
673
696
}
674
- scnt = sscanf (str , "%02d:%02d:%02d.%09s" , & hours , & minutes , & seconds , lit2 );
697
+ scnt = secure_sscanf (str , & status , "%02d:%02d:%02d.%09s" ,
698
+ ARG_INT (& hours ), ARG_INT (& minutes ), ARG_INT (& seconds ),
699
+ ARG_STR (& lit2 , sizeof (lit2 )));
675
700
if (scnt == 3 || scnt == 4 )
676
701
{
677
702
sign = hours < 0 ? SQL_TRUE : SQL_FALSE ;
@@ -860,12 +885,15 @@ static int char2guid(const char *str, SQLGUID *g)
860
885
* "unsigned int", so use a temporary variable for it.
861
886
*/
862
887
unsigned int Data1 ;
863
- if (sscanf (str ,
888
+ int status = 0 ;
889
+ if (secure_sscanf (str , & status ,
864
890
"%08X-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX" ,
865
- & Data1 ,
866
- & g -> Data2 , & g -> Data3 ,
867
- & g -> Data4 [0 ], & g -> Data4 [1 ], & g -> Data4 [2 ], & g -> Data4 [3 ],
868
- & g -> Data4 [4 ], & g -> Data4 [5 ], & g -> Data4 [6 ], & g -> Data4 [7 ]) < 11 )
891
+ ARG_UINT (& Data1 ),
892
+ ARG_USHORT (& g -> Data2 ), ARG_USHORT (& g -> Data3 ),
893
+ ARG_UCHAR (& g -> Data4 [0 ]), ARG_UCHAR (& g -> Data4 [1 ]),
894
+ ARG_UCHAR (& g -> Data4 [2 ]), ARG_UCHAR (& g -> Data4 [3 ]),
895
+ ARG_UCHAR (& g -> Data4 [4 ]), ARG_UCHAR (& g -> Data4 [5 ]),
896
+ ARG_UCHAR (& g -> Data4 [6 ]), ARG_UCHAR (& g -> Data4 [7 ])) < 11 )
869
897
return COPY_GENERAL_ERROR ;
870
898
g -> Data1 = Data1 ;
871
899
return COPY_OK ;
@@ -1416,7 +1444,11 @@ MYLOG(0, "null_cvt_date_string=%d\n", conn->connInfo.cvt_null_date_string);
1416
1444
* PG_TYPE_CHAR,VARCHAR $$$
1417
1445
*/
1418
1446
case PG_TYPE_DATE :
1419
- sscanf (value , "%4d-%2d-%2d" , & std_time .y , & std_time .m , & std_time .d );
1447
+ {
1448
+ int status = 0 ;
1449
+ secure_sscanf (value , & status , "%4d-%2d-%2d" ,
1450
+ ARG_INT (& std_time .y ), ARG_INT (& std_time .m ), ARG_INT (& std_time .d ));
1451
+ }
1420
1452
break ;
1421
1453
1422
1454
case PG_TYPE_TIME :
@@ -1530,7 +1562,8 @@ MYLOG(DETAIL_LOG_LEVEL, "2stime fr=%d\n", std_time.fr);
1530
1562
MYLOG (0 , "index=(" );
1531
1563
for (i = 0 ;; i ++ )
1532
1564
{
1533
- if (sscanf (vp , "%hi" , & shortv ) != 1 )
1565
+ int status = 0 ;
1566
+ if (secure_sscanf (vp , & status , "%hi" , ARG_SHORT (& shortv )) != 1 )
1534
1567
break ;
1535
1568
MYPRINTF (0 , " %hi" , shortv );
1536
1569
nval ++ ;
@@ -5555,7 +5588,8 @@ convert_escape(QueryParse *qp, QueryBuild *qb)
5555
5588
while (isspace ((UCHAR ) qp -> statement [++ qp -> opos ]));
5556
5589
}
5557
5590
5558
- sscanf (F_OldPtr (qp ), "%32s" , key );
5591
+ int status = 0 ;
5592
+ secure_sscanf (F_OldPtr (qp ), & status , "%32s" , ARG_STR (& key , sizeof (key )));
5559
5593
while ((ucv = F_OldChar (qp )) != '\0' && (IS_NOT_SPACE (ucv )))
5560
5594
F_OldNext (qp );
5561
5595
while ((ucv = F_OldChar (qp )) != '\0' && isspace (ucv ))
@@ -5970,6 +6004,7 @@ parse_datetime(const char *buf, SIMPLE_TIME *st)
5970
6004
mm ,
5971
6005
ss ;
5972
6006
int nf ;
6007
+ int status = 0 ;
5973
6008
BOOL bZone ; int zone ;
5974
6009
5975
6010
y = m = d = hh = mm = ss = 0 ;
@@ -5993,9 +6028,13 @@ parse_datetime(const char *buf, SIMPLE_TIME *st)
5993
6028
if (timestamp2stime (buf , st , & bZone , & zone ))
5994
6029
return TRUE;
5995
6030
if (buf [4 ] == '-' ) /* year first */
5996
- nf = sscanf (buf , "%4d-%2d-%2d %2d:%2d:%2d" , & y , & m , & d , & hh , & mm , & ss );
6031
+ nf = secure_sscanf (buf , & status , "%4d-%2d-%2d %2d:%2d:%2d" ,
6032
+ ARG_INT (& y ), ARG_INT (& m ), ARG_INT (& d ),
6033
+ ARG_INT (& hh ), ARG_INT (& mm ), ARG_INT (& ss ));
5997
6034
else
5998
- nf = sscanf (buf , "%2d-%2d-%4d %2d:%2d:%2d" , & m , & d , & y , & hh , & mm , & ss );
6035
+ nf = secure_sscanf (buf , & status , "%2d-%2d-%4d %2d:%2d:%2d" ,
6036
+ ARG_INT (& m ), ARG_INT (& d ), ARG_INT (& y ),
6037
+ ARG_INT (& hh ), ARG_INT (& mm ), ARG_INT (& ss ));
5999
6038
6000
6039
if (nf == 5 || nf == 6 )
6001
6040
{
@@ -6010,9 +6049,11 @@ parse_datetime(const char *buf, SIMPLE_TIME *st)
6010
6049
}
6011
6050
6012
6051
if (buf [4 ] == '-' ) /* year first */
6013
- nf = sscanf (buf , "%4d-%2d-%2d" , & y , & m , & d );
6052
+ nf = secure_sscanf (buf , & status , "%4d-%2d-%2d" ,
6053
+ ARG_INT (& y ), ARG_INT (& m ), ARG_INT (& d ));
6014
6054
else
6015
- nf = sscanf (buf , "%2d-%2d-%4d" , & m , & d , & y );
6055
+ nf = secure_sscanf (buf , & status , "%2d-%2d-%4d" ,
6056
+ ARG_INT (& m ), ARG_INT (& d ), ARG_INT (& y ));
6016
6057
6017
6058
if (nf == 3 )
6018
6059
{
@@ -6023,7 +6064,8 @@ parse_datetime(const char *buf, SIMPLE_TIME *st)
6023
6064
return TRUE;
6024
6065
}
6025
6066
6026
- nf = sscanf (buf , "%2d:%2d:%2d" , & hh , & mm , & ss );
6067
+ nf = secure_sscanf (buf , & status , "%2d:%2d:%2d" ,
6068
+ ARG_INT (& hh ), ARG_INT (& mm ), ARG_INT (& ss ));
6027
6069
if (nf == 2 || nf == 3 )
6028
6070
{
6029
6071
st -> hh = hh ;
0 commit comments