Skip to content

Commit ffa1515

Browse files
mbolivar-nordiccfriedt
authored andcommitted
dtlib: fix issue which allowed invalid node names
Node names are subject to the rules in table 2.1 of the devicetree specification v0.3, while properties are subject to rules in table 2.2. These rules mean that some property names are invalid node names. However, the same regular expression is being used to validate the names of nodes and properties in dtlib. This leads to invalid node names being allowed to pass. Fix this issue by moving the node name handling code to the Node constructor and checking against the characters in table 2.1. The test cases claim that the existing behavior matches dtc. I can't reproduce that. I get errors when I use invalid characters (like "?") in a node name. For example: foo.dts:3.8-11: ERROR (node_name_chars): /node?: Bad character '?' in node name Try to make the dtlib error message reminiscent of that. Signed-off-by: Martí Bolívar <[email protected]>
1 parent fff818b commit ffa1515

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

scripts/dts/python-devicetree/src/devicetree/dtlib.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import errno
1818
import os
1919
import re
20+
import string
2021
import sys
2122
import textwrap
2223
from typing import Any, Dict, Iterable, List, \
@@ -92,6 +93,14 @@ def __init__(self, name: str, parent: Optional['Node'], dt: 'DT'):
9293
self.parent = parent
9394
self.dt = dt
9495

96+
if name.count("@") > 1:
97+
dt._parse_error("multiple '@' in node name")
98+
if not name == "/":
99+
for char in name:
100+
if char not in _nodename_chars:
101+
dt._parse_error(f"{self.path}: bad character '{char}' "
102+
"in node name")
103+
95104
self.props: Dict[str, 'Property'] = collections.OrderedDict()
96105
self.nodes: Dict[str, 'Node'] = collections.OrderedDict()
97106
self.labels: List[str] = []
@@ -950,9 +959,6 @@ def _parse_node(self, node):
950959
if self._peek_token().val == "{":
951960
# '<tok> { ...', expect node
952961

953-
if tok.val.count("@") > 1:
954-
self._parse_error("multiple '@' in node name")
955-
956962
# Fetch the existing node if it already exists. This
957963
# happens when overriding nodes.
958964
child = node.nodes.get(tok.val) or \
@@ -1925,6 +1931,9 @@ def _err(msg) -> NoReturn:
19251931
# names that would clash with other stuff
19261932
_propnodename_re = re.compile(r"\\?([a-zA-Z0-9,._+*#?@-]+)")
19271933

1934+
# Node names are more restrictive than property names.
1935+
_nodename_chars = set(string.ascii_letters + string.digits + ',._+-@')
1936+
19281937
# Misc. tokens that are tried after a property/node name. This is important, as
19291938
# there's overlap with the allowed characters in names.
19301939
_misc_re = re.compile(

scripts/dts/python-devicetree/tests/test_dtlib.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ def temporary_chdir(dirname):
100100
finally:
101101
os.chdir(here)
102102

103+
def test_invalid_nodenames():
104+
# Regression test that verifies node names are not matched against
105+
# the more permissive set of rules used for property names.
106+
107+
verify_error_endswith("""
108+
/dts-v1/;
109+
/ { node? {}; };
110+
""",
111+
"/node?: bad character '?' in node name")
112+
103113
def test_cell_parsing():
104114
'''Miscellaneous properties containing zero or more cells'''
105115

@@ -2107,15 +2117,12 @@ def test_reprs():
21072117
def test_names():
21082118
'''Tests for node/property names.'''
21092119

2110-
# The C tools disallow '@' in property names, but otherwise accept the same
2111-
# characters in node and property names. Emulate that instead of the DT spec
2112-
# (v0.2), which gives different characters for nodes and properties.
21132120
verify_parse(r"""
21142121
/dts-v1/;
21152122
21162123
/ {
21172124
// A leading \ is accepted but ignored in node/propert names
2118-
\aA0,._+*#?- = &_, &{/aA0,._+*#?@-};
2125+
\aA0,._+*#?- = &_, &{/aA0,._+@-};
21192126
21202127
// Names that overlap with operators and integer literals
21212128
@@ -2126,7 +2133,8 @@ def test_names():
21262133
0 = [ 04 ];
21272134
0x123 = [ 05 ];
21282135
2129-
_: \aA0,._+*#?@- {
2136+
// Node names are more restrictive than property names.
2137+
_: \aA0,._+@- {
21302138
};
21312139
21322140
0 {
@@ -2137,14 +2145,14 @@ def test_names():
21372145
/dts-v1/;
21382146
21392147
/ {
2140-
aA0,._+*#?- = &_, &{/aA0,._+*#?@-};
2148+
aA0,._+*#?- = &_, &{/aA0,._+@-};
21412149
+ = [ 00 ];
21422150
* = [ 02 ];
21432151
- = [ 01 ];
21442152
? = [ 03 ];
21452153
0 = [ 04 ];
21462154
0x123 = [ 05 ];
2147-
_: aA0,._+*#?@- {
2155+
_: aA0,._+@- {
21482156
};
21492157
0 {
21502158
};

0 commit comments

Comments
 (0)