From d7cfb74df0f3dfa3fd1a94f6a1e71dcbae9606b3 Mon Sep 17 00:00:00 2001 From: Fahad Zubair Date: Wed, 4 Dec 2024 09:39:52 +0000 Subject: [PATCH] Only allow 'T' as a separator in RFC-3339 dates --- codegen-server-test/build.gradle.kts | 5 +-- rust-runtime/aws-smithy-types/Cargo.toml | 2 +- .../aws-smithy-types/src/date_time/format.rs | 43 +++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/codegen-server-test/build.gradle.kts b/codegen-server-test/build.gradle.kts index 5d9464b3a4..808d476058 100644 --- a/codegen-server-test/build.gradle.kts +++ b/codegen-server-test/build.gradle.kts @@ -21,8 +21,6 @@ val properties = PropertyRetriever(rootProject, project) val pluginName = "rust-server-codegen" val workingDirUnderBuildDir = "smithyprojections/codegen-server-test/" -val checkedInSmithyRuntimeLockfile = rootProject.projectDir.resolve("rust-runtime/Cargo.lock") - dependencies { implementation(project(":codegen-server")) implementation("software.amazon.smithy:smithy-aws-protocol-tests:$smithyVersion") @@ -106,10 +104,9 @@ val allCodegenTests = "../codegen-core/common-test-models".let { commonModels -> project.registerGenerateSmithyBuildTask(rootProject, pluginName, allCodegenTests) project.registerGenerateCargoWorkspaceTask(rootProject, pluginName, allCodegenTests, workingDirUnderBuildDir) project.registerGenerateCargoConfigTomlTask(layout.buildDirectory.dir(workingDirUnderBuildDir).get().asFile) -project.registerCopyCheckedInCargoLockfileTask(checkedInSmithyRuntimeLockfile, layout.buildDirectory.dir(workingDirUnderBuildDir).get().asFile) tasks["smithyBuild"].dependsOn("generateSmithyBuild") -tasks["assemble"].finalizedBy("generateCargoWorkspace", "copyCheckedInCargoLockfile", "generateCargoConfigToml") +tasks["assemble"].finalizedBy("generateCargoWorkspace", "generateCargoConfigToml") project.registerModifyMtimeTask() project.registerCargoCommandsTasks(layout.buildDirectory.dir(workingDirUnderBuildDir).get().asFile) diff --git a/rust-runtime/aws-smithy-types/Cargo.toml b/rust-runtime/aws-smithy-types/Cargo.toml index bf038a6464..e6093486c7 100644 --- a/rust-runtime/aws-smithy-types/Cargo.toml +++ b/rust-runtime/aws-smithy-types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aws-smithy-types" -version = "1.2.9" +version = "1.2.10" authors = [ "AWS Rust SDK Team ", "Russell Cohen ", diff --git a/rust-runtime/aws-smithy-types/src/date_time/format.rs b/rust-runtime/aws-smithy-types/src/date_time/format.rs index 86ffd42ac7..33e27f5369 100644 --- a/rust-runtime/aws-smithy-types/src/date_time/format.rs +++ b/rust-runtime/aws-smithy-types/src/date_time/format.rs @@ -407,6 +407,12 @@ pub(crate) mod rfc3339 { ) .into()); } + if s.len() > 10 && !matches!(s.as_bytes()[10], b'T' | b't') { + return Err(DateTimeParseErrorKind::Invalid( + "RFC-3339 only allows `T` as a separator for date-time values".into(), + ) + .into()); + } let date_time = OffsetDateTime::parse(s, &Rfc3339).map_err(|err| { DateTimeParseErrorKind::Invalid(format!("invalid RFC-3339 date-time: {}", err).into()) })?; @@ -773,6 +779,43 @@ mod tests { http_date_check_roundtrip(9999999999, 0); } + #[test] + fn parse_rfc3339_invalid_separator() { + let test_cases = [ + ("1985-04-12 23:20:50Z", AllowOffsets::OffsetsForbidden), + ("1985-04-12x23:20:50Z", AllowOffsets::OffsetsForbidden), + ("1985-04-12 23:20:50-02:00", AllowOffsets::OffsetsAllowed), + ("1985-04-12a23:20:50-02:00", AllowOffsets::OffsetsAllowed), + ]; + for (date, offset) in test_cases.into_iter() { + let dt = rfc3339::parse(date, offset); + assert!(matches!( + dt.unwrap_err(), + DateTimeParseError { + kind: DateTimeParseErrorKind::Invalid(_) + } + )); + } + } + #[test] + fn parse_rfc3339_t_separator() { + let test_cases = [ + ("1985-04-12t23:20:50Z", AllowOffsets::OffsetsForbidden), + ("1985-04-12T23:20:50Z", AllowOffsets::OffsetsForbidden), + ("1985-04-12t23:20:50-02:00", AllowOffsets::OffsetsAllowed), + ("1985-04-12T23:20:50-02:00", AllowOffsets::OffsetsAllowed), + ]; + for (date, offset) in test_cases.into_iter() { + let dt = rfc3339::parse(date, offset); + assert!( + dt.is_ok(), + "failed to parse date: '{}' with error: {:?}", + date, + dt.err().unwrap() + ); + } + } + proptest! { #![proptest_config(ProptestConfig::with_cases(10000))]