From ca9358388a7deeffd9f645d08a5755248b0a7a2a Mon Sep 17 00:00:00 2001 From: Ashok Gautham Date: Sun, 13 Jan 2013 16:35:37 +0530 Subject: [PATCH 1/4] Fix incorrect error messages in the time library --- src/libstd/time.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 8cc6d0245a1..72132071a05 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -460,7 +460,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { tm.tm_yday = v - 1_i32; Ok(pos) } - None => Err(~"Invalid year") + None => Err(~"Invalid day of year") } } 'k' => { @@ -554,7 +554,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { tm.tm_wday = v; Ok(pos) } - None => Err(~"Invalid weekday") + None => Err(~"Invalid day of week") } } 'v' => { @@ -569,7 +569,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { // FIXME (#2350): range check. match match_digits(s, pos, 1u, false) { Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) } - None => Err(~"Invalid weekday") + None => Err(~"Invalid day of week") } } //'X' {} @@ -582,7 +582,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { tm.tm_year = v - 1900_i32; Ok(pos) } - None => Err(~"Invalid weekday") + None => Err(~"Invalid year") } } 'y' => { @@ -593,7 +593,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { tm.tm_year = v - 1900_i32; Ok(pos) } - None => Err(~"Invalid weekday") + None => Err(~"Invalid year") } } 'Z' => { From 406d2b3bfe6336c71b6aedd202bb896fc47b2587 Mon Sep 17 00:00:00 2001 From: Ashok Gautham Date: Sun, 13 Jan 2013 16:48:34 +0530 Subject: [PATCH 2/4] Fix errors in how parsed time values were used %u flag takes a value in the range of 1-7. However value needs to be stored in tm.tm_wday between 0 and 6. %y takes a two-digit year value. Subtracting 1900_i32 from it is not needed. --- src/libstd/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 72132071a05..53fb51f08b3 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -551,7 +551,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { match match_digits(s, pos, 1u, false) { Some(item) => { let (v, pos) = item; - tm.tm_wday = v; + tm.tm_wday = v-1_i32; Ok(pos) } None => Err(~"Invalid day of week") @@ -590,7 +590,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { match match_digits(s, pos, 2u, false) { Some(item) => { let (v, pos) = item; - tm.tm_year = v - 1900_i32; + tm.tm_year = v; Ok(pos) } None => Err(~"Invalid year") From a157f1d5bf86c1d929cccb5d1b5b197d3147b760 Mon Sep 17 00:00:00 2001 From: Ashok Gautham Date: Sun, 13 Jan 2013 17:08:33 +0530 Subject: [PATCH 3/4] Add range checking in the time library This was requested in Issue #2350. New function match_digits_in_range added and used instead of match_digits wherever needed. --- src/libstd/time.rs | 50 ++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 53fb51f08b3..5684f8b5810 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -320,6 +320,16 @@ priv fn do_strptime(s: &str, format: &str) -> Result { Some((value, pos)) } + fn match_digits_in_range(ss: &str, pos: uint, digits: uint, ws: bool, min: i32, max: i32) + -> Option<(i32, uint)> { + match match_digits(ss, pos, digits, ws) { + Some((val, pos)) if val >= min && val <= max => { + Some((val, pos)) + } + _ => None + } + } + fn parse_char(s: &str, pos: uint, c: char) -> Result { let range = str::char_range_at(s, pos); @@ -393,7 +403,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { Some(item) => { let (v, pos) = item; tm.tm_mon = v; Ok(pos) } None => Err(~"Invalid month") }, - 'C' => match match_digits(s, pos, 2u, false) { + 'C' => match match_digits_in_range(s, pos, 2u, false, 0_i32, 99_i32) { Some(item) => { let (v, pos) = item; tm.tm_year += (v * 100_i32) - 1900_i32; @@ -419,11 +429,11 @@ priv fn do_strptime(s: &str, format: &str) -> Result { .chain(|pos| parse_char(s, pos, '/')) .chain(|pos| parse_type(s, pos, 'y', tm)) } - 'd' => match match_digits(s, pos, 2u, false) { + 'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32, 31_i32) { Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) } None => Err(~"Invalid day of the month") }, - 'e' => match match_digits(s, pos, 2u, true) { + 'e' => match match_digits_in_range(s, pos, 2u, true, 1_i32, 31_i32) { Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) } None => Err(~"Invalid day of the month") }, @@ -435,15 +445,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result { .chain(|pos| parse_type(s, pos, 'd', tm)) } 'H' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, false) { + match match_digits_in_range(s, pos, 2u, false, 0_i32, 23_i32) { Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) } None => Err(~"Invalid hour") } } 'I' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, false) { + match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) { Some(item) => { let (v, pos) = item; tm.tm_hour = if v == 12_i32 { 0_i32 } else { v }; @@ -453,8 +461,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { } } 'j' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 3u, false) { + match match_digits_in_range(s, pos, 3u, false, 1_i32, 366_i32) { Some(item) => { let (v, pos) = item; tm.tm_yday = v - 1_i32; @@ -464,15 +471,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result { } } 'k' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, true) { + match match_digits_in_range(s, pos, 2u, true, 0_i32, 23_i32) { Some(item) => { let (v, pos) = item; tm.tm_hour = v; Ok(pos) } None => Err(~"Invalid hour") } } 'l' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, true) { + match match_digits_in_range(s, pos, 2u, true, 1_i32, 12_i32) { Some(item) => { let (v, pos) = item; tm.tm_hour = if v == 12_i32 { 0_i32 } else { v }; @@ -482,15 +487,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result { } } 'M' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, false) { + match match_digits_in_range(s, pos, 2u, false, 0_i32, 59_i32) { Some(item) => { let (v, pos) = item; tm.tm_min = v; Ok(pos) } None => Err(~"Invalid minute") } } 'm' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, false) { + match match_digits_in_range(s, pos, 2u, false, 1_i32, 12_i32) { Some(item) => { let (v, pos) = item; tm.tm_mon = v - 1_i32; @@ -527,8 +530,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { .chain(|pos| parse_type(s, pos, 'p', tm)) } 'S' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, false) { + match match_digits_in_range(s, pos, 2u, false, 0_i32, 60_i32) { Some(item) => { let (v, pos) = item; tm.tm_sec = v; @@ -547,8 +549,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { } 't' => parse_char(s, pos, '\t'), 'u' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 1u, false) { + match match_digits_in_range(s, pos, 1u, false, 1_i32, 7_i32) { Some(item) => { let (v, pos) = item; tm.tm_wday = v-1_i32; @@ -566,8 +567,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { } //'W' {} 'w' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 1u, false) { + match match_digits_in_range(s, pos, 1u, false, 0_i32, 6_i32) { Some(item) => { let (v, pos) = item; tm.tm_wday = v; Ok(pos) } None => Err(~"Invalid day of week") } @@ -575,7 +575,6 @@ priv fn do_strptime(s: &str, format: &str) -> Result { //'X' {} //'x' {} 'Y' => { - // FIXME (#2350): range check. match match_digits(s, pos, 4u, false) { Some(item) => { let (v, pos) = item; @@ -586,8 +585,7 @@ priv fn do_strptime(s: &str, format: &str) -> Result { } } 'y' => { - // FIXME (#2350): range check. - match match_digits(s, pos, 2u, false) { + match match_digits_in_range(s, pos, 2u, false, 0_i32, 99_i32) { Some(item) => { let (v, pos) = item; tm.tm_year = v; From e69d491aeaec4402c69d1358d1b64b0bd2847507 Mon Sep 17 00:00:00 2001 From: Ashok Gautham Date: Mon, 14 Jan 2013 10:01:09 +0530 Subject: [PATCH 4/4] Tidied up long lines --- src/libstd/time.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 5684f8b5810..02ed3692a98 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -320,8 +320,8 @@ priv fn do_strptime(s: &str, format: &str) -> Result { Some((value, pos)) } - fn match_digits_in_range(ss: &str, pos: uint, digits: uint, ws: bool, min: i32, max: i32) - -> Option<(i32, uint)> { + fn match_digits_in_range(ss: &str, pos: uint, digits: uint, ws: bool, + min: i32, max: i32) -> Option<(i32, uint)> { match match_digits(ss, pos, digits, ws) { Some((val, pos)) if val >= min && val <= max => { Some((val, pos)) @@ -403,7 +403,8 @@ priv fn do_strptime(s: &str, format: &str) -> Result { Some(item) => { let (v, pos) = item; tm.tm_mon = v; Ok(pos) } None => Err(~"Invalid month") }, - 'C' => match match_digits_in_range(s, pos, 2u, false, 0_i32, 99_i32) { + 'C' => match match_digits_in_range(s, pos, 2u, false, 0_i32, + 99_i32) { Some(item) => { let (v, pos) = item; tm.tm_year += (v * 100_i32) - 1900_i32; @@ -429,11 +430,13 @@ priv fn do_strptime(s: &str, format: &str) -> Result { .chain(|pos| parse_char(s, pos, '/')) .chain(|pos| parse_type(s, pos, 'y', tm)) } - 'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32, 31_i32) { + 'd' => match match_digits_in_range(s, pos, 2u, false, 1_i32, + 31_i32) { Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) } None => Err(~"Invalid day of the month") }, - 'e' => match match_digits_in_range(s, pos, 2u, true, 1_i32, 31_i32) { + 'e' => match match_digits_in_range(s, pos, 2u, true, 1_i32, + 31_i32) { Some(item) => { let (v, pos) = item; tm.tm_mday = v; Ok(pos) } None => Err(~"Invalid day of the month") },