Reference implementations of PQC
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

72 lines
2.0 KiB

  1. """
  2. Checks that the implementation does not make use of the `char` type.
  3. This is ambiguous; compilers can freely choose `signed` or `unsigned` char.
  4. """
  5. import os
  6. import pytest
  7. import helpers
  8. import pqclean
  9. import pycparser
  10. def setup_module():
  11. if not(os.path.exists(os.path.join('pycparser', '.git'))):
  12. print("Please run `git submodule update --init`")
  13. def walk_tree(ast):
  14. if type(ast) is pycparser.c_ast.IdentifierType:
  15. if ast.names == ['char']:
  16. yield ast
  17. for (_, child) in ast.children():
  18. yield from walk_tree(child) # recursively yield prohibited nodes
  19. @pytest.mark.parametrize(
  20. 'implementation',
  21. pqclean.Scheme.all_implementations(),
  22. ids=str,
  23. )
  24. @helpers.filtered_test
  25. @helpers.skip_windows()
  26. def test_char(implementation):
  27. errors = []
  28. for fname in os.listdir(implementation.path()):
  29. if not fname.endswith(".c"):
  30. continue
  31. tdir, _ = os.path.split(os.path.realpath(__file__))
  32. ast = pycparser.parse_file(
  33. os.path.join(implementation.path(), fname),
  34. use_cpp=True,
  35. cpp_path='cc', # not all platforms link cpp correctly; cc -E works
  36. cpp_args=[
  37. '-E',
  38. '-std=c99',
  39. '-nostdinc', # pycparser cannot deal with e.g. __attribute__
  40. '-I{}'.format(os.path.join(tdir, "../common")),
  41. # necessary to mock e.g. <stdint.h>
  42. '-I{}'.format(
  43. os.path.join(tdir, 'pycparser/utils/fake_libc_include')),
  44. ]
  45. )
  46. for node in walk_tree(ast):
  47. # flatten nodes to a string to easily enforce uniqueness
  48. err = "\n at {c.file}:{c.line}:{c.column}".format(c=node.coord)
  49. if err not in errors:
  50. errors.append(err)
  51. if errors:
  52. raise AssertionError(
  53. "Prohibited use of char without explicit signed/unsigned" +
  54. "".join(errors)
  55. )
  56. if __name__ == "__main__":
  57. import sys
  58. pytest.main(sys.argv)