]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
hwdb: check that uppercase digits are used in modalias patterns 16476/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 17 Jul 2020 09:09:31 +0000 (11:09 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 17 Jul 2020 09:15:58 +0000 (11:15 +0200)
This is all confusing as hell, becuase in some places lowercase hexadecimal
digits are used, and in other places uppercase. This adds a check for the
most common case that we and others got wrong.

I tried to extend the general grammar in hwdb_grammar() to include this check,
but it quickly became very complicated and didn't seem to work properly. Doing
initial parsing with more general rules is easier and also seems to give better
error messages:

/home/zbyszek/src/systemd-work/build/../hwdb.d/60-autosuspend.hwdb: 3 match groups, 5 matches, 3 properties
Pattern 'v058fp9540*' is invalid: Expected W:(0123...), found 'f'  (at char 4), (line:1, col:5)

hwdb.d/parse_hwdb.py

index c9851ca64c9bd2eccd634a2a783e47173c599331..025133416f6e23c23ce64f1dfad9bc96f0d84a76 100755 (executable)
@@ -79,6 +79,9 @@ GENERAL_MATCHES = {'acpi',
                    'OUI',
                    }
 
+def upperhex_word(length):
+    return Word(nums + 'ABCDEF', exact=length)
+
 @lru_cache()
 def hwdb_grammar():
     ParserElement.setDefaultWhitespaceChars('')
@@ -180,8 +183,27 @@ def parse(fname):
         return []
     return [convert_properties(g) for g in parsed.GROUPS]
 
-def check_match_uniqueness(groups):
+def check_matches(groups):
     matches = sum((group[0] for group in groups), [])
+
+    # This is a partial check. The other cases could be also done, but those
+    # two are most commonly wrong.
+    grammars = { 'usb' : 'v' + upperhex_word(4) + Optional('p' + upperhex_word(4)),
+                 'pci' : 'v' + upperhex_word(8) + Optional('d' + upperhex_word(8)),
+    }
+
+    for match in matches:
+        prefix, rest = match.split(':', maxsplit=1)
+        gr = grammars.get(prefix)
+        if gr:
+            try:
+                gr.parseString(rest)
+            except ParseBaseException as e:
+                error('Pattern {!r} is invalid: {}', rest, e)
+                continue
+            if rest[-1] not in '*:':
+                error('pattern {} does not end with "*" or ":"', match)
+
     matches.sort()
     prev = None
     for match in matches:
@@ -256,7 +278,7 @@ if __name__ == '__main__':
     for fname in args:
         groups = parse(fname)
         print_summary(fname, groups)
-        check_match_uniqueness(groups)
+        check_matches(groups)
         check_properties(groups)
 
     sys.exit(ERROR)