Skip to content

Commit 384f2ae

Browse files
drganjooFahad Zubair
andauthored
Only support T as an allowed separator in RFC-3339 dates (#3934)
This PR modifies `aws-smithy-types::DateTime` to enforce the use of 'T' (or 't') as the date-time separator. A [recent merge](https://github.com/time-rs/time/pull/700/files#diff-78a73b9911c88961601784e674a20c89e7050de9f8763522bbaa88ed28311b51R524) in the 'time' crate introduced support for space characters as separators. While ISO 8601 does allow spaces, RFC 3339 strictly requires 'T' (or 't') as the separator. This change restores the behavior to match how it was before `time = 0.3.37`. This PR also removes the temporary pinning of the time crate in protocol tests. Co-authored-by: Fahad Zubair <[email protected]>
1 parent 801054d commit 384f2ae

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

codegen-server-test/build.gradle.kts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ val properties = PropertyRetriever(rootProject, project)
2121
val pluginName = "rust-server-codegen"
2222
val workingDirUnderBuildDir = "smithyprojections/codegen-server-test/"
2323

24-
val checkedInSmithyRuntimeLockfile = rootProject.projectDir.resolve("rust-runtime/Cargo.lock")
25-
2624
dependencies {
2725
implementation(project(":codegen-server"))
2826
implementation("software.amazon.smithy:smithy-aws-protocol-tests:$smithyVersion")
@@ -106,10 +104,9 @@ val allCodegenTests = "../codegen-core/common-test-models".let { commonModels ->
106104
project.registerGenerateSmithyBuildTask(rootProject, pluginName, allCodegenTests)
107105
project.registerGenerateCargoWorkspaceTask(rootProject, pluginName, allCodegenTests, workingDirUnderBuildDir)
108106
project.registerGenerateCargoConfigTomlTask(layout.buildDirectory.dir(workingDirUnderBuildDir).get().asFile)
109-
project.registerCopyCheckedInCargoLockfileTask(checkedInSmithyRuntimeLockfile, layout.buildDirectory.dir(workingDirUnderBuildDir).get().asFile)
110107

111108
tasks["smithyBuild"].dependsOn("generateSmithyBuild")
112-
tasks["assemble"].finalizedBy("generateCargoWorkspace", "copyCheckedInCargoLockfile", "generateCargoConfigToml")
109+
tasks["assemble"].finalizedBy("generateCargoWorkspace", "generateCargoConfigToml")
113110

114111
project.registerModifyMtimeTask()
115112
project.registerCargoCommandsTasks(layout.buildDirectory.dir(workingDirUnderBuildDir).get().asFile)

rust-runtime/aws-smithy-types/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "aws-smithy-types"
3-
version = "1.2.9"
3+
version = "1.2.10"
44
authors = [
55
"AWS Rust SDK Team <[email protected]>",
66
"Russell Cohen <[email protected]>",

rust-runtime/aws-smithy-types/src/date_time/format.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,12 @@ pub(crate) mod rfc3339 {
407407
)
408408
.into());
409409
}
410+
if s.len() > 10 && !matches!(s.as_bytes()[10], b'T' | b't') {
411+
return Err(DateTimeParseErrorKind::Invalid(
412+
"RFC-3339 only allows `T` as a separator for date-time values".into(),
413+
)
414+
.into());
415+
}
410416
let date_time = OffsetDateTime::parse(s, &Rfc3339).map_err(|err| {
411417
DateTimeParseErrorKind::Invalid(format!("invalid RFC-3339 date-time: {}", err).into())
412418
})?;
@@ -773,6 +779,43 @@ mod tests {
773779
http_date_check_roundtrip(9999999999, 0);
774780
}
775781

782+
#[test]
783+
fn parse_rfc3339_invalid_separator() {
784+
let test_cases = [
785+
("1985-04-12 23:20:50Z", AllowOffsets::OffsetsForbidden),
786+
("1985-04-12x23:20:50Z", AllowOffsets::OffsetsForbidden),
787+
("1985-04-12 23:20:50-02:00", AllowOffsets::OffsetsAllowed),
788+
("1985-04-12a23:20:50-02:00", AllowOffsets::OffsetsAllowed),
789+
];
790+
for (date, offset) in test_cases.into_iter() {
791+
let dt = rfc3339::parse(date, offset);
792+
assert!(matches!(
793+
dt.unwrap_err(),
794+
DateTimeParseError {
795+
kind: DateTimeParseErrorKind::Invalid(_)
796+
}
797+
));
798+
}
799+
}
800+
#[test]
801+
fn parse_rfc3339_t_separator() {
802+
let test_cases = [
803+
("1985-04-12t23:20:50Z", AllowOffsets::OffsetsForbidden),
804+
("1985-04-12T23:20:50Z", AllowOffsets::OffsetsForbidden),
805+
("1985-04-12t23:20:50-02:00", AllowOffsets::OffsetsAllowed),
806+
("1985-04-12T23:20:50-02:00", AllowOffsets::OffsetsAllowed),
807+
];
808+
for (date, offset) in test_cases.into_iter() {
809+
let dt = rfc3339::parse(date, offset);
810+
assert!(
811+
dt.is_ok(),
812+
"failed to parse date: '{}' with error: {:?}",
813+
date,
814+
dt.err().unwrap()
815+
);
816+
}
817+
}
818+
776819
proptest! {
777820
#![proptest_config(ProptestConfig::with_cases(10000))]
778821

0 commit comments

Comments
 (0)