@@ -225,6 +225,39 @@ buf_finalize(StringInfo buf)
225
225
return snap ;
226
226
}
227
227
228
+ /*
229
+ * simple number parser.
230
+ *
231
+ * We return 0 on error, which is invalid value for txid.
232
+ */
233
+ static txid
234
+ str2txid (const char * s , const char * * endp )
235
+ {
236
+ txid val = 0 ;
237
+
238
+ for (; * s ; s ++ )
239
+ {
240
+ txid last = val ;
241
+
242
+ if (* s < '0' || * s > '9' )
243
+ break ;
244
+
245
+ val = val * 10 + (* s - '0' );
246
+
247
+ /*
248
+ * check for overflow
249
+ */
250
+ if (val > MAX_TXID || (val / 10 ) != last )
251
+ {
252
+ val = 0 ;
253
+ break ;
254
+ }
255
+ }
256
+ if (endp )
257
+ * endp = s ;
258
+ return val ;
259
+ }
260
+
228
261
/*
229
262
* parse snapshot from cstring
230
263
*/
@@ -234,21 +267,22 @@ parse_snapshot(const char *str)
234
267
txid xmin ;
235
268
txid xmax ;
236
269
txid last_val = 0 , val ;
237
- char * endp ;
270
+ const char * str_start = str ;
271
+ const char * endp ;
238
272
StringInfo buf ;
239
273
240
- xmin = ( txid ) strtoull ( str , & endp , 0 );
274
+ xmin = str2txid ( str , & endp );
241
275
if (* endp != ':' )
242
276
goto bad_format ;
243
277
str = endp + 1 ;
244
278
245
- xmax = ( txid ) strtoull ( str , & endp , 0 );
279
+ xmax = str2txid ( str , & endp );
246
280
if (* endp != ':' )
247
281
goto bad_format ;
248
282
str = endp + 1 ;
249
283
250
284
/* it should look sane */
251
- if (xmin > xmax || xmin == 0 || xmax > MAX_TXID )
285
+ if (xmin == 0 || xmax == 0 || xmin > xmax )
252
286
goto bad_format ;
253
287
254
288
/* allocate buffer */
@@ -258,11 +292,11 @@ parse_snapshot(const char *str)
258
292
while (* str != '\0' )
259
293
{
260
294
/* read next value */
261
- val = ( txid ) strtoull ( str , & endp , 0 );
295
+ val = str2txid ( str , & endp );
262
296
str = endp ;
263
297
264
298
/* require the input to be in order */
265
- if (val < xmin || val <= last_val || val >= xmax )
299
+ if (val < xmin || val >= xmax || val <= last_val )
266
300
goto bad_format ;
267
301
268
302
buf_add_txid (buf , val );
@@ -277,7 +311,7 @@ parse_snapshot(const char *str)
277
311
return buf_finalize (buf );
278
312
279
313
bad_format :
280
- elog (ERROR , "illegal txid_snapshot input format" );
314
+ elog (ERROR , "invalid input for txid_snapshot: \"%s\"" , str_start );
281
315
return NULL ;
282
316
}
283
317
0 commit comments