diff --git a/.github/workflows/build_wheel.yml b/.github/workflows/build_wheel.yml new file mode 100644 index 0000000..cb0224a --- /dev/null +++ b/.github/workflows/build_wheel.yml @@ -0,0 +1,42 @@ +# Build wheel from source using tox. +name: build_wheel +on: [push, pull_request] +permissions: read-all +jobs: + build_wheel: + runs-on: ubuntu-22.04 + strategy: + matrix: + include: + - python-version: '3.7' + toxenv: 'py37' + - python-version: '3.8' + toxenv: 'py38' + - python-version: '3.9' + toxenv: 'py39' + - python-version: '3.10' + toxenv: 'py310' + - python-version: '3.11' + toxenv: 'py311' + - python-version: '3.12' + toxenv: 'py312' + steps: + - uses: actions/checkout@v3 + - name: Install build dependencies + run: | + sudo add-apt-repository universe && + sudo add-apt-repository -y ppa:deadsnakes/ppa && + sudo apt-get update && + sudo apt-get install -y autoconf automake autopoint build-essential git libtool pkg-config python${{ matrix.python-version }} python${{ matrix.python-version }}-dev python${{ matrix.python-version }}-venv python3-distutils python3-pip python3-setuptools + - name: Install tox + run: | + python3 -m pip install tox + - name: Download test data + run: | + if test -x "synctestdata.sh"; then ./synctestdata.sh; fi + - name: Prepare build + run: | + ./synclibs.sh --use-head && ./autogen.sh && ./configure + - name: Build Python wheel + run: | + tox -e${{ matrix.toxenv }} diff --git a/.gitignore b/.gitignore index a5716d2..6275278 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Files to ignore by git # -# Version: 20230405 +# Version: 20230926 # Generic auto-generated build files *~ @@ -25,10 +25,13 @@ *.swp *.Tpo *.trs +*.whl /*.egg-info/ +__pycache__ .deps .dirstamp .libs +.tox INSTALL Makefile Makefile.bcc @@ -125,6 +128,7 @@ stamp-h[1-9] /libhmac/libhmac.rc /libhmac/libhmac_definitions.h /pyhmac-python[23]/*.[ch] +/setup.cfg /hmactools/*.exe /hmactools/hmacsum /tests/*.exe diff --git a/Makefile.am b/Makefile.am index d4ba0f6..439f944 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,6 +43,9 @@ PKGCONFIG_FILES = \ libhmac.pc.in SETUP_PY_FILES = \ + pyproject.toml \ + setup.cfg \ + setup.cfg.in \ setup.py SPEC_FILES = \ diff --git a/appveyor.yml b/appveyor.yml index 5e4a00d..426a9e7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -183,7 +183,7 @@ environment: install: - cmd: if [%BUILD_ENVIRONMENT%]==[msbuild] ( git clone https://github.com/libyal/vstools.git ..\vstools ) -- sh: if test ${BUILD_ENVIRONMENT} = "python-tox" || test ${BUILD_ENVIRONMENT} = "xcode"; then brew update -q; fi +- sh: if test ${BUILD_ENVIRONMENT} = "python-tox" || test ${BUILD_ENVIRONMENT} = "xcode"; then brew update-reset && brew update -q; fi - sh: if test ${BUILD_ENVIRONMENT} = "python-tox" || test ${BUILD_ENVIRONMENT} = "xcode"; then brew install -q gettext gnu-sed || true; fi - sh: if test ${BUILD_ENVIRONMENT} = "python-tox"; then brew install -q python@${PYTHON_VERSION} tox twine-pypi || true; fi - cmd: if [%BUILD_ENVIRONMENT%]==[python] ( @@ -193,7 +193,7 @@ install: - cmd: if [%BUILD_ENVIRONMENT%]==[cygwin64] ( C:\cygwin64\setup-x86_64.exe -qgnNdO -l C:\cygwin64\var\cache\setup -R c:\cygwin64 -s http://cygwin.mirror.constant.com -P gettext-devel -P wget -P zlib-devel -P libssl-devel -P python3-devel ) - cmd: if [%BUILD_ENVIRONMENT%]==[mingw-w64] ( - C:\msys64\usr\bin\pacman -S --noconfirm --needed autoconf automake gcc gettext-devel libtool make ) + C:\msys64\usr\bin\pacman -S --noconfirm --needed autoconf automake gettext-devel libtool make mingw-w64-x86_64-gcc ) - ps: If ( ( "cygwin64-gcc-no-optimization", "mingw-w64-gcc-no-optimization" ).Contains( $env:TARGET ) ) { $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe -Outfile ..\codecov.exe } diff --git a/configure.ac b/configure.ac index 36162f0..0a76078 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ([2.71]) AC_INIT( [libhmac], - [20230630], + [20231005], [joachim.metz@gmail.com]) AC_CONFIG_SRCDIR( @@ -179,6 +179,7 @@ AC_CONFIG_FILES([dpkg/changelog]) AC_CONFIG_FILES([libhmac/libhmac.rc]) AC_CONFIG_FILES([libhmac.pc]) AC_CONFIG_FILES([libhmac.spec]) +AC_CONFIG_FILES([setup.cfg]) dnl Generate a source configuration file AC_CONFIG_HEADERS([common/config.h]) diff --git a/libhmac.spec.in b/libhmac.spec.in index 354e5f7..0a85a65 100644 --- a/libhmac.spec.in +++ b/libhmac.spec.in @@ -3,10 +3,9 @@ Version: @VERSION@ Release: 1 Summary: Library to support various Hash-based Message Authentication Codes (HMAC) Group: System Environment/Libraries -License: LGPLv3+ +License: LGPL-3.0-or-later Source: %{name}-%{version}.tar.gz URL: https://github.com/libyal/libhmac -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @libhmac_spec_requires@ @ax_libcerror_spec_requires@ @ax_libcrypto_spec_requires@ @ax_libcthreads_spec_requires@ BuildRequires: gcc @ax_libcerror_spec_build_requires@ @ax_libcrypto_spec_build_requires@ @ax_libcthreads_spec_build_requires@ @@ -66,19 +65,16 @@ rm -rf %{buildroot} %postun -p /sbin/ldconfig %files -n libhmac -%defattr(644,root,root,755) %license COPYING COPYING.LESSER %doc AUTHORS README -%attr(755,root,root) %{_libdir}/*.so.* +%{_libdir}/*.so.* %files -n libhmac-static -%defattr(644,root,root,755) %license COPYING COPYING.LESSER %doc AUTHORS README -%attr(755,root,root) %{_libdir}/*.a +%{_libdir}/*.a %files -n libhmac-devel -%defattr(644,root,root,755) %license COPYING COPYING.LESSER %doc AUTHORS README %{_libdir}/*.so @@ -87,17 +83,15 @@ rm -rf %{buildroot} %{_mandir}/man3/* %files -n libhmac-python3 -%defattr(644,root,root,755) %license COPYING COPYING.LESSER %doc AUTHORS README %{_libdir}/python3*/site-packages/*.a %{_libdir}/python3*/site-packages/*.so %files -n libhmac-tools -%defattr(644,root,root,755) %license COPYING COPYING.LESSER %doc AUTHORS README -%attr(755,root,root) %{_bindir}/* +%{_bindir}/* %{_mandir}/man1/* %changelog diff --git a/libhmac/libhmac_md5_context.c b/libhmac/libhmac_md5_context.c index 58f59e8..bd42264 100644 --- a/libhmac/libhmac_md5_context.c +++ b/libhmac/libhmac_md5_context.c @@ -1088,24 +1088,14 @@ int libhmac_md5_context_finalize( return( -1 ); } - if( hash_size > (size_t) UINT_MAX ) + if( ( hash_size < (size_t) LIBHMAC_MD5_HASH_SIZE ) + || ( hash_size > (size_t) UINT_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid hash size value exceeds maximum.", - function ); - - return( -1 ); - } - if( hash_size < (size_t) LIBHMAC_MD5_HASH_SIZE ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid hash size value too small.", + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid hash size value out of bounds.", function ); return( -1 ); diff --git a/libhmac/libhmac_sha1_context.c b/libhmac/libhmac_sha1_context.c index 19d2638..c78e032 100644 --- a/libhmac/libhmac_sha1_context.c +++ b/libhmac/libhmac_sha1_context.c @@ -1161,24 +1161,14 @@ int libhmac_sha1_context_finalize( return( -1 ); } - if( hash_size > (size_t) UINT_MAX ) + if( ( hash_size < (size_t) LIBHMAC_SHA1_HASH_SIZE ) + || ( hash_size > (size_t) UINT_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid hash size value exceeds maximum.", - function ); - - return( -1 ); - } - if( hash_size < (size_t) LIBHMAC_SHA1_HASH_SIZE ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid hash size value too small.", + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid hash size value out of bounds.", function ); return( -1 ); diff --git a/libhmac/libhmac_sha224_context.c b/libhmac/libhmac_sha224_context.c index 4ea42fb..ed112d0 100644 --- a/libhmac/libhmac_sha224_context.c +++ b/libhmac/libhmac_sha224_context.c @@ -1120,24 +1120,14 @@ int libhmac_sha224_context_finalize( return( -1 ); } - if( hash_size > (size_t) UINT_MAX ) + if( ( hash_size < (size_t) LIBHMAC_SHA224_HASH_SIZE ) + || ( hash_size > (size_t) UINT_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid hash size value exceeds maximum.", - function ); - - return( -1 ); - } - if( hash_size < (size_t) LIBHMAC_SHA224_HASH_SIZE ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid hash size value too small.", + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid hash size value out of bounds.", function ); return( -1 ); diff --git a/libhmac/libhmac_sha256_context.c b/libhmac/libhmac_sha256_context.c index 50288fd..2f03b9d 100644 --- a/libhmac/libhmac_sha256_context.c +++ b/libhmac/libhmac_sha256_context.c @@ -1120,24 +1120,14 @@ int libhmac_sha256_context_finalize( return( -1 ); } - if( hash_size > (size_t) UINT_MAX ) + if( ( hash_size < (size_t) LIBHMAC_SHA256_HASH_SIZE ) + || ( hash_size > (size_t) UINT_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid hash size value exceeds maximum.", - function ); - - return( -1 ); - } - if( hash_size < (size_t) LIBHMAC_SHA256_HASH_SIZE ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid hash size value too small.", + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid hash size value out of bounds.", function ); return( -1 ); diff --git a/libhmac/libhmac_sha512_context.c b/libhmac/libhmac_sha512_context.c index 0c50049..086cdf1 100644 --- a/libhmac/libhmac_sha512_context.c +++ b/libhmac/libhmac_sha512_context.c @@ -1156,24 +1156,14 @@ int libhmac_sha512_context_finalize( return( -1 ); } - if( hash_size > (size_t) UINT_MAX ) + if( ( hash_size < (size_t) LIBHMAC_SHA512_HASH_SIZE ) + || ( hash_size > (size_t) UINT_MAX ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid hash size value exceeds maximum.", - function ); - - return( -1 ); - } - if( hash_size < (size_t) LIBHMAC_SHA512_HASH_SIZE ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid hash size value too small.", + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid hash size value out of bounds.", function ); return( -1 ); diff --git a/m4/libuna.m4 b/m4/libuna.m4 index 8357c3d..4462a91 100644 --- a/m4/libuna.m4 +++ b/m4/libuna.m4 @@ -1,6 +1,6 @@ dnl Checks for libuna or required headers and functions dnl -dnl Version: 20210801 +dnl Version: 20230702 dnl Function to detect if a specific libuna definition is available. AC_DEFUN([AX_LIBUNA_CHECK_DEFINITION], @@ -43,7 +43,7 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], [test "x$cross_compiling" != "xyes" && test "x$PKGCONFIG" != "x"], [PKG_CHECK_MODULES( [libuna], - [libuna >= 20210801], + [libuna >= 20230702], [ac_cv_libuna=yes], [ac_cv_libuna=check]) ]) @@ -225,6 +225,138 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + dnl Unicode character functions + AC_CHECK_LIB( + una, + libuna_unicode_character_size_to_byte_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_byte_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_byte_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_size_to_ucs2, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_ucs2, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_ucs2, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_size_to_ucs4, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_ucs4, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_ucs4, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_utf7_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_utf7_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_size_to_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_size_to_utf8_rfc2279, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_utf8_rfc2279, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_utf8_rfc2279, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_size_to_utf16, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_utf16, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_utf16, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_utf16_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_utf16_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_utf32, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_utf32, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_from_utf32_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_unicode_character_copy_to_utf32_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + dnl UTF-8 stream functions AC_CHECK_LIB( una, @@ -337,6 +469,11 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf8_string_with_index_copy_from_byte_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf8_string_compare_with_byte_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) AC_CHECK_LIB( una, libuna_utf8_string_size_from_utf7_stream, @@ -352,6 +489,11 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf8_string_with_index_copy_from_utf7_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf8_string_compare_with_utf7_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) AC_CHECK_LIB( una, libuna_utf8_string_size_from_utf8_stream, @@ -369,47 +511,47 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_size_from_utf16_stream, + libuna_utf8_string_compare_with_utf8_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_copy_from_utf16_stream, + libuna_utf8_string_size_from_utf16, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_with_index_copy_from_utf16_stream, + libuna_utf8_string_copy_from_utf16, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_size_from_utf32_stream, + libuna_utf8_string_with_index_copy_from_utf16, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_copy_from_utf32_stream, + libuna_utf8_string_compare_with_utf16, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_with_index_copy_from_utf32_stream, + libuna_utf8_string_size_from_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_size_from_utf16, + libuna_utf8_string_copy_from_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_copy_from_utf16, + libuna_utf8_string_with_index_copy_from_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf8_string_with_index_copy_from_utf16, + libuna_utf8_string_compare_with_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( @@ -427,6 +569,31 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf8_string_with_index_copy_from_utf32, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf8_string_compare_with_utf32, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf8_string_size_from_utf32_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf8_string_copy_from_utf32_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf8_string_with_index_copy_from_utf32_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf8_string_compare_with_utf32_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) AC_CHECK_LIB( una, libuna_utf8_string_size_from_scsu_stream, @@ -459,6 +626,11 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf16_string_with_index_copy_from_byte_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf16_string_compare_with_byte_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) AC_CHECK_LIB( una, libuna_utf16_string_size_from_utf7_stream, @@ -474,6 +646,27 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf16_string_with_index_copy_from_utf7_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf16_string_compare_with_utf7_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf16_string_size_from_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf16_string_copy_from_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf16_string_with_index_copy_from_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + dnl libuna_utf16_string_compare_with_utf8 is implemented by libuna_utf8_string_compare_with_utf16 AC_CHECK_LIB( una, libuna_utf16_string_size_from_utf8_stream, @@ -489,6 +682,11 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf16_string_with_index_copy_from_utf8_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf16_string_compare_with_utf8_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) AC_CHECK_LIB( una, libuna_utf16_string_size_from_utf16_stream, @@ -506,47 +704,47 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_size_from_utf32_stream, + libuna_utf16_string_compare_with_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_copy_from_utf32_stream, + libuna_utf16_string_size_from_utf32, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_with_index_copy_from_utf32_stream, + libuna_utf16_string_copy_from_utf32, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_size_from_utf8, + libuna_utf16_string_with_index_copy_from_utf32, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_copy_from_utf8, + libuna_utf16_string_compare_with_utf32, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_with_index_copy_from_utf8, + libuna_utf16_string_size_from_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_size_from_utf32, + libuna_utf16_string_copy_from_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_copy_from_utf32, + libuna_utf16_string_with_index_copy_from_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf16_string_with_index_copy_from_utf32, + libuna_utf16_string_compare_with_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( @@ -581,6 +779,11 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf32_string_with_index_copy_from_byte_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf32_string_compare_with_byte_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) AC_CHECK_LIB( una, libuna_utf32_string_size_from_utf7_stream, @@ -596,11 +799,31 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], libuna_utf32_string_with_index_copy_from_utf7_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf32_string_compare_with_utf7_stream, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) AC_CHECK_LIB( una, libuna_utf32_string_size_from_utf8_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf32_string_size_from_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + una, + libuna_utf32_string_copy_from_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + AC_CHECK_LIB( + libuna_utf32_string_with_index_copy_from_utf8, + [ac_cv_libuna_dummy=yes], + [ac_cv_libuna=no]) + dnl libuna_utf32_string_compare_with_utf8 is implemented by libuna_utf8_string_compare_with_utf32 AC_CHECK_LIB( una, libuna_utf32_string_copy_from_utf8_stream, @@ -613,61 +836,63 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_size_from_utf16_stream, + libuna_utf32_string_compare_with_utf8_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_copy_from_utf16_stream, + libuna_utf32_string_size_from_utf16, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_with_index_copy_from_utf16_stream, + libuna_utf32_string_copy_from_utf16, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_size_from_utf32_stream, + libuna_utf32_string_with_index_copy_from_utf16, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) + dnl libuna_utf32_string_compare_with_utf16 is implemented by libuna_utf16_string_compare_with_utf32 AC_CHECK_LIB( una, - libuna_utf32_string_copy_from_utf32_stream, + libuna_utf32_string_size_from_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_with_index_copy_from_utf32_stream, + libuna_utf32_string_copy_from_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_size_from_utf8, + libuna_utf32_string_with_index_copy_from_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_copy_from_utf8, + libuna_utf32_string_compare_with_utf16_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( - libuna_utf32_string_with_index_copy_from_utf8, + una, + libuna_utf32_string_size_from_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_size_from_utf16, + libuna_utf32_string_copy_from_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_copy_from_utf16, + libuna_utf32_string_with_index_copy_from_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( una, - libuna_utf32_string_with_index_copy_from_utf16, + libuna_utf32_string_compare_with_utf32_stream, [ac_cv_libuna_dummy=yes], [ac_cv_libuna=no]) AC_CHECK_LIB( @@ -708,6 +933,13 @@ AC_DEFUN([AX_LIBUNA_CHECK_LIB], [test "x$ac_cv_libuna_defines_compare_less" != xyes], [ac_cv_libuna=no]) + AX_LIBUNA_CHECK_DEFINITION( + LIBUNA_UTF16_STREAM_ALLOW_UNPAIRED_SURROGATE, + [ac_cv_libuna_defines_compare_greater]) + AS_IF( + [test "x$ac_cv_libuna_defines_utf16_stream_allow_unpaired_surrogate" != xyes], + [ac_cv_libuna=no]) + ac_cv_libuna_LIBADD="-luna"]) ]) AS_IF( diff --git a/m4/python.m4 b/m4/python.m4 index 307e15c..e10bc9f 100644 --- a/m4/python.m4 +++ b/m4/python.m4 @@ -1,6 +1,6 @@ dnl Functions for Python bindings dnl -dnl Version: 20211114 +dnl Version: 20230923 dnl Function to check if the python binary is available dnl "python${PYTHON_VERSION} python python# python#.#" @@ -8,7 +8,7 @@ AC_DEFUN([AX_PROG_PYTHON], [AS_IF( [test "x${PYTHON_VERSION}" != x], [ax_python_progs="python${PYTHON_VERSION}"], - [ax_python_progs="python python3 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2 python2.7 python2.6 python2.5"]) + [ax_python_progs="python python3 python3.12 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2 python2.7 python2.6 python2.5"]) AC_CHECK_PROGS( [PYTHON], [$ax_python_progs]) @@ -58,7 +58,7 @@ AC_DEFUN([AX_PROG_PYTHON2], dnl Function to check if the python3 binary is available dnl "python3 python3.#" AC_DEFUN([AX_PROG_PYTHON3], - [ax_python3_progs="python3 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0" + [ax_python3_progs="python3 python3.12 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0" AC_CHECK_PROGS( [PYTHON3], [$ax_python3_progs]) @@ -95,7 +95,7 @@ AC_DEFUN([AX_PROG_PYTHON_CONFIG], [test "x${PYTHON_CONFIG}" = x], [AC_CHECK_PROGS( [PYTHON_CONFIG], - [python-config python3-config python3.11-config python3.10-config python3.9-config python3.8-config python3.7-config python3.6-config python3.5-config python3.4-config python3.3-config python3.2-config python3.1-config python3.0-config python2-config python2.7-config python2.6-config python2.5-config]) + [python-config python3-config python3.12-config python3.11-config python3.10-config python3.9-config python3.8-config python3.7-config python3.6-config python3.5-config python3.4-config python3.3-config python3.2-config python3.1-config python3.0-config python2-config python2.7-config python2.6-config python2.5-config]) ]) AS_IF( [test "x${PYTHON_CONFIG}" = x], @@ -131,7 +131,7 @@ AC_DEFUN([AX_PROG_PYTHON3_CONFIG], [test "x${PYTHON3_CONFIG}" = x], [AC_CHECK_PROGS( [PYTHON3_CONFIG], - [python3-config python3.11-config python3.10-config python3.9-config python3.8-config python3.7-config python3.6-config python3.5-config python3.4-config python3.3-config python3.2-config python3.1-config python3.0-config]) + [python3-config python3.12-config python3.11-config python3.10-config python3.9-config python3.8-config python3.7-config python3.6-config python3.5-config python3.4-config python3.3-config python3.2-config python3.1-config python3.0-config]) ]) AS_IF( [test "x${PYTHON3_CONFIG}" = x], diff --git a/pyhmac/pyhmac.c b/pyhmac/pyhmac.c index 0cf0c50..ecbe961 100644 --- a/pyhmac/pyhmac.c +++ b/pyhmac/pyhmac.c @@ -134,7 +134,6 @@ PyObject *pyhmac_get_version( PyObject *self PYHMAC_ATTRIBUTE_UNUSED, PyObject *arguments PYHMAC_ATTRIBUTE_UNUSED ) { - const char *errors = NULL; const char *version_string = NULL; size_t version_string_length = 0; @@ -157,7 +156,7 @@ PyObject *pyhmac_get_version( return( PyUnicode_DecodeUTF8( version_string, (Py_ssize_t) version_string_length, - errors ) ); + NULL ) ); } #if PY_MAJOR_VERSION >= 3 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1870a2e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,4 @@ +[build-system] +requires = ["setuptools", "wheel"] +build-backend = "setuptools.build_meta" + diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 1ded777..0000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[metadata] -license_files = COPYING COPYING.LESSER diff --git a/setup.cfg.in b/setup.cfg.in new file mode 100644 index 0000000..4ee83bd --- /dev/null +++ b/setup.cfg.in @@ -0,0 +1,15 @@ +[metadata] +name = libhmac-python +version = @VERSION@ +description = Python bindings module for libhmac +long_description = Python bindings module for libhmac +author = Joachim Metz +author_email = joachim.metz@gmail.com +license = GNU Lesser General Public License v3 or later (LGPLv3+) +license_files = COPYING COPYING.LESSER +classifiers = + Development Status :: 3 - Alpha + Programming Language :: Python + +[options] +python_requires = >=3.7 diff --git a/setup.py b/setup.py index afd9215..3a86854 100755 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Script to build and install Python-bindings. -# Version: 20230411 +# Version: 20230909 from __future__ import print_function @@ -25,44 +25,11 @@ from setuptools.command.build_ext import build_ext from setuptools.command.sdist import sdist -try: - from distutils.command.bdist_msi import bdist_msi -except ImportError: - bdist_msi = None -try: - from setuptools.command.bdist_rpm import bdist_rpm -except ImportError: - from distutils.command.bdist import bdist as bdist_rpm - - -if not bdist_msi: - custom_bdist_msi = None -else: - class custom_bdist_msi(bdist_msi): - """Custom handler for the bdist_msi command.""" - - def run(self): - """Builds an MSI.""" - # Make a deepcopy of distribution so the following version changes - # only apply to bdist_msi. - self.distribution = copy.deepcopy(self.distribution) - - # bdist_msi does not support the library version so we add ".1" - # as a work around. - self.distribution.metadata.version = "{0:s}.1".format( - self.distribution.metadata.version) - - bdist_msi.run(self) - - -class custom_bdist_rpm(bdist_rpm): - """Custom handler for the bdist_rpm command.""" - - def run(self): - """Builds a RPM.""" - print("'setup.py bdist_rpm' command not supported use 'rpmbuild' instead.") - sys.exit(1) +if (sys.version_info[0], sys.version_info[1]) < (3, 7): + print(("Unsupported Python version: {0:s}, version 3.7 or higher " + "required.").format(sys.version)) + sys.exit(1) class custom_build_ext(build_ext): @@ -218,49 +185,25 @@ def module_name(self): """The Python module name.""" return "py{0:s}".format(self.library_name[3:]) - @property - def package_name(self): - """The package name.""" - return "{0:s}-python".format(self.library_name) - - @property - def package_description(self): - """The package description.""" - return "Python bindings module for {0:s}".format(self.library_name) - - @property - def project_url(self): - """The project URL.""" - return "https://github.com/libyal/{0:s}/".format(self.library_name) - def _ReadConfigureAc(self): """Reads configure.ac to initialize the project information.""" - file_object = open("configure.ac", "rb") - if not file_object: - raise IOError("Unable to open: configure.ac") - - found_ac_init = False - found_library_name = False - for line in file_object.readlines(): - line = line.strip() - if found_library_name: - library_version = line[1:-2] - if sys.version_info[0] >= 3: - library_version = library_version.decode("ascii") - self.library_version = library_version - break - - elif found_ac_init: - library_name = line[1:-2] - if sys.version_info[0] >= 3: - library_name = library_name.decode("ascii") - self.library_name = library_name - found_library_name = True - - elif line.startswith(b"AC_INIT"): - found_ac_init = True - - file_object.close() + with open("configure.ac", "r", encoding="utf-8") as file_object: + found_ac_init = False + found_library_name = False + for line in file_object.readlines(): + line = line.strip() + if found_library_name: + library_version = line[1:-2] + self.library_version = library_version + break + + elif found_ac_init: + library_name = line[1:-2] + self.library_name = library_name + found_library_name = True + + elif line.startswith("AC_INIT"): + found_ac_init = True if not self.library_name or not self.library_version: raise RuntimeError( @@ -271,30 +214,23 @@ def _ReadMakefileAm(self): if not self.library_name: raise RuntimeError("Missing library name") - file_object = open("Makefile.am", "rb") - if not file_object: - raise IOError("Unable to open: Makefile.am") - - found_subdirs = False - for line in file_object.readlines(): - line = line.strip() - if found_subdirs: - library_name, _, _ = line.partition(b" ") - if sys.version_info[0] >= 3: - library_name = library_name.decode("ascii") + with open("Makefile.am", "r", encoding="utf-8") as file_object: + found_subdirs = False + for line in file_object.readlines(): + line = line.strip() + if found_subdirs: + library_name, _, _ = line.partition(" ") - self.include_directories.append(library_name) + self.include_directories.append(library_name) - if library_name.startswith("lib"): - self.library_names.append(library_name) + if library_name.startswith("lib"): + self.library_names.append(library_name) - if library_name == self.library_name: - break + if library_name == self.library_name: + break - elif line.startswith(b"SUBDIRS"): - found_subdirs = True - - file_object.close() + elif line.startswith("SUBDIRS"): + found_subdirs = True if not self.include_directories or not self.library_names: raise RuntimeError( @@ -306,12 +242,8 @@ def _ReadMakefileAm(self): CMDCLASS = { "build_ext": custom_build_ext, - "bdist_rpm": custom_bdist_rpm, "sdist": custom_sdist} -if custom_bdist_msi: - CMDCLASS["bdist_msi"] = custom_bdist_msi - SOURCES = [] # TODO: replace by detection of MSC @@ -344,18 +276,7 @@ def _ReadMakefileAm(self): # TODO: find a way to detect missing python.h # e.g. on Ubuntu python-dev is not installed by python-pip -# TODO: what about description and platform in egg file - -setup( - name=project_information.package_name, - url=project_information.project_url, - version=project_information.library_version, - description=project_information.package_description, - long_description=project_information.package_description, - long_description_content_type="text/plain", - author="Joachim Metz", - author_email="joachim.metz@gmail.com", - license="GNU Lesser General Public License v3 or later (LGPLv3+)", +setup_args = dict( cmdclass=CMDCLASS, ext_modules=[ Extension( @@ -364,8 +285,9 @@ def _ReadMakefileAm(self): include_dirs=project_information.include_directories, libraries=[], library_dirs=[], - sources=SOURCES, - ), - ], + sources=SOURCES + ) + ] ) +setup(**setup_args) diff --git a/tests/runtests.py b/tests/runtests.py new file mode 100755 index 0000000..271948a --- /dev/null +++ b/tests/runtests.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# Script to run Python test scripts. +# +# Version: 20231004 + +import glob +import os +import sys +import unittest + + +test_profile = ".pybde" +input_glob = "*" +option_sets = ["offset", "password", "recovery_password", "startup_key"] + + +def ReadIgnoreList(test_profile): + """Reads the test profile ignore file if it exists. + + Args: + test_profile (str): test profile. + + Returns: + set[str]: ignore list. + """ + ignore_file_path = os.path.join("tests", "input", test_profile, "ignore") + if os.path.isfile(ignore_file_path): + with open(ignore_file_path, "r", encoding="utf-8") as file_object: + return set([line.strip() for line in file_object.readlines()]) + + return set() + + +if __name__ == "__main__": + print(f"Using Python version {sys.version!s}") + + test_loader = unittest.TestLoader() + test_runner = unittest.TextTestRunner(verbosity=2) + + test_scripts = test_loader.discover("tests", pattern="*.py") + + ignore_list = ReadIgnoreList(test_profile) + + test_set = None + source_file = None + + for test_set in glob.glob(os.path.join("tests", "input", "*")): + test_set = test_set.rsplit(os.path.sep, maxsplit=1)[-1] + if not test_set or test_set[0] == '.' or test_set in ignore_list: + continue + + source_files = glob.glob(os.path.join( + "tests", "input", test_set, input_glob)) + if source_files: + source_file = source_files[0] + break + + setattr(unittest, "source", source_file) + + for option_set in option_sets: + test_file = os.path.basename(source_file) + test_options_file_path = os.path.join( + "tests", "input", test_profile, test_set, + f"{test_file:s}.{option_set:s}") + if os.path.isfile(test_options_file_path): + with open(test_options_file_path, "r", encoding="utf-8") as file_object: + lines = [line.strip() for line in file_object.readlines()] + if lines[0] == "# libyal test data options": + for line in lines[1:]: + key, value = line.split("=", maxsplit=1) + setattr(unittest, key, value) + + test_results = test_runner.run(test_scripts) + if not test_results.wasSuccessful(): + sys.exit(1) diff --git a/tests/test_library.sh b/tests/test_library.sh index b27b379..24aae74 100755 --- a/tests/test_library.sh +++ b/tests/test_library.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Tests library functions and types. # -# Version: 20230410 +# Version: 20231005 EXIT_SUCCESS=0; EXIT_FAILURE=1; @@ -9,7 +9,7 @@ EXIT_IGNORE=77; LIBRARY_TESTS="error md5 md5_context sha1 sha1_context sha224 sha224_context sha256 sha256_context sha512 sha512_context support"; LIBRARY_TESTS_WITH_INPUT=""; -OPTION_SETS=""; +OPTION_SETS=(); INPUT_GLOB="*"; @@ -78,47 +78,52 @@ run_test_with_input() local TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); - local OLDIFS=${IFS}; - - # IFS="\n" is not supported by all platforms. - IFS=" -"; - if test -f "${TEST_SET_DIRECTORY}/files"; then - for INPUT_FILE in `cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"`; + IFS="" read -a INPUT_FILES <<< $(cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"); + else + IFS="" read -a INPUT_FILES <<< $(ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}); + fi + for INPUT_FILE in "${INPUT_FILES[@]}"; + do + if test "${OSTYPE}" = "msys"; + then + # A test executable built with MinGW expects a Windows path. + INPUT_FILE=`echo ${INPUT_FILE} | sed 's?/?\\\\?g'`; + fi + local TESTED_WITH_OPTIONS=0; + + for OPTION_SET in ${OPTION_SETS[@]}; do - if test "${OSTYPE}" = "msys"; - then - # A test executable built with MinGW expects a Windows path. - INPUT_FILE=`echo ${INPUT_FILE} | sed 's?/?\\\\?g'`; - fi - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; - RESULT=$?; + local TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); - if test ${RESULT} -ne ${EXIT_SUCCESS}; + if test -f ${TEST_DATA_OPTION_FILE}; then - break; + TESTED_WITH_OPTIONS=1; + + IFS=" " read -a OPTIONS <<< $(read_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + run_test_on_input_file "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "${OPTION_SET}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${OPTIONS[@]}"; + RESULT=$?; + + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi fi done - else - for INPUT_FILE in `ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; - do - if test "${OSTYPE}" = "msys"; - then - # A test executable built with MinGW expects a Windows path. - INPUT_FILE=`echo ${INPUT_FILE} | sed 's?/?\\\\?g'`; - fi - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; + + if test ${TESTED_WITH_OPTIONS} -eq 0; + then + run_test_on_input_file "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; RESULT=$?; + fi - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi - done - fi - IFS=${OLDIFS}; + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + done if test ${RESULT} -ne ${EXIT_SUCCESS}; then diff --git a/tests/test_md5sum.sh b/tests/test_md5sum.sh index f09e7ec..af6ce83 100755 --- a/tests/test_md5sum.sh +++ b/tests/test_md5sum.sh @@ -1,12 +1,14 @@ #!/usr/bin/env bash # Sum tool testing script # -# Version: 20230410 +# Version: 20231001 EXIT_SUCCESS=0; EXIT_FAILURE=1; EXIT_IGNORE=77; +PROFILES=("hmacsum"); +OPTIONS_PER_PROFILE=("") OPTION_SETS=""; INPUT_GLOB="*"; @@ -113,61 +115,88 @@ then return ${EXIT_IGNORE}; fi -TEST_PROFILE_DIRECTORY=$(get_test_profile_directory "input" "hmacsum"); - -IGNORE_LIST=$(read_ignore_list "${TEST_PROFILE_DIRECTORY}"); - RESULT=${EXIT_SUCCESS}; -for TEST_SET_INPUT_DIRECTORY in input/*; +for PROFILE_INDEX in ${!PROFILES[*]}; do - if ! test -d "${TEST_SET_INPUT_DIRECTORY}"; - then - continue; - fi - if check_for_directory_in_ignore_list "${TEST_SET_INPUT_DIRECTORY}" "${IGNORE_LIST}"; - then - continue; - fi + TEST_PROFILE=${PROFILES[${PROFILE_INDEX}]}; - TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); + TEST_PROFILE_DIRECTORY=$(get_test_profile_directory "input" "${TEST_PROFILE}"); - OLDIFS=${IFS}; + IGNORE_LIST=$(read_ignore_list "${TEST_PROFILE_DIRECTORY}"); - # IFS="\n"; is not supported by all platforms. - IFS=" -"; + IFS=" " read -a PROFILE_OPTIONS <<< ${OPTIONS_PER_PROFILE[${PROFILE_INDEX}]}; - if test -f "${TEST_SET_DIRECTORY}/files"; - then - for INPUT_FILE in `cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"`; + RESULT=${EXIT_SUCCESS}; + + for TEST_SET_INPUT_DIRECTORY in input/*; + do + if ! test -d "${TEST_SET_INPUT_DIRECTORY}"; + then + continue; + fi + TEST_SET=`basename ${TEST_SET_INPUT_DIRECTORY}`; + + if check_for_test_set_in_ignore_list "${TEST_SET}" "${IGNORE_LIST}"; + then + continue; + fi + TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); + + RESULT=${EXIT_SUCCESS}; + + if test -f "${TEST_SET_DIRECTORY}/files"; + then + IFS=$'\n' read -a INPUT_FILES <<< $(cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"); + else + IFS=$'\n' read -a INPUT_FILES <<< $(ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}); + fi + for INPUT_FILE in "${INPUT_FILES[@]}"; do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "hmacsum" "with_callback" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; - RESULT=$?; + TESTED_WITH_OPTIONS=0; - if test ${RESULT} -ne ${EXIT_SUCCESS}; + for OPTION_SET in ${OPTION_SETS[@]}; + do + TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + if test -f ${TEST_DATA_OPTION_FILE}; + then + TESTED_WITH_OPTIONS=1; + + IFS=" " read -a OPTIONS <<< $(read_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + run_test_on_input_file "${TEST_SET_DIRECTORY}" "hmacsum" "with_stdout_reference" "${OPTION_SET}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${PROFILE_OPTIONS[@]}" "${OPTIONS[@]}"; + RESULT=$?; + + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + fi + done + + if test ${TESTED_WITH_OPTIONS} -eq 0; then - break; + run_test_on_input_file "${TEST_SET_DIRECTORY}" "hmacsum" "with_stdout_reference" "" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${PROFILE_OPTIONS[@]}"; + RESULT=$?; fi - done - else - for INPUT_FILE in `ls -1 ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; - do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "hmacsum" "with_callback" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; - RESULT=$?; if test ${RESULT} -ne ${EXIT_SUCCESS}; then break; fi done - fi - IFS=${OLDIFS}; - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi + # Ignore failures due to corrupted data. + if test "${TEST_SET}" = "corrupted"; + then + RESULT=${EXIT_SUCCESS}; + fi + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + done done exit ${RESULT}; diff --git a/tests/test_python_module.sh b/tests/test_python_module.sh index e5ccf9a..7f271d6 100755 --- a/tests/test_python_module.sh +++ b/tests/test_python_module.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Tests Python module functions and types. # -# Version: 20230410 +# Version: 20231005 EXIT_SUCCESS=0; EXIT_FAILURE=1; @@ -9,7 +9,7 @@ EXIT_IGNORE=77; TEST_FUNCTIONS="support"; TEST_FUNCTIONS_WITH_INPUT=""; -OPTION_SETS=""; +OPTION_SETS=(); TEST_TOOL_DIRECTORY="."; INPUT_GLOB="*"; @@ -68,37 +68,47 @@ test_python_function_with_input() local TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); - local OLDIFS=${IFS}; - - # IFS="\n"; is not supported by all platforms. - IFS=" -"; - if test -f "${TEST_SET_DIRECTORY}/files"; then - for INPUT_FILE in `cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"`; + IFS="" read -a INPUT_FILES <<< $(cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"); + else + IFS="" read -a INPUT_FILES <<< $(ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}); + fi + for INPUT_FILE in "${INPUT_FILES[@]}"; + do + local TESTED_WITH_OPTIONS=0; + + for OPTION_SET in ${OPTION_SETS[@]}; do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "${OPTION_SETS}" "${TEST_SCRIPT}" "${INPUT_FILE}"; - RESULT=$?; + local TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); - if test ${RESULT} -ne ${EXIT_SUCCESS}; + if test -f ${TEST_DATA_OPTION_FILE}; then - break; + TESTED_WITH_OPTIONS=1; + + IFS=" " read -a OPTIONS <<< $(read_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + run_test_on_input_file "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "${OPTION_SET}" "${TEST_SCRIPT}" "${INPUT_FILE}" "${OPTIONS[@]}"; + RESULT=$?; + + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi fi done - else - for INPUT_FILE in `ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; - do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "${OPTION_SETS}" "${TEST_SCRIPT}" "${INPUT_FILE}"; + + if test ${TESTED_WITH_OPTIONS} -eq 0; + then + run_test_on_input_file "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "" "${TEST_SCRIPT}" "${INPUT_FILE}"; RESULT=$?; + fi - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi - done - fi - IFS=${OLDIFS}; + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + done if test ${RESULT} -ne ${EXIT_SUCCESS}; then diff --git a/tests/test_runner.sh b/tests/test_runner.sh index 6313971..da773fa 100644 --- a/tests/test_runner.sh +++ b/tests/test_runner.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # Bash functions to run an executable for testing. # -# Version: 20230410 +# Version: 20231001 # # When CHECK_WITH_ASAN is set to a non-empty value the test executable # is run with asan, otherwise it is run without. @@ -406,9 +406,12 @@ read_test_data_option_file() TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); fi - local OPTIONS=() - local OPTIONS_STRING=`cat "${TEST_DATA_OPTION_FILE}" | head -n 1 | sed 's/[\r\n]*$//'`; + local OPTIONS_STRING=`head -n 1 "${TEST_DATA_OPTION_FILE}" | sed 's/[\r\n]*$//'`; + if test "${OPTIONS_STRING}" = "# libyal test data options"; + then + OPTIONS_STRING=`tail -n +2 "${TEST_DATA_OPTION_FILE}" | sed 's/^offset=/-o/;s/^password=/-p/;s/^recovery_password=/-r/;s/^startup_key=/-s/' | tr '\n' ' '`; + fi echo "${OPTIONS_STRING}"; } @@ -1073,14 +1076,10 @@ run_test_on_input_file() local ARGUMENTS=("$@"); local INPUT_NAME=`basename "${INPUT_FILE}"`; - local OPTIONS=(); local TEST_OUTPUT="${INPUT_NAME}"; if test -n "${OPTION_SET}"; then - OPTIONS_STRING=$(read_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); - IFS=" " read -a OPTIONS <<< "${OPTIONS_STRING}"; - TEST_OUTPUT="${INPUT_NAME}-${OPTION_SET}"; fi @@ -1092,7 +1091,7 @@ run_test_on_input_file() if test "${TEST_MODE}" = "with_callback"; then - test_callback "${TMPDIR}" "${TEST_SET_DIRECTORY}" "${TEST_OUTPUT}" "${TEST_EXECUTABLE}" "${TEST_INPUT}" ${ARGUMENTS[@]} "${OPTIONS[@]}"; + test_callback "${TMPDIR}" "${TEST_SET_DIRECTORY}" "${TEST_OUTPUT}" "${TEST_EXECUTABLE}" "${TEST_INPUT}" ${ARGUMENTS[@]}; RESULT=$?; elif test "${TEST_MODE}" = "with_stdout_reference"; @@ -1109,7 +1108,7 @@ run_test_on_input_file() local INPUT_FILE_FULL_PATH=$( readlink_f "${INPUT_FILE}" ); local TEST_LOG="${TEST_OUTPUT}.log"; - (cd ${TMPDIR} && run_test_with_input_and_arguments "${TEST_EXECUTABLE}" "${INPUT_FILE_FULL_PATH}" ${ARGUMENTS[@]} "${OPTIONS[@]}" > "${TEST_LOG}"); + (cd ${TMPDIR} && run_test_with_input_and_arguments "${TEST_EXECUTABLE}" "${INPUT_FILE_FULL_PATH}" ${ARGUMENTS[@]} > "${TEST_LOG}"); RESULT=$?; # Compare output if test ran successfully. @@ -1135,7 +1134,7 @@ run_test_on_input_file() fi else - run_test_with_input_and_arguments "${TEST_EXECUTABLE}" "${INPUT_FILE}" ${ARGUMENTS[@]} "${OPTIONS[@]}"; + run_test_with_input_and_arguments "${TEST_EXECUTABLE}" "${INPUT_FILE}" ${ARGUMENTS[@]}; RESULT=$?; fi @@ -1144,22 +1143,12 @@ run_test_on_input_file() if test -n "${TEST_DESCRIPTION}"; then ARGUMENTS=`echo "${ARGUMENTS[*]}" | tr '\n' ' ' | sed 's/[ ]\$//'`; - OPTIONS=`echo "${OPTIONS[*]}" | tr '\n' ' ' | sed 's/[ ]\$//'`; - if test -z "${ARGUMENTS}" && test -z "${OPTIONS}"; + if test -z "${ARGUMENTS}"; then echo -n "${TEST_DESCRIPTION} with input: ${INPUT_FILE}"; - - elif test -z "${ARGUMENTS}"; - then - echo -n "${TEST_DESCRIPTION} with options: '${OPTIONS}' and input: ${INPUT_FILE}"; - - elif test -z "${OPTIONS}"; - then - echo -n "${TEST_DESCRIPTION} with options: '${ARGUMENTS}' and input: ${INPUT_FILE}"; - else - echo -n "${TEST_DESCRIPTION} with options: '${ARGUMENTS} ${OPTIONS}' and input: ${INPUT_FILE}"; + echo -n "${TEST_DESCRIPTION} with options: '${ARGUMENTS}' and input: ${INPUT_FILE}"; fi if test ${RESULT} -ne ${EXIT_SUCCESS}; @@ -1172,122 +1161,3 @@ run_test_on_input_file() return ${RESULT}; } -# Runs the test with options on the input file. -# -# Note that this function is not intended to be directly invoked -# from outside the test runner script. -# -# Arguments: -# a string containing the path of the test set directory -# a string containing the description of the test -# a string containing the test mode -# a string containing the name of the test data option sets -# a string containing the path of the test executable -# a string containing the path of the test input file -# an array containing the arguments for the test executable -# -# Returns: -# an integer containg the exit status of the test executable -# -run_test_on_input_file_with_options() -{ - local TEST_SET_DIRECTORY=$1; - local TEST_DESCRIPTION=$2; - local TEST_MODE=$3; - local OPTION_SETS=$4; - local TEST_EXECUTABLE=$5; - local INPUT_FILE=$6; - shift 6; - local ARGUMENTS=("$@"); - - local RESULT=${EXIT_SUCCESS}; - local TESTED_WITH_OPTIONS=0; - - for OPTION_SET in `echo ${OPTION_SETS} | tr ' ' '\n'`; - do - local TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); - - if ! test -f ${TEST_DATA_OPTION_FILE}; - then - continue - fi - - run_test_on_input_file "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "${TEST_MODE}" "${OPTION_SET}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" ${ARGUMENTS[@]}; - RESULT=$?; - - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi - TESTED_WITH_OPTIONS=1; - done - - if test ${RESULT} -eq ${EXIT_SUCCESS} && test ${TESTED_WITH_OPTIONS} -eq 0; - then - run_test_on_input_file "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "${TEST_MODE}" "" "${TEST_EXECUTABLE}" "${INPUT_FILE}" ${ARGUMENTS[@]}; - RESULT=$?; - fi - return ${RESULT}; -} - -# Runs the test with options on the file entries in the test set directory. -# -# Note that this function is not intended to be directly invoked -# from outside the test runner script. -# -# Arguments: -# a string containing the path of the test set directory -# a string containing the description of the test -# a string containing the test mode -# a string containing the name of the test data option sets -# a string containing the path of the test executable -# an array containing the arguments for the test executable -# -# Returns: -# an integer containg the exit status of the test executable -# -run_test_on_test_set_with_options() -{ - local TEST_SET_DIRECTORY=$1; - local TEST_DESCRIPTION=$2; - local TEST_MODE=$3; - local OPTION_SETS=$4; - local TEST_EXECUTABLE=$5; - shift 5; - local ARGUMENTS=("$@"); - - local RESULT=${EXIT_SUCCESS}; - - # IFS="\n"; is not supported by all platforms. - IFS=" -"; - - if test -f "${TEST_SET_DIRECTORY}/files"; - then - for INPUT_FILE in `cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"`; - do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "${TEST_MODE}" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" ${ARGUMENTS[@]}; - RESULT=$?; - - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi - done - else - for INPUT_FILE in `ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; - do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "${TEST_MODE}" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" ${ARGUMENTS[@]}; - RESULT=$?; - - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi - done - fi - IFS=${OLDIFS}; - - return ${RESULT}; -} - diff --git a/tests/test_sha1sum.sh b/tests/test_sha1sum.sh index 6342e10..434c81c 100755 --- a/tests/test_sha1sum.sh +++ b/tests/test_sha1sum.sh @@ -1,12 +1,14 @@ #!/usr/bin/env bash # Sum tool testing script # -# Version: 20230701 +# Version: 20231001 EXIT_SUCCESS=0; EXIT_FAILURE=1; EXIT_IGNORE=77; +PROFILES=("hmacsum"); +OPTIONS_PER_PROFILE=("") OPTION_SETS=""; INPUT_GLOB="*"; @@ -115,61 +117,86 @@ then return ${EXIT_IGNORE}; fi -TEST_PROFILE_DIRECTORY=$(get_test_profile_directory "input" "hmacsum"); +for PROFILE_INDEX in ${!PROFILES[*]}; +do + TEST_PROFILE=${PROFILES[${PROFILE_INDEX}]}; -IGNORE_LIST=$(read_ignore_list "${TEST_PROFILE_DIRECTORY}"); + TEST_PROFILE_DIRECTORY=$(get_test_profile_directory "input" "${TEST_PROFILE}"); -RESULT=${EXIT_SUCCESS}; + IGNORE_LIST=$(read_ignore_list "${TEST_PROFILE_DIRECTORY}"); -for TEST_SET_INPUT_DIRECTORY in input/*; -do - if ! test -d "${TEST_SET_INPUT_DIRECTORY}"; - then - continue; - fi - if check_for_directory_in_ignore_list "${TEST_SET_INPUT_DIRECTORY}" "${IGNORE_LIST}"; - then - continue; - fi + IFS=" " read -a PROFILE_OPTIONS <<< ${OPTIONS_PER_PROFILE[${PROFILE_INDEX}]}; - TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); + RESULT=${EXIT_SUCCESS}; - OLDIFS=${IFS}; + for TEST_SET_INPUT_DIRECTORY in input/*; + do + if ! test -d "${TEST_SET_INPUT_DIRECTORY}"; + then + continue; + fi + TEST_SET=`basename ${TEST_SET_INPUT_DIRECTORY}`; - # IFS="\n"; is not supported by all platforms. - IFS=" -"; + if check_for_test_set_in_ignore_list "${TEST_SET}" "${IGNORE_LIST}"; + then + continue; + fi + TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); - if test -f "${TEST_SET_DIRECTORY}/files"; - then - for INPUT_FILE in `cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"`; + RESULT=${EXIT_SUCCESS}; + + if test -f "${TEST_SET_DIRECTORY}/files"; + then + IFS=$'\n' read -a INPUT_FILES <<< $(cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"); + else + IFS=$'\n' read -a INPUT_FILES <<< $(ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}); + fi + for INPUT_FILE in "${INPUT_FILES[@]}"; do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "hmacsum" "with_callback" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; - RESULT=$?; + TESTED_WITH_OPTIONS=0; - if test ${RESULT} -ne ${EXIT_SUCCESS}; + for OPTION_SET in ${OPTION_SETS[@]}; + do + TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + if test -f ${TEST_DATA_OPTION_FILE}; + then + TESTED_WITH_OPTIONS=1; + + IFS=" " read -a OPTIONS <<< $(read_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + run_test_on_input_file "${TEST_SET_DIRECTORY}" "hmacsum" "with_stdout_reference" "${OPTION_SET}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${PROFILE_OPTIONS[@]}" "${OPTIONS[@]}"; + RESULT=$?; + + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + fi + done + + if test ${TESTED_WITH_OPTIONS} -eq 0; then - break; + run_test_on_input_file "${TEST_SET_DIRECTORY}" "hmacsum" "with_stdout_reference" "" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${PROFILE_OPTIONS[@]}"; + RESULT=$?; fi - done - else - for INPUT_FILE in `ls -1 ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; - do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "hmacsum" "with_callback" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; - RESULT=$?; if test ${RESULT} -ne ${EXIT_SUCCESS}; then break; fi done - fi - IFS=${OLDIFS}; - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi + # Ignore failures due to corrupted data. + if test "${TEST_SET}" = "corrupted"; + then + RESULT=${EXIT_SUCCESS}; + fi + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + done done exit ${RESULT}; diff --git a/tests/test_sha2sum.sh b/tests/test_sha2sum.sh index 1de04a2..aa2c0ef 100755 --- a/tests/test_sha2sum.sh +++ b/tests/test_sha2sum.sh @@ -1,12 +1,14 @@ #!/usr/bin/env bash # Sum tool testing script # -# Version: 20230701 +# Version: 20231001 EXIT_SUCCESS=0; EXIT_FAILURE=1; EXIT_IGNORE=77; +PROFILES=("hmacsum"); +OPTIONS_PER_PROFILE=("") OPTION_SETS=""; INPUT_GLOB="*"; @@ -149,61 +151,86 @@ then return ${EXIT_IGNORE}; fi -TEST_PROFILE_DIRECTORY=$(get_test_profile_directory "input" "hmacsum"); +for PROFILE_INDEX in ${!PROFILES[*]}; +do + TEST_PROFILE=${PROFILES[${PROFILE_INDEX}]}; -IGNORE_LIST=$(read_ignore_list "${TEST_PROFILE_DIRECTORY}"); + TEST_PROFILE_DIRECTORY=$(get_test_profile_directory "input" "${TEST_PROFILE}"); -RESULT=${EXIT_SUCCESS}; + IGNORE_LIST=$(read_ignore_list "${TEST_PROFILE_DIRECTORY}"); -for TEST_SET_INPUT_DIRECTORY in input/*; -do - if ! test -d "${TEST_SET_INPUT_DIRECTORY}"; - then - continue; - fi - if check_for_directory_in_ignore_list "${TEST_SET_INPUT_DIRECTORY}" "${IGNORE_LIST}"; - then - continue; - fi + IFS=" " read -a PROFILE_OPTIONS <<< ${OPTIONS_PER_PROFILE[${PROFILE_INDEX}]}; - TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); + RESULT=${EXIT_SUCCESS}; - OLDIFS=${IFS}; + for TEST_SET_INPUT_DIRECTORY in input/*; + do + if ! test -d "${TEST_SET_INPUT_DIRECTORY}"; + then + continue; + fi + TEST_SET=`basename ${TEST_SET_INPUT_DIRECTORY}`; - # IFS="\n"; is not supported by all platforms. - IFS=" -"; + if check_for_test_set_in_ignore_list "${TEST_SET}" "${IGNORE_LIST}"; + then + continue; + fi + TEST_SET_DIRECTORY=$(get_test_set_directory "${TEST_PROFILE_DIRECTORY}" "${TEST_SET_INPUT_DIRECTORY}"); - if test -f "${TEST_SET_DIRECTORY}/files"; - then - for INPUT_FILE in `cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"`; + RESULT=${EXIT_SUCCESS}; + + if test -f "${TEST_SET_DIRECTORY}/files"; + then + IFS=$'\n' read -a INPUT_FILES <<< $(cat ${TEST_SET_DIRECTORY}/files | sed "s?^?${TEST_SET_INPUT_DIRECTORY}/?"); + else + IFS=$'\n' read -a INPUT_FILES <<< $(ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}); + fi + for INPUT_FILE in "${INPUT_FILES[@]}"; do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "hmacsum" "with_callback" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; - RESULT=$?; + TESTED_WITH_OPTIONS=0; - if test ${RESULT} -ne ${EXIT_SUCCESS}; + for OPTION_SET in ${OPTION_SETS[@]}; + do + TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + if test -f ${TEST_DATA_OPTION_FILE}; + then + TESTED_WITH_OPTIONS=1; + + IFS=" " read -a OPTIONS <<< $(read_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}"); + + run_test_on_input_file "${TEST_SET_DIRECTORY}" "hmacsum" "with_stdout_reference" "${OPTION_SET}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${PROFILE_OPTIONS[@]}" "${OPTIONS[@]}"; + RESULT=$?; + + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + fi + done + + if test ${TESTED_WITH_OPTIONS} -eq 0; then - break; + run_test_on_input_file "${TEST_SET_DIRECTORY}" "hmacsum" "with_stdout_reference" "" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${PROFILE_OPTIONS[@]}"; + RESULT=$?; fi - done - else - for INPUT_FILE in `ls -1 ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; - do - run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "hmacsum" "with_callback" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}"; - RESULT=$?; if test ${RESULT} -ne ${EXIT_SUCCESS}; then break; fi done - fi - IFS=${OLDIFS}; - if test ${RESULT} -ne ${EXIT_SUCCESS}; - then - break; - fi + # Ignore failures due to corrupted data. + if test "${TEST_SET}" = "corrupted"; + then + RESULT=${EXIT_SUCCESS}; + fi + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + break; + fi + done done exit ${RESULT}; diff --git a/tox.ini b/tox.ini index df530a0..0eb54f9 100644 --- a/tox.ini +++ b/tox.ini @@ -1,15 +1,20 @@ [tox] -envlist = py3{7,8,9,10,11} +envlist = py3{7,8,9,10,11,12} [testenv] usedevelop = True -allowlist_externals = ./setup.py pip_pre = True passenv = - CFLAGS - CPPFLAGS - INCLUDE - LDFLAGS - LIB + CFLAGS + CPPFLAGS + INCLUDE + LDFLAGS + LIB +deps = + build + setuptools + wheel commands = - ./setup.py bdist_wheel + python -m build --no-isolation --outdir=dist --wheel + python -m pip install --no-index --find-links=dist libhmac-python + python tests/runtests.py