Skip to content

Commit 0401324

Browse files
Enforce activity name validation and handle reserved formats
Added validation to disallow empty activity names and prevent usage of the reserved "Activity-{number}" format. Updated logic to ensure unique system-generated names do not conflict with user-specified or reserved names. Introduced the `regex` crate to facilitate pattern matching.
1 parent 3be767e commit 0401324

File tree

4 files changed

+33
-10
lines changed

4 files changed

+33
-10
lines changed

Cargo.lock

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

sim-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ futures = "0.3.30"
2727
console-subscriber = { version = "0.4.0", optional = true}
2828
tokio-util = { version = "0.7.13", features = ["rt"] }
2929
openssl = { version = "0.10", features = ["vendored"] }
30+
regex = "1.11.1"
3031

3132
[features]
3233
dev = ["console-subscriber"]

sim-cli/src/parsing.rs

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use std::path::PathBuf;
1515
use std::sync::Arc;
1616
use tokio::sync::Mutex;
1717
use tokio_util::task::TaskTracker;
18+
use regex::Regex;
1819

1920
/// The default directory where the simulation files are stored and where the results will be written to.
2021
pub const DEFAULT_DATA_DIR: &str = ".";
@@ -268,8 +269,24 @@ async fn validate_activities(
268269
for (index, act) in activity.into_iter().enumerate() {
269270
// Generate a default name if one is not provided
270271
let name = match &act.name {
271-
Some(name) if !name.is_empty() => {
272-
// Optionally check for duplicate names
272+
Some(name) => {
273+
// Disallow empty names
274+
if name.is_empty() {
275+
return Err(LightningError::ValidationError(
276+
"activity name cannot be empty".to_string()
277+
));
278+
}
279+
280+
// Disallow users from using the reserved "Activity-x" format
281+
let reserved_pattern = Regex::new(r"^Activity-\d+$").unwrap();
282+
if reserved_pattern.is_match(name) {
283+
return Err(LightningError::ValidationError(format!(
284+
"'{}' uses a reserved name format. 'Activity-{{number}}' is reserved for system use.",
285+
name
286+
)));
287+
}
288+
289+
// Check for duplicate names
273290
if !activity_names.insert(name.clone()) {
274291
return Err(LightningError::ValidationError(format!(
275292
"duplicate activity name: {}",
@@ -278,15 +295,19 @@ async fn validate_activities(
278295
}
279296
name.clone()
280297
},
281-
_ => {
282-
let default_name = format!("Activity-{}", index);
283-
// Ensure the default name doesn't conflict with an explicit name
284-
let mut unique_name = default_name.clone();
285-
let mut counter = 1;
286-
while !activity_names.insert(unique_name.clone()) {
287-
unique_name = format!("{}-{}", default_name, counter);
298+
None => {
299+
// Generate a unique system name
300+
let mut counter = index;
301+
let mut unique_name;
302+
303+
loop {
304+
unique_name = format!("Activity-{}", counter);
305+
if activity_names.insert(unique_name.clone()) {
306+
break;
307+
}
288308
counter += 1;
289309
}
310+
290311
unique_name
291312
},
292313
};

simln-lib/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ pub type Interval = ValueOrRange<u16>;
164164
/// This is constructed during activity validation and passed along to the [Simulation].
165165
#[derive(Debug, Clone)]
166166
pub struct ActivityDefinition {
167-
/// Optional name/identifier for this activity
167+
/// Optional identifier for this activity.
168168
pub name: Option<String>,
169169
/// The source of the payment.
170170
pub source: NodeInfo,

0 commit comments

Comments
 (0)