Skip to content

Commit 502d8d5

Browse files
authored
fix: stack-overflow safeguard for find_local_member (#1440)
* fix: add safe-guard against stack-overflow when 'find_local_member' calls 'find_member' recursively * extend 'pou_with_two_types_not_considered_recursive' test
1 parent 83abd33 commit 502d8d5

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

src/index.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,21 +1465,30 @@ impl Index {
14651465
&self,
14661466
container_name: &str,
14671467
variable_name: &str,
1468+
) -> Option<&VariableIndexEntry> {
1469+
self.find_local_member_recursive(container_name, variable_name, &mut FxHashSet::default())
1470+
}
1471+
1472+
fn find_local_member_recursive(
1473+
&self,
1474+
container_name: &str,
1475+
variable_name: &str,
1476+
seen: &mut FxHashSet<String>,
14681477
) -> Option<&VariableIndexEntry> {
14691478
self.type_index
14701479
.find_type(container_name)
14711480
.and_then(|it| it.find_member(variable_name))
14721481
.or(self.find_enum_variant_in_pou(container_name, variable_name))
1473-
// underlying type of an `ACTION`
1482+
// underlying type of an `ACTION` or `METHOD`
14741483
.or(container_name
14751484
.rfind('.')
14761485
.map(|p| &container_name[..p])
1477-
.and_then(|qualifier| self.find_member(qualifier, variable_name)))
1486+
.and_then(|qualifier| self.find_member_recursive(qualifier, variable_name, seen)))
14781487
// 'self' instance of a POUs init function
14791488
.or(container_name
14801489
.rfind("__init_")
14811490
.map(|p| &container_name[p + 1..])
1482-
.and_then(|qualifier| self.find_member(qualifier, variable_name)))
1491+
.and_then(|qualifier| self.find_member_recursive(qualifier, variable_name, seen)))
14831492
}
14841493

14851494
/// Searches for variable name in the given container, if not found, attempts to search for it in super classes
@@ -1491,13 +1500,13 @@ impl Index {
14911500
&'b self,
14921501
container_name: &str,
14931502
variable_name: &str,
1494-
seen: &mut FxHashSet<&'b str>,
1503+
seen: &mut FxHashSet<String>,
14951504
) -> Option<&'b VariableIndexEntry> {
14961505
// Find pou in index
1497-
self.find_local_member(container_name, variable_name)
1506+
self.find_local_member_recursive(container_name, variable_name, seen)
14981507
.or_else(|| {
14991508
if let Some(class) = self.find_pou(container_name).and_then(|it| it.get_super_class()) {
1500-
if !seen.insert(class) {
1509+
if !seen.insert(class.into()) {
15011510
return None;
15021511
}
15031512
self.find_member_recursive(class, variable_name, seen).filter(|it| !(it.is_temp()))

src/index/tests/index_tests.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2273,11 +2273,19 @@ fn pou_with_two_types_not_considered_recursive() {
22732273
x : fb;
22742274
y : fb;
22752275
END_VAR
2276-
END_PROGRAM",
2276+
METHOD x : fb
2277+
END_METHOD
2278+
END_PROGRAM
2279+
2280+
ACTION p.y
2281+
END_ACTION",
22772282
);
22782283

22792284
let pou_type = index.find_pou_type("p").unwrap();
22802285
assert_eq!(pou_type.get_type_information().get_size(&index).unwrap().bits(), 64);
2286+
2287+
assert!(index.find_local_member("p", "x").is_some());
2288+
assert!(index.find_local_member("p", "y").is_some());
22812289
}
22822290

22832291
#[test]

0 commit comments

Comments
 (0)