fn parse_rfc2822<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&'a str, ())> {
macro_rules! try_consume {
($e:expr) => {{ let (s_, v) = $e?;
s = s_;
v
}};
}
// an adapted RFC 2822 syntax from Section 3.3 and 4.3: // // c-char = <any char except '(', ')' and '\\'> // c-escape = "\" <any char> // comment = "(" *(comment / c-char / c-escape) ")" *S // date-time = [ day-of-week "," ] date 1*S time *S *comment // day-of-week = *S day-name *S // day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" // date = day month year // day = *S 1*2DIGIT *S // month = 1*S month-name 1*S // month-name = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / // "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" // year = *S 2*DIGIT *S // time = time-of-day 1*S zone // time-of-day = hour ":" minute [ ":" second ] // hour = *S 2DIGIT *S // minute = *S 2DIGIT *S // second = *S 2DIGIT *S // zone = ( "+" / "-" ) 4DIGIT / // "UT" / "GMT" / ; same as +0000 // "EST" / "CST" / "MST" / "PST" / ; same as -0500 to -0800 // "EDT" / "CDT" / "MDT" / "PDT" / ; same as -0400 to -0700 // 1*(%d65-90 / %d97-122) ; same as -0000 // // some notes: // // - quoted characters can be in any mixture of lower and upper cases. // // - we do not recognize a folding white space (FWS) or comment (CFWS). // for our purposes, instead, we accept any sequence of Unicode // white space characters (denoted here to `S`). For comments, we accept // any text within parentheses while respecting escaped parentheses. // Any actual RFC 2822 parser is expected to parse FWS and/or CFWS themselves // and replace it with a single SP (`%x20`); this is legitimate. // // - two-digit year < 50 should be interpreted by adding 2000. // two-digit year >= 50 or three-digit year should be interpreted // by adding 1900. note that four-or-more-digit years less than 1000 // are *never* affected by this rule. // // - mismatching day-of-week is always an error, which is consistent to // Chrono's own rules. // // - zones can range from `-9959` to `+9959`, but `FixedOffset` does not // support offsets larger than 24 hours. this is not *that* problematic // since we do not directly go to a `DateTime` so one can recover // the offset information from `Parsed` anyway.
s = s.trim_start();
iflet Ok((s_, weekday)) = scan::short_weekday(s) { if !s_.starts_with(',') { return Err(INVALID);
}
s = &s_[1..];
parsed.set_weekday(weekday)?;
}
s = s.trim_start();
parsed.set_day(try_consume!(scan::number(s, 1, 2)))?;
s = scan::space(s)?; // mandatory
parsed.set_month(1 + i64::from(try_consume!(scan::short_month0(s))))?;
s = scan::space(s)?; // mandatory
// distinguish two- and three-digit years from four-digit years let prevlen = s.len(); letmut year = try_consume!(scan::number(s, 2, usize::MAX)); let yearlen = prevlen - s.len(); match (yearlen, year) {
(2, 0..=49) => {
year += 2000;
} // 47 -> 2047, 05 -> 2005
(2, 50..=99) => {
year += 1900;
} // 79 -> 1979
(3, _) => {
year += 1900;
} // 112 -> 2012, 009 -> 1909
(_, _) => {} // 1987 -> 1987, 0654 -> 0654
}
parsed.set_year(year)?;
// an adapted RFC 3339 syntax from Section 5.6: // // date-fullyear = 4DIGIT // date-month = 2DIGIT ; 01-12 // date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year // time-hour = 2DIGIT ; 00-23 // time-minute = 2DIGIT ; 00-59 // time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second rules // time-secfrac = "." 1*DIGIT // time-numoffset = ("+" / "-") time-hour ":" time-minute // time-offset = "Z" / time-numoffset // partial-time = time-hour ":" time-minute ":" time-second [time-secfrac] // full-date = date-fullyear "-" date-month "-" date-mday // full-time = partial-time time-offset // date-time = full-date "T" full-time // // some notes: // // - quoted characters can be in any mixture of lower and upper cases. // // - it may accept any number of fractional digits for seconds. // for Chrono, this means that we should skip digits past first 9 digits. // // - unlike RFC 2822, the valid offset ranges from -23:59 to +23:59. // note that this restriction is unique to RFC 3339 and not ISO 8601. // since this is not a typical Chrono behavior, we check it earlier. // // - For readability a full-date and a full-time may be separated by a space character.
parsed.set_year(try_consume!(scan::number(s, 4, 4)))?;
s = scan::char(s, b'-')?;
parsed.set_month(try_consume!(scan::number(s, 2, 2)))?;
s = scan::char(s, b'-')?;
parsed.set_day(try_consume!(scan::number(s, 2, 2)))?;
parsed.set_hour(try_consume!(scan::number(s, 2, 2)))?;
s = scan::char(s, b':')?;
parsed.set_minute(try_consume!(scan::number(s, 2, 2)))?;
s = scan::char(s, b':')?;
parsed.set_second(try_consume!(scan::number(s, 2, 2)))?; if s.starts_with('.') { let nanosecond = try_consume!(scan::nanosecond(&s[1..]));
parsed.set_nanosecond(nanosecond)?;
}
let offset = try_consume!(scan::timezone_offset(s, |s| scan::char(s, b':'), true, false, true)); // This range check is similar to the one in `FixedOffset::east_opt`, so it would be redundant. // But it is possible to read the offset directly from `Parsed`. We want to only successfully // populate `Parsed` if the input is fully valid RFC 3339. // Max for the hours field is `23`, and for the minutes field `59`. const MAX_RFC3339_OFFSET: i32 = (23 * 60 + 59) * 60; if !(-MAX_RFC3339_OFFSET..=MAX_RFC3339_OFFSET).contains(&offset) { return Err(OUT_OF_RANGE);
}
parsed.set_offset(i64::from(offset))?;
Ok((s, ()))
}
/// Tries to parse given string into `parsed` with given formatting items. /// Returns `Ok` when the entire string has been parsed (otherwise `parsed` should not be used). /// There should be no trailing string after parsing; /// use a stray [`Item::Space`](./enum.Item.html#variant.Space) to trim whitespaces. /// /// This particular date and time parser is: /// /// - Greedy. It will consume the longest possible prefix. /// For example, `April` is always consumed entirely when the long month name is requested; /// it equally accepts `Apr`, but prefers the longer prefix in this case. /// /// - Padding-agnostic (for numeric items). /// The [`Pad`](./enum.Pad.html) field is completely ignored, /// so one can prepend any number of whitespace then any number of zeroes before numbers. /// /// - (Still) obeying the intrinsic parsing width. This allows, for example, parsing `HHMMSS`. pub fn parse<'a, I, B>(parsed: &mut Parsed, s: &str, items: I) -> ParseResult<()> where
I: Iterator<Item = B>,
B: Borrow<Item<'a>>,
{ match parse_internal(parsed, s, items) {
Ok("") => Ok(()),
Ok(_) => Err(TOO_LONG), // if there are trailing chars it is an error
Err(e) => Err(e),
}
}
/// Tries to parse given string into `parsed` with given formatting items. /// Returns `Ok` with a slice of the unparsed remainder. /// /// This particular date and time parser is: /// /// - Greedy. It will consume the longest possible prefix. /// For example, `April` is always consumed entirely when the long month name is requested; /// it equally accepts `Apr`, but prefers the longer prefix in this case. /// /// - Padding-agnostic (for numeric items). /// The [`Pad`](./enum.Pad.html) field is completely ignored, /// so one can prepend any number of zeroes before numbers. /// /// - (Still) obeying the intrinsic parsing width. This allows, for example, parsing `HHMMSS`. pub fn parse_and_remainder<'a, 'b, I, B>(
parsed: &mut Parsed,
s: &'b str,
items: I,
) -> ParseResult<&'b str> where
I: Iterator<Item = B>,
B: Borrow<Item<'a>>,
{
parse_internal(parsed, s, items)
}
fn parse_internal<'a, 'b, I, B>(
parsed: &mut Parsed, mut s: &'b str,
items: I,
) -> Result<&'b str, ParseError> where
I: Iterator<Item = B>,
B: Borrow<Item<'a>>,
{
macro_rules! try_consume {
($e:expr) => {{ match $e {
Ok((s_, v)) => {
s = s_;
v
}
Err(e) => return Err(e),
}
}};
}
for item in items { match *item.borrow() {
Item::Literal(prefix) => { if s.len() < prefix.len() { return Err(TOO_SHORT);
} if !s.starts_with(prefix) { return Err(INVALID);
}
s = &s[prefix.len()..];
}
#[cfg(feature = "alloc")]
Item::OwnedLiteral(ref prefix) => { if s.len() < prefix.len() { return Err(TOO_SHORT);
} if !s.starts_with(&prefix[..]) { return Err(INVALID);
}
s = &s[prefix.len()..];
}
Item::Space(_) => {
s = s.trim_start();
}
#[cfg(feature = "alloc")]
Item::OwnedSpace(_) => {
s = s.trim_start();
}
// for the future expansion
Internal(ref int) => match int._dummy {},
};
s = s.trim_start(); let v = if signed { if s.starts_with('-') { let v = try_consume!(scan::number(&s[1..], 1, usize::MAX)); 0i64.checked_sub(v).ok_or(OUT_OF_RANGE)?
} elseif s.starts_with('+') {
try_consume!(scan::number(&s[1..], 1, usize::MAX))
} else { // if there is no explicit sign, we respect the original `width`
try_consume!(scan::number(s, 1, width))
}
} else {
try_consume!(scan::number(s, 1, width))
};
set(parsed, v)?;
}
Item::Fixed(ref spec) => { usesuper::Fixed::*;
match spec {
&ShortMonthName => { let month0 = try_consume!(scan::short_month0(s));
parsed.set_month(i64::from(month0) + 1)?;
}
&RFC2822 => try_consume!(parse_rfc2822(parsed, s)),
&RFC3339 => { // Used for the `%+` specifier, which has the description: // "Same as `%Y-%m-%dT%H:%M:%S%.f%:z` (...) // This format also supports having a `Z` or `UTC` in place of `%:z`." // Use the relaxed parser to match this description.
try_consume!(parse_rfc3339_relaxed(parsed, s))
}
}
}
/// Accepts a relaxed form of RFC3339. /// A space or a 'T' are accepted as the separator between the date and time /// parts. Additional spaces are allowed between each component. /// /// All of these examples are equivalent: /// ``` /// # use chrono::{DateTime, offset::FixedOffset}; /// "2012-12-12T12:12:12Z".parse::<DateTime<FixedOffset>>()?; /// "2012-12-12 12:12:12Z".parse::<DateTime<FixedOffset>>()?; /// "2012- 12-12T12: 12:12Z".parse::<DateTime<FixedOffset>>()?; /// # Ok::<(), chrono::ParseError>(()) /// ``` impl str::FromStr for DateTime<FixedOffset> { type Err = ParseError;
/// Accepts a relaxed form of RFC3339. /// /// Differences with RFC3339: /// - Values don't require padding to two digits. /// - Years outside the range 0...=9999 are accepted, but they must include a sign. /// - `UTC` is accepted as a valid timezone name/offset (for compatibility with the debug format of /// `DateTime<Utc>`. /// - There can be spaces between any of the components. /// - The colon in the offset may be missing.
fn parse_rfc3339_relaxed<'a>(parsed: &mut Parsed, mut s: &'a str) -> ParseResult<(&tyle='color:blue'>'a str, ())> { const DATE_ITEMS: &[Item<'static>] = &[
Item::Numeric(Numeric::Year, Pad::Zero),
Item::Space(""),
Item::Literal("-"),
Item::Numeric(Numeric::Month, Pad::Zero),
Item::Space(""),
Item::Literal("-"),
Item::Numeric(Numeric::Day, Pad::Zero),
]; const TIME_ITEMS: &[Item<'static>] = &[
Item::Numeric(Numeric::Hour, Pad::Zero),
Item::Space(""),
Item::Literal(":"),
Item::Numeric(Numeric::Minute, Pad::Zero),
Item::Space(""),
Item::Literal(":"),
Item::Numeric(Numeric::Second, Pad::Zero),
Item::Fixed(Fixed::Nanosecond),
Item::Space(""),
];
s = parse_internal(parsed, s, DATE_ITEMS.iter())?;
// fixed-length fractions of a second
check("", &[fixed(Nanosecond3)], parsed!()); // no field set, but not an error
check("4", &[fixed(Nanosecond3)], Err(TOO_LONG)); // never consumes `4`
check(".12", &[fixed(Nanosecond3)], Err(TOO_SHORT));
check(".123", &[fixed(Nanosecond3)], parsed!(nanosecond: 123_000_000));
check(".1234", &[fixed(Nanosecond3)], Err(TOO_LONG));
check(".1234", &[fixed(Nanosecond3), Literal("4")], parsed!(nanosecond: 123_000_000));
check("", &[fixed(Nanosecond6)], parsed!()); // no field set, but not an error
check("4", &[fixed(Nanosecond6)], Err(TOO_LONG)); // never consumes `4`
check(".12345", &[fixed(Nanosecond6)], Err(TOO_SHORT));
check(".123456", &[fixed(Nanosecond6)], parsed!(nanosecond: 123_456_000));
check(".1234567", &[fixed(Nanosecond6)], Err(TOO_LONG));
check(".1234567", &[fixed(Nanosecond6), Literal("7")], parsed!(nanosecond: 123_456_000));
check("", &[fixed(Nanosecond9)], parsed!()); // no field set, but not an error
check("4", &[fixed(Nanosecond9)], Err(TOO_LONG)); // never consumes `4`
check(".12345678", &[fixed(Nanosecond9)], Err(TOO_SHORT));
check(".123456789", &[fixed(Nanosecond9)], parsed!(nanosecond: 123_456_789));
check(".1234567890", &[fixed(Nanosecond9)], Err(TOO_LONG));
check(".1234567890", &[fixed(Nanosecond9), Literal("0")], parsed!(nanosecond: 123_456_789));
// TimezoneName
check("CEST", &[fixed(TimezoneName)], parsed!());
check("cest", &[fixed(TimezoneName)], parsed!()); // lowercase
check("XXXXXXXX", &[fixed(TimezoneName)], parsed!()); // not a real timezone name
check("!!!!", &[fixed(TimezoneName)], parsed!()); // not a real timezone name!
check("CEST 5", &[fixed(TimezoneName), Literal(" "), num(Numeric::Day)], parsed!(day: 5));
check("CEST ", &[fixed(TimezoneName)], Err(TOO_LONG));
check(" CEST", &[fixed(TimezoneName)], Err(TOO_LONG));
check("CE ST", &[fixed(TimezoneName)], Err(TOO_LONG));
}
#[test] #[rustfmt::skip]
fn test_parse_practical_examples() {
use crate::format::InternalInternal::*;
use crate::format::Item::{Literal, Space};
use crate::format::Numeric::*;
"Sun Aug 02 ::15 CEST 2020",
&[
if (JvmtiExport:can_pop_frame()) {
Space(" "), num(Day), Space(/
Literal(":"), num(Second), Space(" // call_VM_base, so the arg registers are available.
num(Year
], // address of the same-named entrypoint in the generated interpreter code.
year: 2020, month: 8, dayjrx10;
hour_div_12: 1, hour_mod_12: 1, minute: 39, second: 15
)java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
;
check(
ld(x10 val_addr;
rsed(
year:2006, month: 1, day: day:2,hour_div_12:1,hour_mod_12:3 minute 4 :5
)
);
check(
:14PM"
&Hour12) (""),num) fixedFixed:LowerAmPm]java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
parsed(hour_div_12: 1, hour_mod_12: 3, minute: 14),
);
check( "12345678901234.56789",
&[num(Timestamp), Literal("lwut0 Address( JvmtiThreadState:earlyret_state_offset()))
parsed
ld(,Address(xthread JavaThread::jvmti_thread_state_offset());
check( "1234567890123456789,
&[() Fixed:anosecond]
java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 38
;
// docstring examples from `impl str::FromStr`
check( "2000-01-02T03:04:05Z"(cp_offset >0 bcp stillpointing tostartofbytecode)
}elseif (index_size == sizeof(u4)) {
num(Year), Literal java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
num( else if (index_size= (u1) {
internal_fixed(imezoneOffsetPermissive)
],
parsed!(
year: 2000, month: 1, day: 2 { 0
),
);
checkjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14 "2000-01-2 ::5Z", voidInterpreterMacroAssembler::get_cache_and_index_and_bytecode_at_bcp(Register cache,
num(Year), Literal("-"), num(Month), Literal("-"), num(Day), Space(" "),
num(Hour, Literal(""), num(inute), Literal"", (Second)java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
internal_fixed(TimezoneOffsetPermissive)
],
parsed!
year: 2000, month: 1, day size_t index_size){
offset: 0
),
);
}
#[track_caller int bcp_offsetjava.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
mut parsed Parsed:new(;
assert!(parse(&mut parsed, sassert(sizeofConstantPoolCacheEntry == 4 java.lang.StringIndexOutOfBoundsException: Range [76, 75) out of bounds for length 78
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
#[track_calleradd(,cache, in_bytes(ConstantPoolCache:base_offset()));
fn checks:&tr :&[tem] : ParseResultParsed) java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
let mut parsed = ->resolved_references(index)
let parse(mutparsed, s,items.iter();
let.map(_ parsed;
assert_eq!(parsed, expected
}
#[test]
fn test_rfc2822()void ::load_resolved_klass_at_offset
let ymd_hmsn = |y, m, d, h, n, s, nano, off| {
lhu(temp,)) // temp = resolved_klass_index
.unwrap()
y,,d h ,s
(
.with_nanosecond(nano)
.unwrap()
};
// Test data - (input, Ok(expected result) or Err(error code))
let testdates = [
("// x10: superklass
(Fri, 2Jan :: -" (,1 17 35,20 0,
Label& java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73 ",20 :35:20-0800 UTC)",Ok(ymd_hmsn2015,1,, 17,35, ,0,-)), // trailing comment
(
rjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
Ok(ymd_hmsn(2015,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
), // complex trailing comment
(r"Tue, addi(esp, esp wordSize)
( "Tue}
Ok(ymd_hmsn(2015, 1, 20, 17, 35, 20 (esp ,2 :);
, // multiple comments
("Tue, 20 Jan bler::(Register ) {
("20Jan 2015173520-",Ok(ymd_hmsn(, 1 ,, 3520,0,-)) // no day of week
("20 JAN 2015 17:35:20 -0800", Ok(ymd_hmsn(2015, 1, 20, 17, 35}
(Tue 20Jan 17:350800, Okymd_hmsn(,1,20,17,350,0 -8)),// no second " Sep :4500+000, Ok(ymd_hmsn(,9,11, 9 45 0 0,0))java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 86
("112001094500 EST" (ymd_hmsn(2001, 9, 11, 9, 45, 0 0-5))java.lang.StringIndexOutOfBoundsException: Index 85 out of bounds for length 85
("11 Sep 2001
("30 Feb 2015 17:35:20 -0800", Err(OUT_OF_RANGE)), // bad day of month "ue 20Jan 2015, Err(TOO_SHORT
("Tue(esp, esp,-2*wordSize;
(" pop_ptr(;
("Tue, 20 Jan 2015 7 case ztos: // fall through case: // fall through
("Tue, java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 12
(Tue 20 Jan 2015:5: 0890, ErrOUT_OF_RANGE), offset
("6 case : // named timezones that have specific timezone offsets // see https://www.rfc-editor.org/rfc/rfc2822#section-4.3java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 54
("Tue, 20 Jan 2015 17:35:20 GMT", Ok(ymd_hmsn(2015, 1, 20, 17, 35, java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 31
("Tue, 20 Janbreak;
("Tue, 20 Jan 2015 break;
(
("Tue, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
("ue 20 Jan 17:520CDT"Okymd_hmsn20151 ,17,3520,,5)))
("Tue, 20 Jan 2015 17:35:20 CST", Ok(ymd_hmsn(2015, 1, 20, (,Address,Interpreterexpr_offset_in_bytesn)java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
("Tue, 20 Jan 2015 17:35:20 MDT",java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
("Tue,
("Tue, 20 Jan 2015 17:35:mv(x19_sender_sp, sp);
("Tue, 20 Jan 2015 17:35:20 PST", Ok(ymd_hmsn( sd(esp,Address,frame::interpreter_frame_last_sp_offset * wordSize));
("Tue, 20 Jan 2015 17java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/
T, 20java.lang.StringIndexOutOfBoundsException: Range [26, 25) out of bounds for length 89 // JVMTI events, such as single-stepping, are implemented partly by avoiding running // interp_only_mode if these events CAN be enabled.
(Tue 2015 :35:20" ((2015 ,20, 17 35 20,0 0),
(Tue, 20 201517:3520 ", ymd_hmsn , 2017 ,20 ,0)) // named single-letter timezone "J" is specifically not validbind();
("Tue, 20 Jan 2015 17:35:20jrt0)java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
("Tue, 20 Jan 2015 17:35:v InterpreterMacroAssembler:(TosState state, int step) {
(Tue,20 2015173520Z, INVALID),
(INVALID)) // bad offset: zulu not allowed
("Tue, 20 Jan 2015 17:35:20 ZULU", ool verifyoop,
("Tue, 20 Jan 2015 17:35:20 −0800", Err(INVALID)), // bad offset: timezone offset using MINUS SIGN (U+2212), not specified for RFC 2822
("Tue, 20 Jan 2015 // Pay attention to the argument Rs, which is acquiesce in t0.
("Tue, 20 }
(Tue, Jan 201517:35:200800, Err(NVALID),// bad character!
];
fn rfc2822_to_datetime(date: &str) -> ParseResult<DateTime<FixedOffsetjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
let ld(1,Address(, JavaThread::polling_word_offset()))
parsemut ,:FixedFixed:]java.lang.StringIndexOutOfBoundsException: Range [76, 71) out of bounds for length 76
.)
}
// Test against test data above for &(date, checkdate) in testdates. #[cfg(feature = "std")]
eprintln!("Test input: {date: ld(1 Addresst1));
let } if dt != checkdate { // check for expected result
panic!( "Date conversion failed for {date}\nReceived: {dt:?}\nExpected: {checkdate:?}"
);
}
}
}
#[test]
add(,xbcp,step)java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24 static
let // load curr
// Check that the format is what we expect #[cfg(// Unlock the receiver ifthis is a synchronized method.
assert_eq!(dt.format(RFC850_FMT).to_string(), "Sunday//
// Check that it parses correctly
assert_eq!(
NaiveDateTime::parse_from_strvoidInterpreterMacroAssembler:remove_activation bool throw_monitor_exceptionjava.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
);
// Check that the rest of the weekdays parse correctly (this test originally failed because unlocked unlock, no_unlock; // Sunday parsed incorrectly).
let testdates = [
(
.with_ymd_and_hms(1994, 11, 7,8, 49, ).nwrap(), "Monday, 07-Nov-94 08:49:37 GMTsuper_call_VM_leaf((,InterpreterRuntime:t_unwind), xthread);
),
(
Utc.with_ymd_and_hmsconst do_not_unlock_if_synchronized(xthread, "Tuesday, 08-Nov-94 08:49:37 GMT",
),
(
.with_ymd_and_hms(199411 ,8,49,37).unwrap(, "Wednesday, 09-Nov-94 08:/java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
),
(
Utc.with_ymd_and_hms(1994o check that object has "ThursdayconstAddress monitor(fp, :interpreter_frame_initial_sp_offset *
),
(
Utc.with_ymd_and_hms(1994, 11, 11, 8, 49, 37).unwrap(), "Friday, 11-Nov-94 08:49:37 GMT",
)
(
Utc.with_ymd_and_hms(1994, 11, 12, 8, 49, 37).unwrap(),call_VM(noreg CAST_FROM_FN_PTRaddress, "Saturday, 12-Nov-94 08:49:37 GMT",
),
];
java.lang.StringIndexOutOfBoundsException: Range [12, 11) out of bounds for length 31
assert_eq!(NaiveDateTime:parse_from_str(al1 ,Ok(val.0.aive_utc());
}
let test_dates_fail = [ "Saturday, 12-Nov-94 08:49:37", "Saturday, 12-Nov-94 08:49:37 Z", "Saturday, 12-Nov-94 08:49:37 GMTTTT",restart
java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 "Saturday, 12-Nov-94 l(, ; "Caturday, 12-Nov-94 08:49:37 GMT", " 99Nov94 :937 " "java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0 "Saturday, 12-Mop-94 08:49CAST_FROM_FN_PTR(address,InterpreterRuntime:: "Saturday, 12-Nov-94 28:49:37 GMT", "Saturday, 12-Nov-94 08:99:37 GMT", "Saturday, 12-Nov-94 08:49:99 GMT",
];
for val in &test_dates_fail {
assert!(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
#[test]
fn test_rfc3339() {
let ymd_hmsnbindloop;
FixedOffset:( * 60java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
.unwrap()
.with_ymd_and_hms(y, m, d, h, nbind(ntry);
.unwrap()
.with_nanosecond(nano)
};
// Test data - (input, Ok(expected result) or Err(error code))
let testdates = [
("2015-01-20T17:35:20-08:00", Ok(ymd_hmsn(2015, (t1,t0 )java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
InterpreterRuntime))java.lang.StringIndexOutOfBoundsException: Index 91 out of bounds for length 91
("1944-06-06T04:04:00Z"
("2001-09-11T09:45:00-08:00", Ok(java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 10
("2015-01-2035:20001-08:" ymd_hmsn2015, 1,20 ,35 ,1__000,-))java.lang.StringIndexOutOfBoundsException: Index 100 out of bounds for length 100
(,esp16) // Lock object
("2015-01-20T17:35:20.000000004-08// c_rarg1: BasicObjectLock to be used for locking
("2015-01-20T17:35:20.000000004−08:00", Ok(ymd_hmsn(2015,// Kills:
( "2015-01-20T17:35:20.000000000452-08:00",
Ok(ymd_hmsn(2015, 1, 20, 17, 35, 20, 0, -8)),
), // too small
"2015-01-20T17:20000000000452−:00,
Ok(ymd_hmsn(2015, 1, 20, 17, 35, 20, 0, -8)),
), const obj_offset =BasicObjectLock::bj_offset_in_bytes();
("2015-01-20 17:35:20-08:00", Ok(ymd_hmsn(2015, 1, 20, 17, 35, 20, 0, -8))), // without 'T'
("2015/01/20T17:35:20.001-08:00", Err(INVALID)), // wrong separator char YMD
-08:00", Err(INVALID), // wrong separator char HMS
(0120T17::20-800" (NVALID) missing
("99-01-20T17:35:20-08:00", Err(INVALID)), andit JVM_ACC_IS_VALUE_BASED_CLASS
( // Load (object->mark() | 1) into swap_reg
("-2000-01ori(,t0,1)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
("2015-02-30T17:35:20-08:00", java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
("2015-01-20T25 swap_reg,,obj_reg, t0,count, /*fallthrough*/NULL);
("2015-01= 0
("2015-01-20T17:35:90-08:00", Err(OUT_OF_RANGE)), // bad second value
("2015-01-20T17:35:20-24:00", Err(OUT_OF_RANGE)), // bad offset value "-0120::20-8:00,Err(INVALID) // bad year format
("15-01-20T17:35:20-08:00:00java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
("2015-01-20T17:35:2008:00", Err(INVALID)), // missing offset sign
("2015 (,
("2015-01-20T17:35:20Zulu", Err(TOO_LONG)), // bad offset format
("2015-01-20T17:35:20 Zulu", Err(INVALID)), // bad offset format
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
("2015-01-20T17:35:20 GMT"// Unlocks an object. Used in monitorexit bytecode and
("2015-01-20T17:35:20+GMT", Err(INVALID)), // bad offset format
("2015-01-20T17:35:20++08:00", Err(INVALID)), // bad offset format
// t0, t1 (temp regs)
("2015-01-20 assert = ," only forlooksItberarg1
("2015-01-T:35200800, Err()), // bad offset sign
("2015-01-20T17:35:20-08-00", Err(INVALID)), // bad offset separator
java.lang.StringIndexOutOfBoundsException: Index 81 out of bounds for length 81
("2015-01
("2015-01-20T17:35:20-08:0", Err(TOO_SHORT)), // bad offset minutes
(2015--20T17:35:20-08:AA INVALID), // bad offset minutes
("2015-01-20T17:35:20-08:ZZ", Err(INVALID)),call_VM_leaf(address InterpreterRuntime::, )
("2015-01-20T17:35:20.001-08 : 00", Err(INVALID)), // bad offset separator
("2015-01-20T17:35:20-08:00:00", int constant
("2015-01-20T17:35:20+08:", Err(TOO_SHORT)), // bad offset format
("2015-01-20T17:35:20-08:}
("2015-01-20T17:35:20−08:", Err(TOO_SHORT)), // bad offset format with MINUS SIGN (U+2212)
("2015-01-20T17:35:20-08", Err(void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in,
("2015-01-20T"int,
("2015-01-20java.lang.StringIndexOutOfBoundsException: Range [59, 27) out of bounds for length 62
("2015-01-20T00:00:1-08:00, )java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
];
// Test against test data above for
let dt = ) if dt != checkdate { // check for expected result
panic!( "Date for date\nReceived:{:}\nExpected:checkdate?"
);
}
}
}
#[test]
fn test_issue_1010() {
let dt = crate::NaiveDateTime::parse_from_str( "\u{c}SUN\u{e}\u{3000}\0m@J\u{3000}\0\u{3000}\0m\u{c}!\u{c}\u{b}\u{c}\u{c}\u{c}\u{c}%A\u{c}\u{b}\0SU\u{c}\u{c}", "uc\{c%\{}\{}0SUN\{}\{}u{SUNN\uc\{c\{}SUN\{}\{}!uc\u{b}uc}uc\u{c}u{c}A\c}\{}a,
;
java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.