@@ -320,6 +320,16 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
320
320
Some ( ( value, pos) )
321
321
}
322
322
323
+ fn match_digits_in_range ( ss : & str , pos : uint , digits : uint , ws : bool , min : i32 , max : i32 )
324
+ -> Option < ( i32 , uint ) > {
325
+ match match_digits ( ss, pos, digits, ws) {
326
+ Some ( ( val, pos) ) if val >= min && val <= max => {
327
+ Some ( ( val, pos) )
328
+ }
329
+ _ => None
330
+ }
331
+ }
332
+
323
333
fn parse_char ( s : & str , pos : uint , c : char ) -> Result < uint , ~str > {
324
334
let range = str:: char_range_at ( s, pos) ;
325
335
@@ -393,7 +403,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
393
403
Some ( item) => { let ( v, pos) = item; tm. tm_mon = v; Ok ( pos) }
394
404
None => Err ( ~"Invalid month")
395
405
} ,
396
- 'C' => match match_digits ( s, pos, 2 u, false ) {
406
+ 'C' => match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 99_i32 ) {
397
407
Some ( item) => {
398
408
let ( v, pos) = item;
399
409
tm. tm_year += ( v * 100_i32 ) - 1900_i32 ;
@@ -419,11 +429,11 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
419
429
. chain ( |pos| parse_char ( s, pos, '/' ) )
420
430
. chain ( |pos| parse_type ( s, pos, 'y' , tm) )
421
431
}
422
- 'd' => match match_digits ( s, pos, 2 u, false ) {
432
+ 'd' => match match_digits_in_range ( s, pos, 2 u, false , 1_i32 , 31_i32 ) {
423
433
Some ( item) => { let ( v, pos) = item; tm. tm_mday = v; Ok ( pos) }
424
434
None => Err ( ~"Invalid day of the month")
425
435
} ,
426
- 'e' => match match_digits ( s, pos, 2 u, true ) {
436
+ 'e' => match match_digits_in_range ( s, pos, 2 u, true , 1_i32 , 31_i32 ) {
427
437
Some ( item) => { let ( v, pos) = item; tm. tm_mday = v; Ok ( pos) }
428
438
None => Err ( ~"Invalid day of the month")
429
439
} ,
@@ -435,15 +445,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
435
445
. chain ( |pos| parse_type ( s, pos, 'd' , tm) )
436
446
}
437
447
'H' => {
438
- // FIXME (#2350): range check.
439
- match match_digits ( s, pos, 2 u, false ) {
448
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 23_i32 ) {
440
449
Some ( item) => { let ( v, pos) = item; tm. tm_hour = v; Ok ( pos) }
441
450
None => Err ( ~"Invalid hour")
442
451
}
443
452
}
444
453
'I' => {
445
- // FIXME (#2350): range check.
446
- match match_digits ( s, pos, 2 u, false ) {
454
+ match match_digits_in_range ( s, pos, 2 u, false , 1_i32 , 12_i32 ) {
447
455
Some ( item) => {
448
456
let ( v, pos) = item;
449
457
tm. tm_hour = if v == 12_i32 { 0_i32 } else { v } ;
@@ -453,8 +461,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
453
461
}
454
462
}
455
463
'j' => {
456
- // FIXME (#2350): range check.
457
- match match_digits ( s, pos, 3 u, false ) {
464
+ match match_digits_in_range ( s, pos, 3 u, false , 1_i32 , 366_i32 ) {
458
465
Some ( item) => {
459
466
let ( v, pos) = item;
460
467
tm. tm_yday = v - 1_i32 ;
@@ -464,15 +471,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
464
471
}
465
472
}
466
473
'k' => {
467
- // FIXME (#2350): range check.
468
- match match_digits ( s, pos, 2 u, true ) {
474
+ match match_digits_in_range ( s, pos, 2 u, true , 0_i32 , 23_i32 ) {
469
475
Some ( item) => { let ( v, pos) = item; tm. tm_hour = v; Ok ( pos) }
470
476
None => Err ( ~"Invalid hour")
471
477
}
472
478
}
473
479
'l' => {
474
- // FIXME (#2350): range check.
475
- match match_digits ( s, pos, 2 u, true ) {
480
+ match match_digits_in_range ( s, pos, 2 u, true , 1_i32 , 12_i32 ) {
476
481
Some ( item) => {
477
482
let ( v, pos) = item;
478
483
tm. tm_hour = if v == 12_i32 { 0_i32 } else { v } ;
@@ -482,15 +487,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
482
487
}
483
488
}
484
489
'M' => {
485
- // FIXME (#2350): range check.
486
- match match_digits ( s, pos, 2 u, false ) {
490
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 59_i32 ) {
487
491
Some ( item) => { let ( v, pos) = item; tm. tm_min = v; Ok ( pos) }
488
492
None => Err ( ~"Invalid minute")
489
493
}
490
494
}
491
495
'm' => {
492
- // FIXME (#2350): range check.
493
- match match_digits ( s, pos, 2 u, false ) {
496
+ match match_digits_in_range ( s, pos, 2 u, false , 1_i32 , 12_i32 ) {
494
497
Some ( item) => {
495
498
let ( v, pos) = item;
496
499
tm. tm_mon = v - 1_i32 ;
@@ -527,8 +530,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
527
530
. chain ( |pos| parse_type ( s, pos, 'p' , tm) )
528
531
}
529
532
'S' => {
530
- // FIXME (#2350): range check.
531
- match match_digits ( s, pos, 2 u, false ) {
533
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 60_i32 ) {
532
534
Some ( item) => {
533
535
let ( v, pos) = item;
534
536
tm. tm_sec = v;
@@ -547,8 +549,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
547
549
}
548
550
't' => parse_char ( s, pos, '\t' ) ,
549
551
'u' => {
550
- // FIXME (#2350): range check.
551
- match match_digits ( s, pos, 1 u, false ) {
552
+ match match_digits_in_range ( s, pos, 1 u, false , 1_i32 , 7_i32 ) {
552
553
Some ( item) => {
553
554
let ( v, pos) = item;
554
555
tm. tm_wday = v-1_i32 ;
@@ -566,16 +567,14 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
566
567
}
567
568
//'W' {}
568
569
'w' => {
569
- // FIXME (#2350): range check.
570
- match match_digits ( s, pos, 1 u, false ) {
570
+ match match_digits_in_range ( s, pos, 1 u, false , 0_i32 , 6_i32 ) {
571
571
Some ( item) => { let ( v, pos) = item; tm. tm_wday = v; Ok ( pos) }
572
572
None => Err ( ~"Invalid day of week")
573
573
}
574
574
}
575
575
//'X' {}
576
576
//'x' {}
577
577
'Y' => {
578
- // FIXME (#2350): range check.
579
578
match match_digits ( s, pos, 4 u, false ) {
580
579
Some ( item) => {
581
580
let ( v, pos) = item;
@@ -586,8 +585,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
586
585
}
587
586
}
588
587
'y' => {
589
- // FIXME (#2350): range check.
590
- match match_digits ( s, pos, 2 u, false ) {
588
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 99_i32 ) {
591
589
Some ( item) => {
592
590
let ( v, pos) = item;
593
591
tm. tm_year = v;
0 commit comments