@@ -58,121 +58,112 @@ static void ClockFmtScnStorageDelete(ClockFmtScnStorage *fss);
5858 *----------------------------------------------------------------------
5959 */
6060
61- static inline void
62- _str2int_no (
63- int * out ,
64- register
65- const char * p ,
66- const char * e ,
67- int sign )
68- {
69- /* assert(e <= p+10); */
70- register int val = 0 ;
71- /* overflow impossible for 10 digits ("9..9"), so no needs to check at all */
72- while (p < e ) { /* never overflows */
73- val = val * 10 + (* p ++ - '0' );
74- }
75- if (sign < 0 ) { val = - val ; }
76- * out = val ;
77- }
78-
79- static inline void
80- _str2wideInt_no (
81- Tcl_WideInt * out ,
82- register
83- const char * p ,
84- const char * e ,
85- int sign )
86- {
87- /* assert(e <= p+18); */
88- register Tcl_WideInt val = 0 ;
89- /* overflow impossible for 18 digits ("9..9"), so no needs to check at all */
90- while (p < e ) { /* never overflows */
91- val = val * 10 + (* p ++ - '0' );
92- }
93- if (sign < 0 ) { val = - val ; }
94- * out = val ;
95- }
96-
97- /* int & Tcl_WideInt overflows may happens here (expected case) */
98- #if (defined(__GNUC__ ) || defined(__GNUG__ )) && !defined(__clang__ )
99- # pragma GCC optimize("no-trapv")
100- #endif
101-
10261static inline int
10362_str2int (
104- int * out ,
105- register
63+ int * out ,
10664 const char * p ,
10765 const char * e ,
10866 int sign )
10967{
110- register int val = 0 ;
111- /* overflow impossible for 10 digits ("9..9"), so no needs to check before */
112- const char * eNO = p + 10 ;
113- if (eNO > e ) {
114- eNO = e ;
68+ char last ;
69+ int val = 0 ;
70+
71+ if (e - p > 10 ) { /* definitely overflows */
72+ return TCL_ERROR ;
11573 }
116- while (p < eNO ) { /* never overflows */
117- val = val * 10 + (* p ++ - '0' );
74+
75+ /*
76+ * Overflow impossible for max 9 digits ("9..9"),
77+ * or for 10 digits if it starts with 1 ("19..9").
78+ */
79+ if (e - p <= 9 || * p <= '1' ) {
80+ while (p < e ) {
81+ val = val * 10 + (* p ++ - '0' );
82+ }
83+ * out = (sign >= 0 ) ? val : - val ;
84+ return TCL_OK ;
11885 }
86+
87+ /* 10 digits and it may overflow at last char */
88+ e -- ;
89+ while (p < e ) {
90+ val = val * 10 + (* p ++ - '0' );
91+ }
92+ last = * p - '0' ;
11993 if (sign >= 0 ) {
120- while (p < e ) { /* check for overflow */
121- int prev = val ;
122- val = val * 10 + (* p ++ - '0' );
123- if (val / 10 < prev ) {
124- return TCL_ERROR ;
125- }
126- }
94+ if ( (val > INT_MAX / 10 )
95+ || ((val == INT_MAX / 10 ) && (last > INT_MAX % 10 ))
96+ ) {
97+ return TCL_ERROR ; /* overflow*/
98+ }
99+ val = val * 10 + last ;
127100 } else {
128- val = - val ;
129- while (p < e ) { /* check for overflow */
130- int prev = val ;
131- val = val * 10 - (* p ++ - '0' );
132- if (val / 10 > prev ) {
133- return TCL_ERROR ;
134- }
135- }
101+ val = - val ;
102+ if ( (val < INT_MIN / 10 )
103+ || ((val == INT_MIN / 10 ) && ((INT_MIN % 10 < 0 ) ?
104+ (last > - (INT_MIN % 10 )) : (last > 10 - (INT_MIN % 10 ))
105+ ))
106+ ) {
107+ return TCL_ERROR ; /* overflow*/
108+ }
109+ val = val * 10 - last ;
136110 }
111+
137112 * out = val ;
138113 return TCL_OK ;
139114}
140115
141116static inline int
142117_str2wideInt (
143118 Tcl_WideInt * out ,
144- register
145- const char * p ,
146- const char * e ,
119+ const char * p ,
120+ const char * e ,
147121 int sign )
148122{
149- register Tcl_WideInt val = 0 ;
150- /* overflow impossible for 18 digits ("9..9"), so no needs to check before */
151- const char * eNO = p + 18 ;
152- if (eNO > e ) {
153- eNO = e ;
123+ char last ;
124+ Tcl_WideInt val = 0 ;
125+
126+ if (e - p > 19 ) { /* definitely overflows */
127+ return TCL_ERROR ;
154128 }
155- while (p < eNO ) { /* never overflows */
156- val = val * 10 + (* p ++ - '0' );
129+
130+ /*
131+ * Overflow impossible for max 18 digits ("9..9"),
132+ * or for 19 digits if it starts with 8 ("89..9").
133+ */
134+ if (e - p <= 18 || * p <= '8' ) {
135+ while (p < e ) {
136+ val = val * 10 + (* p ++ - '0' );
137+ }
138+ * out = (sign >= 0 ) ? val : - val ;
139+ return TCL_OK ;
140+ }
141+
142+ /* 19 digits and it may overflow at last char */
143+ e -- ;
144+ while (p < e ) {
145+ val = val * 10 + (* p ++ - '0' );
157146 }
147+ last = * p - '0' ;
158148 if (sign >= 0 ) {
159- while (p < e ) { /* check for overflow */
160- Tcl_WideInt prev = val ;
161- val = val * 10 + (* p ++ - '0' );
162- if (val / 10 < prev ) {
163- return TCL_ERROR ;
164- }
165- }
149+ if ( (val > WIDE_MAX / 10 )
150+ || ((val == WIDE_MAX / 10 ) && (last > WIDE_MAX % 10 ))
151+ ) {
152+ return TCL_ERROR ; /* overflow*/
153+ }
154+ val = val * 10 + last ;
166155 } else {
167- val = - val ;
168- while (p < e ) { /* check for overflow */
169- Tcl_WideInt prev = val ;
170- val = val * 10 - (* p ++ - '0' );
171- if (val / 10 > prev ) {
172- return TCL_ERROR ;
173- }
174- }
156+ val = - val ;
157+ if ( (val < WIDE_MIN / 10 )
158+ || ((val == WIDE_MIN / 10 ) && ((WIDE_MIN % 10 < 0 ) ?
159+ (last > - (WIDE_MIN % 10 )) : (last > 10 - (WIDE_MIN % 10 ))
160+ ))
161+ ) {
162+ return TCL_ERROR ; /* overflow*/
163+ }
164+ val = val * 10 - last ;
175165 }
166+
176167 * out = val ;
177168 return TCL_OK ;
178169}
@@ -186,10 +177,6 @@ TclAtoWIe(
186177{
187178 return _str2wideInt (out , p , e , sign );
188179}
189-
190- #if (defined(__GNUC__ ) || defined(__GNUG__ )) && !defined(__clang__ )
191- # pragma GCC reset_options
192- #endif
193180
194181/*
195182 *----------------------------------------------------------------------
@@ -2398,30 +2385,15 @@ ClockScan(
23982385 if (map -> offs ) {
23992386 p = yyInput ; x = p + size ;
24002387 if (map -> type == CTOKT_INT ) {
2401- if (size <= 10 ) {
2402- _str2int_no ((int * )(((char * )info ) + map -> offs ),
2403- p , x , sign );
2404- } else {
2405- /* we don't have such large scan tokens at the moment */
2406- goto overflow ;
2407- /* currently unused (maxSize of CTOKT_INT tokens <= 10) */
2408- #if 0
2409- if (_str2int ((int * )(((char * )info ) + map -> offs ),
2388+ if (_str2int ((int * )(((char * )info ) + map -> offs ),
24102389 p , x , sign ) != TCL_OK ) {
2411- goto overflow ;
2412- }
2413- #endif
2390+ goto overflow ;
24142391 }
24152392 p = x ;
24162393 } else {
2417- if (size <= 18 ) {
2418- _str2wideInt_no ((Tcl_WideInt * )(((char * )info ) + map -> offs ),
2419- p , x , sign );
2420- } else {
2421- if (_str2wideInt ((Tcl_WideInt * )(((char * )info ) + map -> offs ),
2394+ if (_str2wideInt ((Tcl_WideInt * )(((char * )info ) + map -> offs ),
24222395 p , x , sign ) != TCL_OK ) {
2423- goto overflow ;
2424- }
2396+ goto overflow ;
24252397 }
24262398 p = x ;
24272399 }
0 commit comments