Skip to content

Commit 1a226f5

Browse files
committed
Merge pull request #4466 from ScriptDevil/master
Range checking and miscellaneous fixes tin time library
2 parents 9d67267 + e69d491 commit 1a226f5

File tree

1 file changed

+34
-33
lines changed

1 file changed

+34
-33
lines changed

src/libstd/time.rs

+34-33
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,16 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
341341
Some((value, pos))
342342
}
343343

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+
344354
fn parse_char(s: &str, pos: uint, c: char) -> Result<uint, ~str> {
345355
let range = str::char_range_at(s, pos);
346356

@@ -414,7 +424,8 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
414424
Some(item) => { let (v, pos) = item; tm.tm_mon = v; Ok(pos) }
415425
None => Err(~"Invalid month")
416426
},
417-
'C' => match match_digits(s, pos, 2u, false) {
427+
'C' => match match_digits_in_range(s, pos, 2u, false, 0_i32,
428+
99_i32) {
418429
Some(item) => {
419430
let (v, pos) = item;
420431
tm.tm_year += (v * 100_i32) - 1900_i32;
@@ -440,11 +451,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
440451
.chain(|pos| parse_char(s, pos, '/'))
441452
.chain(|pos| parse_type(s, pos, 'y', &mut *tm))
442453
}
443-
'd' => match match_digits(s, pos, 2u, false) {
454+
'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32,
455+
31_i32) {
444456
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
445457
None => Err(~"Invalid day of the month")
446458
},
447-
'e' => match match_digits(s, pos, 2u, true) {
459+
'e' => match match_digits_in_range(s, pos, 2u, true, 1_i32,
460+
31_i32) {
448461
Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) }
449462
None => Err(~"Invalid day of the month")
450463
},
@@ -456,15 +469,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
456469
.chain(|pos| parse_type(s, pos, 'd', &mut *tm))
457470
}
458471
'H' => {
459-
// FIXME (#2350): range check.
460-
match match_digits(s, pos, 2u, false) {
472+
match match_digits_in_range(s, pos, 2u, false, 0_i32, 23_i32) {
461473
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
462474
None => Err(~"Invalid hour")
463475
}
464476
}
465477
'I' => {
466-
// FIXME (#2350): range check.
467-
match match_digits(s, pos, 2u, false) {
478+
match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) {
468479
Some(item) => {
469480
let (v, pos) = item;
470481
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> {
474485
}
475486
}
476487
'j' => {
477-
// FIXME (#2350): range check.
478-
match match_digits(s, pos, 3u, false) {
488+
match match_digits_in_range(s, pos, 3u, false, 1_i32, 366_i32) {
479489
Some(item) => {
480490
let (v, pos) = item;
481491
tm.tm_yday = v - 1_i32;
482492
Ok(pos)
483493
}
484-
None => Err(~"Invalid year")
494+
None => Err(~"Invalid day of year")
485495
}
486496
}
487497
'k' => {
488-
// FIXME (#2350): range check.
489-
match match_digits(s, pos, 2u, true) {
498+
match match_digits_in_range(s, pos, 2u, true, 0_i32, 23_i32) {
490499
Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) }
491500
None => Err(~"Invalid hour")
492501
}
493502
}
494503
'l' => {
495-
// FIXME (#2350): range check.
496-
match match_digits(s, pos, 2u, true) {
504+
match match_digits_in_range(s, pos, 2u, true, 1_i32, 12_i32) {
497505
Some(item) => {
498506
let (v, pos) = item;
499507
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> {
503511
}
504512
}
505513
'M' => {
506-
// FIXME (#2350): range check.
507-
match match_digits(s, pos, 2u, false) {
514+
match match_digits_in_range(s, pos, 2u, false, 0_i32, 59_i32) {
508515
Some(item) => { let (v, pos) = item; tm.tm_min = v; Ok(pos) }
509516
None => Err(~"Invalid minute")
510517
}
511518
}
512519
'm' => {
513-
// FIXME (#2350): range check.
514-
match match_digits(s, pos, 2u, false) {
520+
match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) {
515521
Some(item) => {
516522
let (v, pos) = item;
517523
tm.tm_mon = v - 1_i32;
@@ -548,8 +554,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
548554
.chain(|pos| parse_type(s, pos, 'p', &mut *tm))
549555
}
550556
'S' => {
551-
// FIXME (#2350): range check.
552-
match match_digits(s, pos, 2u, false) {
557+
match match_digits_in_range(s, pos, 2u, false, 0_i32, 60_i32) {
553558
Some(item) => {
554559
let (v, pos) = item;
555560
tm.tm_sec = v;
@@ -568,14 +573,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
568573
}
569574
't' => parse_char(s, pos, '\t'),
570575
'u' => {
571-
// FIXME (#2350): range check.
572-
match match_digits(s, pos, 1u, false) {
576+
match match_digits_in_range(s, pos, 1u, false, 1_i32, 7_i32) {
573577
Some(item) => {
574578
let (v, pos) = item;
575-
tm.tm_wday = v;
579+
tm.tm_wday = v-1_i32;
576580
Ok(pos)
577581
}
578-
None => Err(~"Invalid weekday")
582+
None => Err(~"Invalid day of week")
579583
}
580584
}
581585
'v' => {
@@ -587,34 +591,31 @@ priv fn do_strptime(s: &str, format: &str) -> Result<Tm, ~str> {
587591
}
588592
//'W' {}
589593
'w' => {
590-
// FIXME (#2350): range check.
591-
match match_digits(s, pos, 1u, false) {
594+
match match_digits_in_range(s, pos, 1u, false, 0_i32, 6_i32) {
592595
Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) }
593-
None => Err(~"Invalid weekday")
596+
None => Err(~"Invalid day of week")
594597
}
595598
}
596599
//'X' {}
597600
//'x' {}
598601
'Y' => {
599-
// FIXME (#2350): range check.
600602
match match_digits(s, pos, 4u, false) {
601603
Some(item) => {
602604
let (v, pos) = item;
603605
tm.tm_year = v - 1900_i32;
604606
Ok(pos)
605607
}
606-
None => Err(~"Invalid weekday")
608+
None => Err(~"Invalid year")
607609
}
608610
}
609611
'y' => {
610-
// FIXME (#2350): range check.
611-
match match_digits(s, pos, 2u, false) {
612+
match match_digits_in_range(s, pos, 2u, false, 0_i32, 99_i32) {
612613
Some(item) => {
613614
let (v, pos) = item;
614-
tm.tm_year = v - 1900_i32;
615+
tm.tm_year = v;
615616
Ok(pos)
616617
}
617-
None => Err(~"Invalid weekday")
618+
None => Err(~"Invalid year")
618619
}
619620
}
620621
'Z' => {

0 commit comments

Comments
 (0)