This is an automated email from the ASF dual-hosted git repository.
mgrigorov pushed a commit to branch branch-1.11
in repository https://gitbox.apache.org/repos/asf/avro.git
The following commit(s) were added to refs/heads/branch-1.11 by this push:
new 9de1895ff AVRO-3827: [Rust] Disallow duplicate field names (#2433)
9de1895ff is described below
commit 9de1895ffb74f927213ec604f5f62bbed81d4754
Author: Kousuke Saruta <[email protected]>
AuthorDate: Thu Aug 10 16:28:57 2023 +0900
AVRO-3827: [Rust] Disallow duplicate field names (#2433)
* AVRO-3827: [Rust] Disallow duplicate field names
* Reuse BTreeMap.
* Use the returned Option.
(cherry picked from commit 3deb73c840fe2b966cda0094f8114f47cf6b131e)
---
lang/rust/avro/src/error.rs | 3 ++
lang/rust/avro/src/schema.rs | 71 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/lang/rust/avro/src/error.rs b/lang/rust/avro/src/error.rs
index 661223313..c0c279bfa 100644
--- a/lang/rust/avro/src/error.rs
+++ b/lang/rust/avro/src/error.rs
@@ -307,6 +307,9 @@ pub enum Error {
#[error("Invalid field name {0}")]
FieldName(String),
+ #[error("Duplicate field name {0}")]
+ FieldNameDuplicate(String),
+
#[error("Invalid schema name {0}. It must match the regex '{1}'")]
InvalidSchemaName(String, &'static str),
diff --git a/lang/rust/avro/src/schema.rs b/lang/rust/avro/src/schema.rs
index 45333cf37..7f9a8198d 100644
--- a/lang/rust/avro/src/schema.rs
+++ b/lang/rust/avro/src/schema.rs
@@ -1441,7 +1441,9 @@ impl Parser {
})?;
for field in &fields {
- lookup.insert(field.name.clone(), field.position);
+ if let Some(_old) = lookup.insert(field.name.clone(),
field.position) {
+ return Err(Error::FieldNameDuplicate(field.name.clone()));
+ }
if let Some(ref field_aliases) = field.aliases {
for alias in field_aliases {
@@ -5026,4 +5028,71 @@ mod tests {
other => Err(format!("Expected Error::FieldName, got
{other:?}").into()),
}
}
+
+ #[test]
+ fn test_avro_3827_disallow_duplicate_field_names() -> TestResult {
+ let schema_str = r#"
+ {
+ "name": "my_schema",
+ "type": "record",
+ "fields": [
+ {
+ "name": "f1",
+ "type": {
+ "name": "a",
+ "type": "record",
+ "fields": []
+ }
+ }, {
+ "name": "f1",
+ "type": {
+ "name": "b",
+ "type": "record",
+ "fields": []
+ }
+ }
+ ]
+ }
+ "#;
+
+ match Schema::parse_str(schema_str) {
+ Err(Error::FieldNameDuplicate(_)) => (),
+ other => {
+ return Err(format!("Expected Error::FieldNameDuplicate, got
{other:?}").into())
+ }
+ };
+
+ let schema_str = r#"
+ {
+ "name": "my_schema",
+ "type": "record",
+ "fields": [
+ {
+ "name": "f1",
+ "type": {
+ "name": "a",
+ "type": "record",
+ "fields": [
+ {
+ "name": "f1",
+ "type": {
+ "name": "b",
+ "type": "record",
+ "fields": []
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ "#;
+
+ let expected =
r#"{"name":"my_schema","type":"record","fields":[{"name":"f1","type":{"name":"a","type":"record","fields":[{"name":"f1","type":{"name":"b","type":"record","fields":[]}}]}}]}"#;
+ let schema = Schema::parse_str(schema_str)?;
+ let canonical_form = schema.canonical_form();
+ assert_eq!(canonical_form, expected);
+
+ Ok(())
+ }
}