@@ -341,6 +341,16 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
341
341
Some ( ( value, pos) )
342
342
}
343
343
344
+ fn match_digits_in_range ( ss : & str , pos : uint , digits : uint , ws : bool ,
345
+ min : i32 , max : i32 ) -> Option < ( i32 , uint ) > {
346
+ match match_digits ( ss, pos, digits, ws) {
347
+ Some ( ( val, pos) ) if val >= min && val <= max => {
348
+ Some ( ( val, pos) )
349
+ }
350
+ _ => None
351
+ }
352
+ }
353
+
344
354
fn parse_char ( s : & str , pos : uint , c : char ) -> Result < uint , ~str > {
345
355
let range = str:: char_range_at ( s, pos) ;
346
356
@@ -414,7 +424,8 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
414
424
Some ( item) => { let ( v, pos) = item; tm. tm_mon = v; Ok ( pos) }
415
425
None => Err ( ~"Invalid month")
416
426
} ,
417
- 'C' => match match_digits ( s, pos, 2 u, false ) {
427
+ 'C' => match match_digits_in_range ( s, pos, 2 u, false , 0_i32 ,
428
+ 99_i32 ) {
418
429
Some ( item) => {
419
430
let ( v, pos) = item;
420
431
tm. tm_year += ( v * 100_i32 ) - 1900_i32 ;
@@ -440,11 +451,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
440
451
. chain ( |pos| parse_char ( s, pos, '/' ) )
441
452
. chain ( |pos| parse_type ( s, pos, 'y' , & mut * tm) )
442
453
}
443
- 'd' => match match_digits ( s, pos, 2 u, false ) {
454
+ 'd' => match match_digits_in_range ( s, pos, 2 u, false , 1_i32 ,
455
+ 31_i32 ) {
444
456
Some ( item) => { let ( v, pos) = item; tm. tm_mday = v; Ok ( pos) }
445
457
None => Err ( ~"Invalid day of the month")
446
458
} ,
447
- 'e' => match match_digits ( s, pos, 2 u, true ) {
459
+ 'e' => match match_digits_in_range ( s, pos, 2 u, true , 1_i32 ,
460
+ 31_i32 ) {
448
461
Some ( item) => { let ( v, pos) = item; tm. tm_mday = v; Ok ( pos) }
449
462
None => Err ( ~"Invalid day of the month")
450
463
} ,
@@ -456,15 +469,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
456
469
. chain ( |pos| parse_type ( s, pos, 'd' , & mut * tm) )
457
470
}
458
471
'H' => {
459
- // FIXME (#2350): range check.
460
- match match_digits ( s, pos, 2 u, false ) {
472
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 23_i32 ) {
461
473
Some ( item) => { let ( v, pos) = item; tm. tm_hour = v; Ok ( pos) }
462
474
None => Err ( ~"Invalid hour")
463
475
}
464
476
}
465
477
'I' => {
466
- // FIXME (#2350): range check.
467
- match match_digits ( s, pos, 2 u, false ) {
478
+ match match_digits_in_range ( s, pos, 2 u, false , 1_i32 , 12_i32 ) {
468
479
Some ( item) => {
469
480
let ( v, pos) = item;
470
481
tm. tm_hour = if v == 12_i32 { 0_i32 } else { v } ;
@@ -474,26 +485,23 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
474
485
}
475
486
}
476
487
'j' => {
477
- // FIXME (#2350): range check.
478
- match match_digits ( s, pos, 3 u, false ) {
488
+ match match_digits_in_range ( s, pos, 3 u, false , 1_i32 , 366_i32 ) {
479
489
Some ( item) => {
480
490
let ( v, pos) = item;
481
491
tm. tm_yday = v - 1_i32 ;
482
492
Ok ( pos)
483
493
}
484
- None => Err ( ~"Invalid year")
494
+ None => Err ( ~"Invalid day of year")
485
495
}
486
496
}
487
497
'k' => {
488
- // FIXME (#2350): range check.
489
- match match_digits ( s, pos, 2 u, true ) {
498
+ match match_digits_in_range ( s, pos, 2 u, true , 0_i32 , 23_i32 ) {
490
499
Some ( item) => { let ( v, pos) = item; tm. tm_hour = v; Ok ( pos) }
491
500
None => Err ( ~"Invalid hour")
492
501
}
493
502
}
494
503
'l' => {
495
- // FIXME (#2350): range check.
496
- match match_digits ( s, pos, 2 u, true ) {
504
+ match match_digits_in_range ( s, pos, 2 u, true , 1_i32 , 12_i32 ) {
497
505
Some ( item) => {
498
506
let ( v, pos) = item;
499
507
tm. tm_hour = if v == 12_i32 { 0_i32 } else { v } ;
@@ -503,15 +511,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
503
511
}
504
512
}
505
513
'M' => {
506
- // FIXME (#2350): range check.
507
- match match_digits ( s, pos, 2 u, false ) {
514
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 59_i32 ) {
508
515
Some ( item) => { let ( v, pos) = item; tm. tm_min = v; Ok ( pos) }
509
516
None => Err ( ~"Invalid minute")
510
517
}
511
518
}
512
519
'm' => {
513
- // FIXME (#2350): range check.
514
- match match_digits ( s, pos, 2 u, false ) {
520
+ match match_digits_in_range ( s, pos, 2 u, false , 1_i32 , 12_i32 ) {
515
521
Some ( item) => {
516
522
let ( v, pos) = item;
517
523
tm. tm_mon = v - 1_i32 ;
@@ -548,8 +554,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
548
554
. chain ( |pos| parse_type ( s, pos, 'p' , & mut * tm) )
549
555
}
550
556
'S' => {
551
- // FIXME (#2350): range check.
552
- match match_digits ( s, pos, 2 u, false ) {
557
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 60_i32 ) {
553
558
Some ( item) => {
554
559
let ( v, pos) = item;
555
560
tm. tm_sec = v;
@@ -568,14 +573,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
568
573
}
569
574
't' => parse_char ( s, pos, '\t' ) ,
570
575
'u' => {
571
- // FIXME (#2350): range check.
572
- match match_digits ( s, pos, 1 u, false ) {
576
+ match match_digits_in_range ( s, pos, 1 u, false , 1_i32 , 7_i32 ) {
573
577
Some ( item) => {
574
578
let ( v, pos) = item;
575
- tm. tm_wday = v;
579
+ tm. tm_wday = v- 1_i32 ;
576
580
Ok ( pos)
577
581
}
578
- None => Err ( ~"Invalid weekday ")
582
+ None => Err ( ~"Invalid day of week ")
579
583
}
580
584
}
581
585
'v' => {
@@ -587,34 +591,31 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
587
591
}
588
592
//'W' {}
589
593
'w' => {
590
- // FIXME (#2350): range check.
591
- match match_digits ( s, pos, 1 u, false ) {
594
+ match match_digits_in_range ( s, pos, 1 u, false , 0_i32 , 6_i32 ) {
592
595
Some ( item) => { let ( v, pos) = item; tm. tm_wday = v; Ok ( pos) }
593
- None => Err ( ~"Invalid weekday ")
596
+ None => Err ( ~"Invalid day of week ")
594
597
}
595
598
}
596
599
//'X' {}
597
600
//'x' {}
598
601
'Y' => {
599
- // FIXME (#2350): range check.
600
602
match match_digits ( s, pos, 4 u, false ) {
601
603
Some ( item) => {
602
604
let ( v, pos) = item;
603
605
tm. tm_year = v - 1900_i32 ;
604
606
Ok ( pos)
605
607
}
606
- None => Err ( ~"Invalid weekday ")
608
+ None => Err ( ~"Invalid year ")
607
609
}
608
610
}
609
611
'y' => {
610
- // FIXME (#2350): range check.
611
- match match_digits ( s, pos, 2 u, false ) {
612
+ match match_digits_in_range ( s, pos, 2 u, false , 0_i32 , 99_i32 ) {
612
613
Some ( item) => {
613
614
let ( v, pos) = item;
614
- tm. tm_year = v - 1900_i32 ;
615
+ tm. tm_year = v;
615
616
Ok ( pos)
616
617
}
617
- None => Err ( ~"Invalid weekday ")
618
+ None => Err ( ~"Invalid year ")
618
619
}
619
620
}
620
621
'Z' => {
0 commit comments