Skip to content

Commit 4154fc2

Browse files
enhancement: stream name validation (#921)
removed existing stream name validation added validation to allow below special characters - Hyphen (-) Underscore (_) fixes: #917
1 parent 974929a commit 4154fc2

File tree

5 files changed

+15
-40
lines changed

5 files changed

+15
-40
lines changed

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

server/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mime = "0.3.17"
3434
### other dependencies
3535
anyhow = { version = "1.0", features = ["backtrace"] }
3636
argon2 = "0.5.0"
37-
async-trait = "0.1"
37+
async-trait = "0.1.82"
3838
base64 = "0.22.0"
3939
lazy_static = "1.4"
4040
bytes = "1.4"
@@ -71,7 +71,7 @@ prometheus = { version = "0.13", features = ["process"] }
7171
rand = "0.8"
7272
regex = "1.7.3"
7373
relative-path = { version = "1.7", features = ["serde"] }
74-
reqwest = { version = "0.11.27", default_features = false, features = [
74+
reqwest = { version = "0.11.27", default-features = false, features = [
7575
"rustls-tls",
7676
"json",
7777
] } # cannot update cause rustls is not latest `see rustls`
@@ -113,7 +113,7 @@ sha1_smol = { version = "1.0", features = ["std"] }
113113
static-files = "0.2"
114114
ureq = "2.6"
115115
vergen = { version = "8.1", features = ["build", "git", "cargo", "gitcl"] }
116-
zip = { version = "1.1.1", default_features = false, features = ["deflate"] }
116+
zip = { version = "1.1.1", default-features = false, features = ["deflate"] }
117117
url = "2.4.0"
118118
prost-build = "0.12.3"
119119

server/src/storage/s3.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ impl S3 {
322322
stream_json_check.push(task);
323323
}
324324

325-
stream_json_check.try_collect().await?;
325+
stream_json_check.try_collect::<()>().await?;
326326

327327
Ok(dirs.into_iter().map(|name| LogStream { name }).collect())
328328
}
@@ -633,7 +633,7 @@ impl ObjectStorage for S3 {
633633
stream_json_check.push(task);
634634
}
635635

636-
stream_json_check.try_collect().await?;
636+
stream_json_check.try_collect::<()>().await?;
637637

638638
Ok(dirs.into_iter().map(|name| LogStream { name }).collect())
639639
}

server/src/utils/arrow.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,8 @@ pub fn record_batches_to_json(records: &[&RecordBatch]) -> Result<Vec<Map<String
9898

9999
let buf = writer.into_inner();
100100

101-
let json_rows: Vec<Map<String, Value>> = match serde_json::from_reader(buf.as_slice()) {
102-
Ok(json) => json,
103-
Err(_) => vec![],
104-
};
101+
let json_rows: Vec<Map<String, Value>> =
102+
serde_json::from_reader(buf.as_slice()).unwrap_or_default();
105103

106104
Ok(json_rows)
107105
}

server/src/validator.rs

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const DENIED_NAMES: &[&str] = &[
3131
"select", "from", "where", "group", "by", "order", "limit", "offset", "join", "and",
3232
];
3333

34+
const ALLOWED_SPECIAL_CHARS: &[char] = &['-', '_'];
35+
3436
pub fn alert(alerts: &Alerts) -> Result<(), AlertValidationError> {
3537
let alert_name: Vec<&str> = alerts.alerts.iter().map(|a| a.name.as_str()).collect();
3638
let mut alert_name_dedup = alert_name.clone();
@@ -80,34 +82,15 @@ pub fn stream_name(stream_name: &str, stream_type: &str) -> Result<(), StreamNam
8082
return Err(StreamNameValidationError::EmptyName);
8183
}
8284

83-
if stream_name.chars().all(char::is_numeric) {
84-
return Err(StreamNameValidationError::NameNumericOnly(
85-
stream_name.to_owned(),
86-
));
87-
}
88-
89-
if stream_name.chars().next().unwrap().is_numeric() {
90-
return Err(StreamNameValidationError::NameCantStartWithNumber(
91-
stream_name.to_owned(),
92-
));
93-
}
94-
9585
for c in stream_name.chars() {
9686
match c {
9787
' ' => {
9888
return Err(StreamNameValidationError::NameWhiteSpace(
9989
stream_name.to_owned(),
10090
))
10191
}
102-
c if !c.is_alphanumeric() => {
103-
return Err(StreamNameValidationError::NameSpecialChar(
104-
stream_name.to_owned(),
105-
))
106-
}
107-
c if c.is_ascii_uppercase() => {
108-
return Err(StreamNameValidationError::NameUpperCase(
109-
stream_name.to_owned(),
110-
))
92+
c if !c.is_alphanumeric() && !ALLOWED_SPECIAL_CHARS.contains(&c) => {
93+
return Err(StreamNameValidationError::NameSpecialChar { c })
11194
}
11295
_ => {}
11396
}
@@ -182,16 +165,10 @@ pub mod error {
182165
pub enum StreamNameValidationError {
183166
#[error("Stream name cannot be empty")]
184167
EmptyName,
185-
#[error("Invalid stream name with numeric values only")]
186-
NameNumericOnly(String),
187-
#[error("Stream name cannot start with a number")]
188-
NameCantStartWithNumber(String),
189168
#[error("Stream name cannot contain whitespace")]
190169
NameWhiteSpace(String),
191-
#[error("Stream name cannot contain special characters")]
192-
NameSpecialChar(String),
193-
#[error("Uppercase character in stream name")]
194-
NameUpperCase(String),
170+
#[error("Stream name cannot contain special character: {c}")]
171+
NameSpecialChar { c: char },
195172
#[error("SQL keyword cannot be used as stream name")]
196173
SQLKeyword(String),
197174
#[error("The stream {0} is reserved for internal use and cannot be used for user defined streams")]

0 commit comments

Comments
 (0)