Browse Source

Prohibit using char without explicit sign modifier

Related to #79
tags/v0.0.1
Joost Rijneveld 5 years ago
parent
commit
17fc0da52e
No known key found for this signature in database GPG Key ID: A4FE39CF49CBC553
4 changed files with 67 additions and 0 deletions
  1. +3
    -0
      .gitmodules
  2. +1
    -0
      requirements.txt
  3. +1
    -0
      test/pycparser
  4. +62
    -0
      test/test_char.py

+ 3
- 0
.gitmodules View File

@@ -0,0 +1,3 @@
[submodule "test/pycparser"]
path = test/pycparser
url = https://github.com/eliben/pycparser.git

+ 1
- 0
requirements.txt View File

@@ -1,3 +1,4 @@
PyYAML
nose
rednose
pycparser

+ 1
- 0
test/pycparser

@@ -0,0 +1 @@
Subproject commit e1a1d737be66308b633215fa26ac5ed30e890103

+ 62
- 0
test/test_char.py View File

@@ -0,0 +1,62 @@

"""
Checks that the implementation does not make use of the `char` type.
This is ambiguous; compilers can freely choose `signed` or `unsigned` char.
"""

import pqclean
import pycparser
import os


def test_char():
for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations:
yield check_char, implementation


def walk_tree(ast):
if type(ast) is pycparser.c_ast.IdentifierType:
if ast.names == ['char']:
yield ast

for (_, child) in ast.children():
yield from walk_tree(child) # recursively yield prohibited nodes


def check_char(implementation):
errors = []
for fname in os.listdir(implementation.path()):
if not fname.endswith(".c"):
continue
tdir, _ = os.path.split(os.path.realpath(__file__))
ast = pycparser.parse_file(
os.path.join(implementation.path(), fname),
use_cpp=True,
cpp_args=[
'-nostdinc', # pycparser cannot deal with e.g. __attribute__
'-I{}'.format(os.path.join(tdir, "../common")),
# necessary to mock e.g. <stdint.h>
'-I{}'.format(
os.path.join(tdir, 'pycparser/utils/fake_libc_include')),
]
)
for node in walk_tree(ast):
# flatten nodes to a string to easily enforce uniqueness
err = "\n at {c.file}:{c.line}:{c.column}".format(c=node.coord)
if err not in errors:
errors.append(err)
if errors:
raise AssertionError(
"Prohibited use of char without explicit signed/unsigned" +
"".join(errors)
)


if __name__ == '__main__':
try:
import nose2
nose2.main()
except ImportError:
import nose
nose.runmodule()

Loading…
Cancel
Save