-
Notifications
You must be signed in to change notification settings - Fork 6
Description
In the Rust OpenFeature provider, the navigate_path function in provider.rs does not check whether the current path segment is the last one before returning a value. When a multi-segment path hits a non-struct value (like a string or number) at a non-terminal segment, the function returns that value as if the path was found instead of returning None.
The Go and Java providers both handle this correctly:
- Go returns
(nil, false)seeTestGetValueForPath_NonMapValueinprovider_test.go - Java throws a
TypeMismatchError
Example
Given a flag value:
{ "color": "red" }Resolving "my-flag.color.nonexistent" should fail, but instead it returns "red".
Root Cause
provider.rs lines 741–760:
fn navigate_path(value: Option<Struct>, path: &str) -> Option<Struct> {
let mut current = value?;
for part in path.split('.') {
let field = current.fields.get(part)?;
match &field.kind {
Some(value::Kind::StructValue(s)) => {
current = s.clone();
}
_ => {
// Comment says "if we're at the last part" but never checks
let mut fields = HashMap::new();
fields.insert(part.to_string(), field.clone());
return Some(Struct { fields });
}
}
}
Some(current)
}The _ arm returns immediately without checking if the current segment is the last in the path.
Suggested Fix
Only return the wrapped value when the current segment is the final one. Otherwise, return None:
_ => {
if parts_remaining == 0 {
let mut fields = HashMap::new();
fields.insert(part.to_string(), field.clone());
return Some(Struct { fields });
} else {
return None; // Can't traverse further through a non-struct value
}
}A test for this case should also be added, similar to Go's TestGetValueForPath_NonMapValue.