CI updates and assorted cleanups
This commit is contained in:
parent
b6dd61cea8
commit
283ab0e7ea
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -327,7 +327,7 @@ jobs:
|
|||||||
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
git rev-parse --short=12 HEAD > %BDIR%\upx\.GITREV.txt
|
||||||
@REM ===== build bzip2 =====
|
@REM ===== build bzip2 =====
|
||||||
cd %BDIR%\bzip2
|
cd %BDIR%\bzip2
|
||||||
@rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -c %H%\vendor\bzip2\*.c
|
@rem %RUN_CL% -J -O2 -W4 -wd4127 -wd4244 -wd4267 -WX %DEFS% -DBZ_NO_STDIO -c %H%\vendor\bzip2\*.c
|
||||||
@rem %RUN_LIB% -out:bzip2.lib *.obj
|
@rem %RUN_LIB% -out:bzip2.lib *.obj
|
||||||
@REM ===== build UCL =====
|
@REM ===== build UCL =====
|
||||||
cd %BDIR%\ucl
|
cd %BDIR%\ucl
|
||||||
@ -348,7 +348,7 @@ jobs:
|
|||||||
set s=%H%\src
|
set s=%H%\src
|
||||||
cat .GITREV.txt
|
cat .GITREV.txt
|
||||||
set /p GITREV=<.GITREV.txt
|
set /p GITREV=<.GITREV.txt
|
||||||
set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0
|
set UPX_DEFS=-DUPX_CONFIG_DISABLE_WSTRICT=0 -DUPX_CONFIG_DISABLE_WERROR=0 -DWITH_THREADS=0 -DWITH_BZIP2=0 -DWITH_ZSTD=0
|
||||||
set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib
|
set UPX_LIBS=%BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib
|
||||||
@rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib
|
@rem set UPX_LIBS=%BDIR%\bzip2\bzip2.lib %BDIR%\ucl\ucl.lib %BDIR%\zlib\zlib.lib %BDIR%\zstd\zstd.lib
|
||||||
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
|
set sources=%s%\*.cpp %s%\check\*.cpp %s%\compress\*.cpp %s%\console\*.cpp %s%\filter\*.cpp %s%\util\*.cpp
|
||||||
|
|||||||
2
.github/workflows/misc-spell-check.yml
vendored
2
.github/workflows/misc-spell-check.yml
vendored
@ -17,5 +17,5 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with: { submodules: false }
|
with: { submodules: false }
|
||||||
- name: 'Spell check with crate-ci/typos'
|
- name: 'Spell check with crate-ci/typos'
|
||||||
uses: crate-ci/typos@47dd2976043bd5c76a33aa9300b328a176a1d6f7 # v1.16.21
|
uses: crate-ci/typos@0d04ce91a7a8436a6e3c589750514ac586632192 # v1.16.22
|
||||||
with: { config: ./.github/typos_config.toml }
|
with: { config: ./.github/typos_config.toml }
|
||||||
|
|||||||
73
.github/workflows/weekly-ci-bs-by-hand.yml
vendored
73
.github/workflows/weekly-ci-bs-by-hand.yml
vendored
@ -142,7 +142,7 @@ jobs:
|
|||||||
cd "upx with space"/build/by-hand
|
cd "upx with space"/build/by-hand
|
||||||
bash "$testsuite"
|
bash "$testsuite"
|
||||||
|
|
||||||
job-by-hand-windows: # uses a POSIX-compliant shell
|
job-by-hand-windows-clang: # uses a POSIX-compliant shell
|
||||||
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
|
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
|
||||||
if: github.repository_owner == 'upx'
|
if: github.repository_owner == 'upx'
|
||||||
strategy:
|
strategy:
|
||||||
@ -151,7 +151,7 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- { os: windows-2019 }
|
- { os: windows-2019 }
|
||||||
- { os: windows-2022 }
|
- { os: windows-2022 }
|
||||||
name: ${{ format('by-hand cc {0}', matrix.os) }}
|
name: ${{ format('by-hand clang {0}', matrix.os) }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- run: git config --global core.autocrlf false
|
- run: git config --global core.autocrlf false
|
||||||
@ -160,7 +160,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "upx with space"
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "upx with space"
|
||||||
git -C "upx with space" submodule update --init
|
git -C "upx with space" submodule update --init
|
||||||
- name: 'Build by-hand with bash - clang'
|
- name: 'Build by-hand with bash'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
xflags="-static -Wall -Wextra -Werror"
|
xflags="-static -Wall -Wextra -Werror"
|
||||||
@ -169,9 +169,72 @@ jobs:
|
|||||||
export zlib_extra_flags="-DHAVE_VSNPRINTF"
|
export zlib_extra_flags="-DHAVE_VSNPRINTF"
|
||||||
export AR_LIBFILE=upx_submodules.lib
|
export AR_LIBFILE=upx_submodules.lib
|
||||||
CC="clang $xflags" CXX="clang++ -std=gnu++17 $xflags" bash "./upx with space/misc/scripts/build_upx_by_hand.sh"
|
CC="clang $xflags" CXX="clang++ -std=gnu++17 $xflags" bash "./upx with space/misc/scripts/build_upx_by_hand.sh"
|
||||||
- name: 'Build by-hand with bash - gcc'
|
|
||||||
if: success() || failure() # run this step even if the previous step failed
|
job-by-hand-windows-gcc: # uses a POSIX-compliant shell
|
||||||
|
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
|
||||||
|
if: github.repository_owner == 'upx'
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- { os: windows-2019 }
|
||||||
|
- { os: windows-2022 }
|
||||||
|
name: ${{ format('by-hand gcc {0}', matrix.os) }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- run: git config --global core.autocrlf false
|
||||||
|
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "upx with space"
|
||||||
|
git -C "upx with space" submodule update --init
|
||||||
|
- name: 'Build by-hand with bash'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
xflags="-static -Wall -Wextra -Werror"
|
xflags="-static -Wall -Wextra -Werror"
|
||||||
CC="gcc $xflags" CXX="g++ -std=gnu++17 $xflags" bash "./upx with space/misc/scripts/build_upx_by_hand.sh"
|
CC="gcc $xflags" CXX="g++ -std=gnu++17 $xflags" bash "./upx with space/misc/scripts/build_upx_by_hand.sh"
|
||||||
|
|
||||||
|
job-by-hand-windows-msvc: # uses a POSIX-compliant shell
|
||||||
|
# ...and also uses a subdirectory "upx with space" in order to detect possible quoting issues
|
||||||
|
if: github.repository_owner == 'upx'
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# clang-cl
|
||||||
|
- { os: windows-2019, vsversion: 2019, arch: amd64, clang_cl: true }
|
||||||
|
- { os: windows-2022, vsversion: 2022, arch: amd64, clang_cl: true }
|
||||||
|
# msvc
|
||||||
|
- { os: windows-2019, vsversion: 2019, arch: amd64 }
|
||||||
|
- { os: windows-2019, vsversion: 2019, arch: amd64_arm64 }
|
||||||
|
- { os: windows-2019, vsversion: 2019, arch: amd64_x86 }
|
||||||
|
- { os: windows-2022, vsversion: 2022, arch: amd64 }
|
||||||
|
- { os: windows-2022, vsversion: 2022, arch: amd64_arm64 }
|
||||||
|
- { os: windows-2022, vsversion: 2022, arch: amd64_x86 }
|
||||||
|
name: ${{ format('by-hand vs{0} {1} {2}', matrix.vsversion, matrix.arch, matrix.clang_cl && 'clang-cl' || '') }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- run: git config --global core.autocrlf false
|
||||||
|
- name: ${{ format('Check out UPX {0} source code', github.ref_name) }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
git clone --branch "$GITHUB_REF_NAME" --depth 1 "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" "upx with space"
|
||||||
|
git -C "upx with space" submodule update --init
|
||||||
|
- name: 'Set up Developer Command Prompt'
|
||||||
|
uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89 # v1.12.1
|
||||||
|
with:
|
||||||
|
vsversion: ${{ matrix.vsversion }}
|
||||||
|
arch: ${{ matrix.arch }}
|
||||||
|
- name: 'Build by-hand with bash'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
X="${{ matrix.clang_cl && 'clang-cl' || 'cl' }}"
|
||||||
|
command -v cl clang-cl lib link
|
||||||
|
# using MSVC headers and libraries, so adjust settings
|
||||||
|
xflags="-MT -J -W3 -DWIN32_LEAN_AND_MEAN -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS"
|
||||||
|
export mandatory_flags=
|
||||||
|
export sensible_flags=
|
||||||
|
export zlib_extra_flags="-DHAVE_VSNPRINTF"
|
||||||
|
export AR=false
|
||||||
|
export obj_suffix=.obj
|
||||||
|
CC="$X $xflags" CXX="$X -std:c++17 -Zc:__cplusplus -EHsc $xflags" bash "./upx with space/misc/scripts/build_upx_by_hand.sh"
|
||||||
|
|||||||
@ -426,6 +426,7 @@ if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
|||||||
set(t upx_vendor_bzip2)
|
set(t upx_vendor_bzip2)
|
||||||
upx_compile_target_debug_with_O2(${t})
|
upx_compile_target_debug_with_O2(${t})
|
||||||
upx_sanitize_target(${t})
|
upx_sanitize_target(${t})
|
||||||
|
target_compile_definitions(${t} PRIVATE BZ_NO_STDIO=1)
|
||||||
if(MSVC_FRONTEND)
|
if(MSVC_FRONTEND)
|
||||||
target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX})
|
target_compile_options(${t} PRIVATE ${warn_WN} -wd4127 -wd4244 -wd4267 ${warn_WX})
|
||||||
else()
|
else()
|
||||||
@ -488,7 +489,7 @@ if(NOT UPX_CONFIG_DISABLE_WERROR)
|
|||||||
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0)
|
target_compile_definitions(${t} PRIVATE UPX_CONFIG_DISABLE_WERROR=0)
|
||||||
endif()
|
endif()
|
||||||
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
if(NOT UPX_CONFIG_DISABLE_BZIP2)
|
||||||
target_compile_definitions(${t} PRIVATE WITH_BZIP2=0) # FIXME TODO
|
target_compile_definitions(${t} PRIVATE WITH_BZIP2=1)
|
||||||
endif()
|
endif()
|
||||||
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
if(NOT UPX_CONFIG_DISABLE_ZSTD)
|
||||||
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
|
target_compile_definitions(${t} PRIVATE WITH_ZSTD=1)
|
||||||
|
|||||||
@ -8,7 +8,8 @@ set -e
|
|||||||
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
# Copyright (C) Markus Franz Xaver Johannes Oberhumer
|
||||||
#
|
#
|
||||||
|
|
||||||
# uses optional environment variables: AR, CC, CXX, OPTIMIZE, VERBOSE, top_srcdir
|
# uses optional environment variables: AR, CC, CXX, OPTIMIZE, VERBOSE
|
||||||
|
# and optional settings for top_srcdir, obj_suffix and XXX_extra_flags
|
||||||
|
|
||||||
# shell init
|
# shell init
|
||||||
### set -x # enable logging
|
### set -x # enable logging
|
||||||
@ -24,19 +25,23 @@ CXX="${CXX:-c++ -std=gnu++17}"
|
|||||||
if test "x$AR" = "x0" || test "x$AR" = "xfalse" || test "x$AR" = "x/bin/false"; then
|
if test "x$AR" = "x0" || test "x$AR" = "xfalse" || test "x$AR" = "x/bin/false"; then
|
||||||
AR="" # do not use $AR
|
AR="" # do not use $AR
|
||||||
fi
|
fi
|
||||||
|
if test -z "${mandatory_flags+set}"; then
|
||||||
# protect against security threats caused by misguided compiler "optimizations"
|
# protect against security threats caused by misguided compiler "optimizations"
|
||||||
mandatory_flags="-fno-strict-aliasing -fno-strict-overflow -funsigned-char"
|
mandatory_flags="-fno-strict-aliasing -fno-strict-overflow -funsigned-char"
|
||||||
|
fi
|
||||||
|
if test -z "${sensible_flags+set}"; then
|
||||||
# not mandatory but good practice when using <windows.h>:
|
# not mandatory but good practice when using <windows.h>:
|
||||||
sensible_flags="-DWIN32_LEAN_AND_MEAN"
|
sensible_flags="-DWIN32_LEAN_AND_MEAN"
|
||||||
if test "x$OPTIMIZE" != "x" && test "x$OPTIMIZE" != "x0"; then
|
if test "x$OPTIMIZE" != "x" && test "x$OPTIMIZE" != "x0"; then
|
||||||
# not mandatory and not minimal, but usually a good idea:
|
# not mandatory and not minimal, but usually a good idea:
|
||||||
sensible_flags="-Wall -O2 $sensible_flags"
|
sensible_flags="-Wall -O2 $sensible_flags"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
CC="$CC $sensible_flags $mandatory_flags"
|
CC="$CC $sensible_flags $mandatory_flags"
|
||||||
CXX="$CXX $sensible_flags $mandatory_flags"
|
CXX="$CXX $sensible_flags $mandatory_flags"
|
||||||
|
|
||||||
# go to upx top-level directory
|
# go to upx top-level directory
|
||||||
# HINT: set "top_srcdir" manually if your system does not have "readlink"
|
# HINT: set "top_srcdir" manually if your system does not have "readlink -f"
|
||||||
if test "x$top_srcdir" = "x"; then
|
if test "x$top_srcdir" = "x"; then
|
||||||
my_argv0abs="$(readlink -fn "$my_argv0")"
|
my_argv0abs="$(readlink -fn "$my_argv0")"
|
||||||
test "x$my_argv0abs" = "x" && exit 1
|
test "x$my_argv0abs" = "x" && exit 1
|
||||||
@ -91,25 +96,31 @@ check_submodule() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# build
|
# build
|
||||||
|
upx_submodule_defs=
|
||||||
run "+" mkdir -p "build/by-hand"
|
run "+" mkdir -p "build/by-hand"
|
||||||
if check_submodule bzip2; then
|
if check_submodule bzip2; then
|
||||||
test -z "${bzip2_extra_flags+set}" && bzip2_extra_flags=
|
upx_submodule_defs="$upx_submodule_defs -DWITH_BZIP2"
|
||||||
|
test -z "${bzip2_extra_flags+set}" && bzip2_extra_flags="-DBZ_NO_STDIO"
|
||||||
for f in "$rel_top_srcdir"/vendor/bzip2/*.c; do
|
for f in "$rel_top_srcdir"/vendor/bzip2/*.c; do
|
||||||
run "CC $f" $CC $bzip2_extra_flags -c "$f"
|
run "CC $f" $CC $bzip2_extra_flags -c "$f"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if check_submodule ucl; then
|
if check_submodule ucl; then
|
||||||
|
#upx_submodule_defs="$upx_submodule_defs -DWITH_UCL"
|
||||||
|
test -z "${ucl_extra_flags+set}" && ucl_extra_flags=
|
||||||
for f in "$rel_top_srcdir"/vendor/ucl/src/*.c; do
|
for f in "$rel_top_srcdir"/vendor/ucl/src/*.c; do
|
||||||
run "CC $f" $CC -I"$rel_top_srcdir"/vendor/ucl/include -I"$rel_top_srcdir"/vendor/ucl -c "$f"
|
run "CC $f" $CC -I"$rel_top_srcdir"/vendor/ucl/include -I"$rel_top_srcdir"/vendor/ucl $ucl_extra_flags -c "$f"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if check_submodule zlib; then
|
if check_submodule zlib; then
|
||||||
|
#upx_submodule_defs="$upx_submodule_defs -DWITH_ZLIB"
|
||||||
test -z "${zlib_extra_flags+set}" && zlib_extra_flags="-DHAVE_UNISTD_H -DHAVE_VSNPRINTF"
|
test -z "${zlib_extra_flags+set}" && zlib_extra_flags="-DHAVE_UNISTD_H -DHAVE_VSNPRINTF"
|
||||||
for f in "$rel_top_srcdir"/vendor/zlib/*.c; do
|
for f in "$rel_top_srcdir"/vendor/zlib/*.c; do
|
||||||
run "CC $f" $CC $zlib_extra_flags -c "$f"
|
run "CC $f" $CC $zlib_extra_flags -c "$f"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
if check_submodule zstd; then
|
if check_submodule zstd; then
|
||||||
|
upx_submodule_defs="$upx_submodule_defs -DWITH_ZSTD"
|
||||||
test -z "${zstd_extra_flags+set}" && zstd_extra_flags="-DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM"
|
test -z "${zstd_extra_flags+set}" && zstd_extra_flags="-DDYNAMIC_BMI2=0 -DZSTD_DISABLE_ASM"
|
||||||
for f in "$rel_top_srcdir"/vendor/zstd/lib/*/*.c; do
|
for f in "$rel_top_srcdir"/vendor/zstd/lib/*/*.c; do
|
||||||
run "CC $f" $CC $zstd_extra_flags -c "$f"
|
run "CC $f" $CC $zstd_extra_flags -c "$f"
|
||||||
@ -121,15 +132,16 @@ echo "#==== build UPX ====="
|
|||||||
run "+" cd "build/by-hand" || exit 1
|
run "+" cd "build/by-hand" || exit 1
|
||||||
rel_top_srcdir=../..
|
rel_top_srcdir=../..
|
||||||
for f in "$rel_top_srcdir"/src/*.cpp "$rel_top_srcdir"/src/*/*.cpp; do
|
for f in "$rel_top_srcdir"/src/*.cpp "$rel_top_srcdir"/src/*/*.cpp; do
|
||||||
run "CXX $f" $CXX -I"$rel_top_srcdir"/vendor -c "$f"
|
run "CXX $f" $CXX -I"$rel_top_srcdir"/vendor $upx_submodule_defs -c "$f"
|
||||||
done
|
done
|
||||||
# echo "#==== link UPX ====="
|
# echo "#==== link UPX ====="
|
||||||
|
test "x$obj_suffix" = "x" && obj_suffix=.o
|
||||||
if test "x$AR" = "x"; then
|
if test "x$AR" = "x"; then
|
||||||
# link without using $AR
|
# link without using $AR
|
||||||
run "CXX upx" $CXX -o upx *.o */*.o
|
run "CXX upx" $CXX -o upx *${obj_suffix} */*${obj_suffix}
|
||||||
else
|
else
|
||||||
run "AR libupx" $AR rcs ${AR_LIBFILE:-libupx_submodules.a} */*.o
|
run "AR libupx" $AR rcs ${AR_LIBFILE:-libupx_submodules.a} */*${obj_suffix}
|
||||||
run "CXX upx" $CXX -o upx *.o -L. -lupx_submodules
|
run "CXX upx" $CXX -o upx *${obj_suffix} -L. -lupx_submodules
|
||||||
fi
|
fi
|
||||||
echo "# current directory: '$(pwd)'"
|
echo "# current directory: '$(pwd)'"
|
||||||
ls -l upx*
|
ls -l upx*
|
||||||
|
|||||||
@ -62,7 +62,7 @@ unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb, int method, int level, const upx_compress_config_t *cconf,
|
upx_callback_t *cb, int method, int level, const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult) {
|
upx_compress_result_t *cresult) {
|
||||||
int r = UPX_E_ERROR;
|
int r = UPX_E_ERROR;
|
||||||
upx_compress_result_t cresult_buffer;
|
upx_compress_result_t cresult_buffer;
|
||||||
@ -95,6 +95,10 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
|
|||||||
const unsigned orig_dst_len = *dst_len;
|
const unsigned orig_dst_len = *dst_len;
|
||||||
if (__acc_cte(false)) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
else if (M_IS_BZIP2(method))
|
||||||
|
r = upx_bzip2_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
@ -112,7 +116,7 @@ int upx_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned
|
|||||||
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
r = upx_zstd_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown compression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@ -140,6 +144,10 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne
|
|||||||
const unsigned orig_dst_len = *dst_len;
|
const unsigned orig_dst_len = *dst_len;
|
||||||
if (__acc_cte(false)) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
else if (M_IS_BZIP2(method))
|
||||||
|
r = upx_bzip2_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
@ -161,7 +169,7 @@ int upx_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigne
|
|||||||
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
|
r = upx_zstd_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_noexcept(*dst_len <= orig_dst_len);
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
@ -187,6 +195,10 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off
|
|||||||
const unsigned orig_dst_len = *dst_len;
|
const unsigned orig_dst_len = *dst_len;
|
||||||
if (__acc_cte(false)) {
|
if (__acc_cte(false)) {
|
||||||
}
|
}
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
else if (M_IS_BZIP2(method))
|
||||||
|
r = upx_bzip2_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
|
#endif
|
||||||
#if (WITH_LZMA)
|
#if (WITH_LZMA)
|
||||||
else if (M_IS_LZMA(method))
|
else if (M_IS_LZMA(method))
|
||||||
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
@ -204,7 +216,7 @@ int upx_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off
|
|||||||
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
r = upx_zstd_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult);
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
throwInternalError("unknown decompression method");
|
throwInternalError("unknown compression method %d", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_noexcept(*dst_len <= orig_dst_len);
|
assert_noexcept(*dst_len <= orig_dst_len);
|
||||||
|
|||||||
@ -37,7 +37,7 @@ int upx_bzip2_init(void);
|
|||||||
const char *upx_bzip2_version_string(void);
|
const char *upx_bzip2_version_string(void);
|
||||||
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
|
int upx_bzip2_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned *dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
@ -58,7 +58,7 @@ int upx_lzma_init(void);
|
|||||||
const char *upx_lzma_version_string(void);
|
const char *upx_lzma_version_string(void);
|
||||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned *dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
@ -79,7 +79,7 @@ int upx_nrv_init(void);
|
|||||||
const char *upx_nrv_version_string(void);
|
const char *upx_nrv_version_string(void);
|
||||||
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned *dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
@ -100,7 +100,7 @@ int upx_ucl_init(void);
|
|||||||
const char *upx_ucl_version_string(void);
|
const char *upx_ucl_version_string(void);
|
||||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned *dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
@ -123,7 +123,7 @@ int upx_zlib_init(void);
|
|||||||
const char *upx_zlib_version_string(void);
|
const char *upx_zlib_version_string(void);
|
||||||
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
int upx_zlib_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned *dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
@ -146,7 +146,7 @@ int upx_zstd_init(void);
|
|||||||
const char *upx_zstd_version_string(void);
|
const char *upx_zstd_version_string(void);
|
||||||
int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
|
int upx_zstd_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned *dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
|
|||||||
208
src/compress/compress_bzip2.cpp
Normal file
208
src/compress/compress_bzip2.cpp
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/* compress_bzip2.cpp --
|
||||||
|
|
||||||
|
This file is part of the UPX executable compressor.
|
||||||
|
|
||||||
|
Copyright (C) 1996-2023 Markus Franz Xaver Johannes Oberhumer
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
UPX and the UCL library are free software; you can redistribute them
|
||||||
|
and/or modify them under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; see the file COPYING.
|
||||||
|
If not, write to the Free Software Foundation, Inc.,
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
Markus F.X.J. Oberhumer
|
||||||
|
<markus@oberhumer.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
void bzip2_compress_config_t::reset() noexcept { mem_clear(this); }
|
||||||
|
|
||||||
|
#if WITH_BZIP2
|
||||||
|
#include "compress.h"
|
||||||
|
#include "../util/membuffer.h"
|
||||||
|
#include <bzip2/bzlib.h>
|
||||||
|
|
||||||
|
#if defined(BZ_NO_STDIO) || 1
|
||||||
|
// we need to supply bz_internal_error() when building with BZ_NO_STDIO
|
||||||
|
extern "C" {
|
||||||
|
extern void bz_internal_error(int);
|
||||||
|
void bz_internal_error(int errcode) { throwInternalError("bz_internal_error %d", errcode); }
|
||||||
|
}
|
||||||
|
#endif // BZ_NO_STDIO
|
||||||
|
|
||||||
|
static int convert_errno_from_bzip2(int r) {
|
||||||
|
switch (r) {
|
||||||
|
case BZ_OK:
|
||||||
|
return UPX_E_OK;
|
||||||
|
case BZ_MEM_ERROR:
|
||||||
|
return UPX_E_OUT_OF_MEMORY;
|
||||||
|
// TODO later: convert to UPX_E_INPUT_OVERRUN, UPX_E_OUTPUT_OVERRUN
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_BZIP2);
|
||||||
|
assert(level > 0);
|
||||||
|
assert(cresult != nullptr);
|
||||||
|
UNUSED(cb_parm);
|
||||||
|
int r = UPX_E_ERROR;
|
||||||
|
const bzip2_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_bzip2 : nullptr;
|
||||||
|
bzip2_compress_result_t *const res = &cresult->result_bzip2;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
|
int blockSize100k = (src_len + 100000 - 1) / 100000;
|
||||||
|
if (blockSize100k < 1)
|
||||||
|
blockSize100k = 1;
|
||||||
|
if (blockSize100k > 9)
|
||||||
|
blockSize100k = 9;
|
||||||
|
// idea for later: could enhance lcconf to allow setting blockSize100k
|
||||||
|
UNUSED(lcconf);
|
||||||
|
if (level <= 3 && blockSize100k > level)
|
||||||
|
blockSize100k = level;
|
||||||
|
|
||||||
|
char *dest = (char *) dst;
|
||||||
|
char *source = (char *) const_cast<byte *>(src);
|
||||||
|
r = BZ2_bzBuffToBuffCompress(dest, dst_len, source, src_len, blockSize100k, 0, 0);
|
||||||
|
return convert_errno_from_bzip2(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
//
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_decompress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
|
int method, const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_BZIP2);
|
||||||
|
UNUSED(method);
|
||||||
|
UNUSED(cresult);
|
||||||
|
char *dest = (char *) dst;
|
||||||
|
char *source = (char *) const_cast<byte *>(src);
|
||||||
|
int small = 0;
|
||||||
|
int r = BZ2_bzBuffToBuffDecompress(dest, dst_len, source, src_len, small, 0);
|
||||||
|
return convert_errno_from_bzip2(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// test_overlap - see <ucl/ucl.h> for semantics
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_test_overlap(const upx_bytep buf, const upx_bytep tbuf, unsigned src_off,
|
||||||
|
unsigned src_len, unsigned *dst_len, int method,
|
||||||
|
const upx_compress_result_t *cresult) {
|
||||||
|
assert(method == M_BZIP2);
|
||||||
|
|
||||||
|
MemBuffer b(src_off + src_len);
|
||||||
|
memcpy(b + src_off, buf + src_off, src_len);
|
||||||
|
unsigned saved_dst_len = *dst_len;
|
||||||
|
int r = upx_bzip2_decompress(raw_index_bytes(b, src_off, src_len), src_len,
|
||||||
|
raw_bytes(b, *dst_len), dst_len, method, cresult);
|
||||||
|
if (r != UPX_E_OK)
|
||||||
|
return r;
|
||||||
|
if (*dst_len != saved_dst_len)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
// NOTE: there is a very tiny possibility that decompression has
|
||||||
|
// succeeded but the data is not restored correctly because of
|
||||||
|
// in-place buffer overlapping, so we use an extra memcmp().
|
||||||
|
if (tbuf != nullptr && memcmp(tbuf, b, *dst_len) != 0)
|
||||||
|
return UPX_E_ERROR;
|
||||||
|
return UPX_E_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// misc
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
int upx_bzip2_init(void) { return 0; }
|
||||||
|
|
||||||
|
const char *upx_bzip2_version_string(void) { return BZ2_bzlibVersion(); }
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
// doctest checks
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#if DEBUG && !defined(DOCTEST_CONFIG_DISABLE) && 1
|
||||||
|
|
||||||
|
static bool check_bzip2(const int method, const int level, const unsigned expected_c_len) {
|
||||||
|
const unsigned u_len = 16384;
|
||||||
|
const unsigned c_extra = 4096;
|
||||||
|
MemBuffer u_buf, c_buf, d_buf;
|
||||||
|
unsigned c_len, d_len;
|
||||||
|
upx_compress_result_t cresult;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
u_buf.alloc(u_len);
|
||||||
|
memset(u_buf, 0, u_len);
|
||||||
|
c_buf.allocForCompression(u_len, c_extra);
|
||||||
|
d_buf.allocForDecompression(u_len);
|
||||||
|
|
||||||
|
c_len = c_buf.getSize() - c_extra;
|
||||||
|
r = upx_bzip2_compress(raw_bytes(u_buf, u_len), u_len, raw_index_bytes(c_buf, c_extra, c_len),
|
||||||
|
&c_len, nullptr, method, level, NULL_cconf, &cresult);
|
||||||
|
if (r != 0 || c_len != expected_c_len)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = d_buf.getSize();
|
||||||
|
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r != 0 || d_len != u_len || memcmp(u_buf, d_buf, u_len) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
d_len = u_len - 1;
|
||||||
|
r = upx_bzip2_decompress(raw_index_bytes(c_buf, c_extra, c_len), c_len, raw_bytes(d_buf, d_len),
|
||||||
|
&d_len, method, nullptr);
|
||||||
|
if (r == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: rewrite Packer::findOverlapOverhead() so that we can test it here
|
||||||
|
// unsigned x_len = d_len;
|
||||||
|
// r = upx_bzip2_test_overlap(c_buf, u_buf, c_extra, c_len, &x_len, method, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("compress_bzip2") { CHECK(check_bzip2(M_BZIP2, 9, 46)); }
|
||||||
|
|
||||||
|
#endif // DEBUG
|
||||||
|
|
||||||
|
TEST_CASE("upx_bzip2_decompress") {
|
||||||
|
#if 0 // TODO later, see above
|
||||||
|
const byte *c_data;
|
||||||
|
byte d_buf[32];
|
||||||
|
unsigned d_len;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
c_data = (const byte *) "\x28\xb5\x2f\xfd\x20\x20\x3d\x00\x00\x08\xff\x01\x00\x34\x4e\x08";
|
||||||
|
d_len = 32;
|
||||||
|
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
|
||||||
|
CHECK((r == 0 && d_len == 32));
|
||||||
|
r = upx_bzip2_decompress(c_data, 15, d_buf, &d_len, M_BZIP2, nullptr);
|
||||||
|
CHECK(r == UPX_E_INPUT_OVERRUN);
|
||||||
|
d_len = 31;
|
||||||
|
r = upx_bzip2_decompress(c_data, 16, d_buf, &d_len, M_BZIP2, nullptr);
|
||||||
|
CHECK(r == UPX_E_OUTPUT_OVERRUN);
|
||||||
|
UNUSED(r);
|
||||||
|
#endif // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WITH_BZIP2
|
||||||
|
|
||||||
|
/* vim:set ts=4 sw=4 et: */
|
||||||
@ -293,7 +293,7 @@ struct ProgressInfo final : public ICompressProgressInfo, public CMyUnknownImp {
|
|||||||
virtual ~ProgressInfo() {}
|
virtual ~ProgressInfo() {}
|
||||||
MY_UNKNOWN_IMP
|
MY_UNKNOWN_IMP
|
||||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize) override;
|
||||||
upx_callback_p cb = nullptr;
|
upx_callback_t *cb = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
|
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) {
|
||||||
@ -317,7 +317,7 @@ STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outS
|
|||||||
#undef RC_NORMALIZE
|
#undef RC_NORMALIZE
|
||||||
|
|
||||||
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb, int method, int level,
|
upx_callback_t *cb, int method, int level,
|
||||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
assert(M_IS_LZMA(method));
|
assert(M_IS_LZMA(method));
|
||||||
assert(level > 0);
|
assert(level > 0);
|
||||||
@ -327,6 +327,7 @@ int upx_lzma_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
|
|||||||
HRESULT rh;
|
HRESULT rh;
|
||||||
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
const lzma_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_lzma : nullptr;
|
||||||
lzma_compress_result_t *const res = &cresult->result_lzma;
|
lzma_compress_result_t *const res = &cresult->result_lzma;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
MyLzma::InStream is;
|
MyLzma::InStream is;
|
||||||
is.AddRef();
|
is.AddRef();
|
||||||
|
|||||||
@ -66,7 +66,7 @@ extern "C" {
|
|||||||
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
|
static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user) {
|
||||||
if (state != -1 && state != 3)
|
if (state != -1 && state != 3)
|
||||||
return;
|
return;
|
||||||
upx_callback_p cb = (upx_callback_p) user;
|
upx_callback_t *cb = (upx_callback_t *) user;
|
||||||
if (cb && cb->nprogress)
|
if (cb && cb->nprogress)
|
||||||
cb->nprogress(cb, a, b);
|
cb->nprogress(cb, a, b);
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ static void __UCL_CDECL wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, uc
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
int upx_ucl_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb_parm, int method, int level,
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
int r;
|
int r;
|
||||||
assert(level > 0);
|
assert(level > 0);
|
||||||
|
|||||||
@ -75,7 +75,7 @@ static int convert_errno_from_zlib(int zr) {
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb_parm, int method, int level,
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
assert(method == M_DEFLATE);
|
assert(method == M_DEFLATE);
|
||||||
assert(level > 0);
|
assert(level > 0);
|
||||||
@ -85,6 +85,7 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
|
|||||||
int zr;
|
int zr;
|
||||||
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
const zlib_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zlib : nullptr;
|
||||||
zlib_compress_result_t *const res = &cresult->result_zlib;
|
zlib_compress_result_t *const res = &cresult->result_zlib;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
if (level == 10)
|
if (level == 10)
|
||||||
level = 9;
|
level = 9;
|
||||||
@ -99,8 +100,6 @@ int upx_zlib_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
|
|||||||
oassign(strategy, lcconf->strategy);
|
oassign(strategy, lcconf->strategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
res->dummy = 0;
|
|
||||||
|
|
||||||
z_stream s;
|
z_stream s;
|
||||||
s.zalloc = (alloc_func) nullptr;
|
s.zalloc = (alloc_func) nullptr;
|
||||||
s.zfree = (free_func) nullptr;
|
s.zfree = (free_func) nullptr;
|
||||||
|
|||||||
@ -55,7 +55,7 @@ static int convert_errno_from_zstd(size_t zr) {
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb_parm, int method, int level,
|
upx_callback_t *cb_parm, int method, int level,
|
||||||
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
const upx_compress_config_t *cconf_parm, upx_compress_result_t *cresult) {
|
||||||
assert(method == M_ZSTD);
|
assert(method == M_ZSTD);
|
||||||
assert(level > 0);
|
assert(level > 0);
|
||||||
@ -65,6 +65,7 @@ int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
|
|||||||
size_t zr;
|
size_t zr;
|
||||||
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
|
const zstd_compress_config_t *const lcconf = cconf_parm ? &cconf_parm->conf_zstd : nullptr;
|
||||||
zstd_compress_result_t *const res = &cresult->result_zstd;
|
zstd_compress_result_t *const res = &cresult->result_zstd;
|
||||||
|
res->reset();
|
||||||
|
|
||||||
// TODO later: map level 1..10 to zstd-level 1..22
|
// TODO later: map level 1..10 to zstd-level 1..22
|
||||||
if (level == 10)
|
if (level == 10)
|
||||||
@ -75,8 +76,6 @@ int upx_zstd_compress(const upx_bytep src, unsigned src_len, upx_bytep dst, unsi
|
|||||||
UNUSED(lcconf);
|
UNUSED(lcconf);
|
||||||
}
|
}
|
||||||
|
|
||||||
res->dummy = 0;
|
|
||||||
|
|
||||||
zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
|
zr = ZSTD_compress(dst, *dst_len, src, src_len, level);
|
||||||
if (ZSTD_isError(zr)) {
|
if (ZSTD_isError(zr)) {
|
||||||
*dst_len = 0; // TODO ???
|
*dst_len = 0; // TODO ???
|
||||||
|
|||||||
47
src/conf.h
47
src/conf.h
@ -154,7 +154,7 @@ typedef unsigned char uchar;
|
|||||||
// convention: use "charptr" when dealing with abstract pointer arithmetics
|
// convention: use "charptr" when dealing with abstract pointer arithmetics
|
||||||
#define charptr upx_charptr_unit_type *
|
#define charptr upx_charptr_unit_type *
|
||||||
// upx_charptr_unit_type is some opaque type with sizeof(type) == 1
|
// upx_charptr_unit_type is some opaque type with sizeof(type) == 1
|
||||||
struct alignas(1) upx_charptr_unit_type { char hidden__; };
|
struct alignas(1) upx_charptr_unit_type final { char hidden__; };
|
||||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1)
|
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(upx_charptr_unit_type) == 1)
|
||||||
|
|
||||||
// using the system off_t was a bad idea even back in 199x...
|
// using the system off_t was a bad idea even back in 199x...
|
||||||
@ -576,6 +576,7 @@ using upx::tribool;
|
|||||||
#define M_LZMA 14
|
#define M_LZMA 14
|
||||||
#define M_DEFLATE 15 // zlib
|
#define M_DEFLATE 15 // zlib
|
||||||
#define M_ZSTD 16
|
#define M_ZSTD 16
|
||||||
|
#define M_BZIP2 17
|
||||||
// compression methods internal usage
|
// compression methods internal usage
|
||||||
#define M_ALL (-1)
|
#define M_ALL (-1)
|
||||||
#define M_END (-2)
|
#define M_END (-2)
|
||||||
@ -590,6 +591,7 @@ using upx::tribool;
|
|||||||
#define M_IS_LZMA(x) (((x) &255) == M_LZMA)
|
#define M_IS_LZMA(x) (((x) &255) == M_LZMA)
|
||||||
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
#define M_IS_DEFLATE(x) ((x) == M_DEFLATE)
|
||||||
#define M_IS_ZSTD(x) ((x) == M_ZSTD)
|
#define M_IS_ZSTD(x) ((x) == M_ZSTD)
|
||||||
|
#define M_IS_BZIP2(x) ((x) == M_BZIP2)
|
||||||
|
|
||||||
// filters internal usage
|
// filters internal usage
|
||||||
#define FT_END (-1)
|
#define FT_END (-1)
|
||||||
@ -613,10 +615,9 @@ using upx::tribool;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct upx_callback_t;
|
struct upx_callback_t;
|
||||||
typedef upx_callback_t *upx_callback_p;
|
typedef void(__acc_cdecl *upx_progress_func_t)(upx_callback_t *, unsigned, unsigned);
|
||||||
typedef void(__acc_cdecl *upx_progress_func_t)(upx_callback_p, unsigned, unsigned);
|
|
||||||
|
|
||||||
struct upx_callback_t {
|
struct upx_callback_t final {
|
||||||
upx_progress_func_t nprogress;
|
upx_progress_func_t nprogress;
|
||||||
void *user;
|
void *user;
|
||||||
|
|
||||||
@ -627,7 +628,13 @@ struct upx_callback_t {
|
|||||||
// compression - config_t
|
// compression - config_t
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
struct lzma_compress_config_t {
|
struct bzip2_compress_config_t final {
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lzma_compress_config_t final {
|
||||||
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
|
typedef OptVar<unsigned, 2u, 0u, 4u> pos_bits_t; // pb
|
||||||
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp
|
typedef OptVar<unsigned, 0u, 0u, 4u> lit_pos_bits_t; // lp
|
||||||
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
|
typedef OptVar<unsigned, 3u, 0u, 8u> lit_context_bits_t; // lc
|
||||||
@ -647,11 +654,11 @@ struct lzma_compress_config_t {
|
|||||||
void reset() noexcept;
|
void reset() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ucl_compress_config_t : public REAL_ucl_compress_config_t {
|
struct ucl_compress_config_t final : public REAL_ucl_compress_config_t {
|
||||||
void reset() noexcept { memset(this, 0xff, sizeof(*this)); }
|
void reset() noexcept { memset(this, 0xff, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zlib_compress_config_t {
|
struct zlib_compress_config_t final {
|
||||||
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
typedef OptVar<unsigned, 8u, 1u, 9u> mem_level_t; // ml
|
||||||
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
|
typedef OptVar<unsigned, 15u, 9u, 15u> window_bits_t; // wb
|
||||||
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
|
typedef OptVar<unsigned, 0u, 0u, 4u> strategy_t; // st
|
||||||
@ -663,19 +670,21 @@ struct zlib_compress_config_t {
|
|||||||
void reset() noexcept;
|
void reset() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zstd_compress_config_t {
|
struct zstd_compress_config_t final {
|
||||||
unsigned dummy;
|
unsigned dummy;
|
||||||
|
|
||||||
void reset() noexcept;
|
void reset() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct upx_compress_config_t {
|
struct upx_compress_config_t final {
|
||||||
|
bzip2_compress_config_t conf_bzip2;
|
||||||
lzma_compress_config_t conf_lzma;
|
lzma_compress_config_t conf_lzma;
|
||||||
ucl_compress_config_t conf_ucl;
|
ucl_compress_config_t conf_ucl;
|
||||||
zlib_compress_config_t conf_zlib;
|
zlib_compress_config_t conf_zlib;
|
||||||
zstd_compress_config_t conf_zstd;
|
zstd_compress_config_t conf_zstd;
|
||||||
|
|
||||||
void reset() noexcept {
|
void reset() noexcept {
|
||||||
|
conf_bzip2.reset();
|
||||||
conf_lzma.reset();
|
conf_lzma.reset();
|
||||||
conf_ucl.reset();
|
conf_ucl.reset();
|
||||||
conf_zlib.reset();
|
conf_zlib.reset();
|
||||||
@ -689,7 +698,13 @@ struct upx_compress_config_t {
|
|||||||
// compression - result_t
|
// compression - result_t
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
struct lzma_compress_result_t {
|
struct bzip2_compress_result_t final {
|
||||||
|
unsigned dummy;
|
||||||
|
|
||||||
|
void reset() noexcept { mem_clear(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lzma_compress_result_t final {
|
||||||
unsigned pos_bits; // pb
|
unsigned pos_bits; // pb
|
||||||
unsigned lit_pos_bits; // lp
|
unsigned lit_pos_bits; // lp
|
||||||
unsigned lit_context_bits; // lc
|
unsigned lit_context_bits; // lc
|
||||||
@ -702,25 +717,25 @@ struct lzma_compress_result_t {
|
|||||||
void reset() noexcept { mem_clear(this); }
|
void reset() noexcept { mem_clear(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ucl_compress_result_t {
|
struct ucl_compress_result_t final {
|
||||||
ucl_uint result[16];
|
ucl_uint result[16];
|
||||||
|
|
||||||
void reset() noexcept { mem_clear(this); }
|
void reset() noexcept { mem_clear(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zlib_compress_result_t {
|
struct zlib_compress_result_t final {
|
||||||
unsigned dummy;
|
unsigned dummy;
|
||||||
|
|
||||||
void reset() noexcept { mem_clear(this); }
|
void reset() noexcept { mem_clear(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zstd_compress_result_t {
|
struct zstd_compress_result_t final {
|
||||||
unsigned dummy;
|
unsigned dummy;
|
||||||
|
|
||||||
void reset() noexcept { mem_clear(this); }
|
void reset() noexcept { mem_clear(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct upx_compress_result_t {
|
struct upx_compress_result_t final {
|
||||||
// debugging aid
|
// debugging aid
|
||||||
struct Debug {
|
struct Debug {
|
||||||
int method, level;
|
int method, level;
|
||||||
@ -729,6 +744,7 @@ struct upx_compress_result_t {
|
|||||||
};
|
};
|
||||||
Debug debug;
|
Debug debug;
|
||||||
|
|
||||||
|
bzip2_compress_result_t result_bzip2;
|
||||||
lzma_compress_result_t result_lzma;
|
lzma_compress_result_t result_lzma;
|
||||||
ucl_compress_result_t result_ucl;
|
ucl_compress_result_t result_ucl;
|
||||||
zlib_compress_result_t result_zlib;
|
zlib_compress_result_t result_zlib;
|
||||||
@ -736,6 +752,7 @@ struct upx_compress_result_t {
|
|||||||
|
|
||||||
void reset() noexcept {
|
void reset() noexcept {
|
||||||
debug.reset();
|
debug.reset();
|
||||||
|
result_bzip2.reset();
|
||||||
result_lzma.reset();
|
result_lzma.reset();
|
||||||
result_ucl.reset();
|
result_ucl.reset();
|
||||||
result_zlib.reset();
|
result_zlib.reset();
|
||||||
@ -803,7 +820,7 @@ unsigned upx_crc32 (const void *buf, unsigned len, unsigned crc = 0);
|
|||||||
|
|
||||||
int upx_compress ( const upx_bytep src, unsigned src_len,
|
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||||
upx_bytep dst, unsigned *dst_len,
|
upx_bytep dst, unsigned *dst_len,
|
||||||
upx_callback_p cb,
|
upx_callback_t *cb,
|
||||||
int method, int level,
|
int method, int level,
|
||||||
const upx_compress_config_t *cconf,
|
const upx_compress_config_t *cconf,
|
||||||
upx_compress_result_t *cresult );
|
upx_compress_result_t *cresult );
|
||||||
|
|||||||
@ -150,7 +150,7 @@ void throwCantPack(const char *format, ...) {
|
|||||||
char msg[1024];
|
char msg[1024];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap);
|
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
throwCantPack(msg);
|
throwCantPack(msg);
|
||||||
}
|
}
|
||||||
@ -160,7 +160,17 @@ void throwCantUnpack(const char *format, ...) {
|
|||||||
char msg[1024];
|
char msg[1024];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
(void) upx_safe_vsnprintf(msg, sizeof(msg), format, ap);
|
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
throwCantUnpack(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void throwInternalError(const char *format, ...) {
|
||||||
|
char msg[1024];
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
(void) upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
throwCantUnpack(msg);
|
throwCantUnpack(msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -212,6 +212,10 @@ template <class T>
|
|||||||
void throwCantUnpack(const T *, ...) DELETED_FUNCTION;
|
void throwCantUnpack(const T *, ...) DELETED_FUNCTION;
|
||||||
template <>
|
template <>
|
||||||
NORET void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2);
|
NORET void throwCantUnpack(const char *format, ...) may_throw attribute_format(1, 2);
|
||||||
|
template <class T>
|
||||||
|
void throwInternalError(const T *, ...) DELETED_FUNCTION;
|
||||||
|
template <>
|
||||||
|
NORET void throwInternalError(const char *format, ...) may_throw attribute_format(1, 2);
|
||||||
|
|
||||||
#undef NORET
|
#undef NORET
|
||||||
|
|
||||||
|
|||||||
@ -411,6 +411,11 @@ void show_version(bool one_line) {
|
|||||||
if (v != nullptr && v[0])
|
if (v != nullptr && v[0])
|
||||||
fprintf(f, "zstd data compression library %s\n", v);
|
fprintf(f, "zstd data compression library %s\n", v);
|
||||||
#endif
|
#endif
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
v = upx_bzip2_version_string();
|
||||||
|
if (v != nullptr && v[0])
|
||||||
|
fprintf(f, "bzip2 data compression library %s\n", v);
|
||||||
|
#endif
|
||||||
#if !defined(DOCTEST_CONFIG_DISABLE)
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
fprintf(f, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
|
fprintf(f, "doctest C++ testing framework version %s\n", DOCTEST_VERSION_STR);
|
||||||
#endif
|
#endif
|
||||||
@ -429,6 +434,9 @@ void show_version(bool one_line) {
|
|||||||
// see vendor/zstd/LICENSE; main author is Yann Collet
|
// see vendor/zstd/LICENSE; main author is Yann Collet
|
||||||
fprintf(f, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n");
|
fprintf(f, "Copyright (C) 2015" "-2023 Meta Platforms, Inc. and affiliates\n");
|
||||||
#endif
|
#endif
|
||||||
|
#if (WITH_BZIP2)
|
||||||
|
fprintf(f, "Copyright (C) 1996" "-2010 Julian Seward\n"); // see <bzlib.h>
|
||||||
|
#endif
|
||||||
#if !defined(DOCTEST_CONFIG_DISABLE)
|
#if !defined(DOCTEST_CONFIG_DISABLE)
|
||||||
fprintf(f, "Copyright (C) 2016" "-2023 Viktor Kirilov\n");
|
fprintf(f, "Copyright (C) 2016" "-2023 Viktor Kirilov\n");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -354,7 +354,7 @@ void UiPacker::endCallback(bool done) {
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
void __acc_cdecl UiPacker::progress_callback(upx_callback_p cb, unsigned isize, unsigned osize) {
|
void __acc_cdecl UiPacker::progress_callback(upx_callback_t *cb, unsigned isize, unsigned osize) {
|
||||||
// printf("%6d %6d %d\n", isize, osize, state);
|
// printf("%6d %6d %d\n", isize, osize, state);
|
||||||
UiPacker *self = (UiPacker *) cb->user;
|
UiPacker *self = (UiPacker *) cb->user;
|
||||||
self->doCallback(isize, osize);
|
self->doCallback(isize, osize);
|
||||||
|
|||||||
2
src/ui.h
2
src/ui.h
@ -69,7 +69,7 @@ public:
|
|||||||
virtual upx_callback_t *getCallback() { return &cb; }
|
virtual upx_callback_t *getCallback() { return &cb; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void __acc_cdecl progress_callback(upx_callback_p cb, unsigned, unsigned);
|
static void __acc_cdecl progress_callback(upx_callback_t *, unsigned, unsigned);
|
||||||
virtual void doCallback(unsigned isize, unsigned osize);
|
virtual void doCallback(unsigned isize, unsigned osize);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@ -40,6 +40,15 @@ upx_rsize_t upx_safe_strlen(const char *s) {
|
|||||||
#define strlen upx_safe_strlen
|
#define strlen upx_safe_strlen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
upx_rsize_t upx_safe_strlen_noexcept(const char *s) noexcept {
|
||||||
|
#undef strlen
|
||||||
|
assert_noexcept(s != nullptr);
|
||||||
|
size_t len = strlen(s);
|
||||||
|
assert_noexcept(len < UPX_RSIZE_MAX_STR);
|
||||||
|
return len;
|
||||||
|
#define strlen upx_safe_strlen
|
||||||
|
}
|
||||||
|
|
||||||
int upx_safe_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) {
|
int upx_safe_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_list ap) {
|
||||||
#undef vsnprintf
|
#undef vsnprintf
|
||||||
size_t size;
|
size_t size;
|
||||||
@ -68,6 +77,35 @@ int upx_safe_vsnprintf(char *str, upx_rsize_t max_size, const char *format, va_l
|
|||||||
#define vsnprintf upx_safe_vsnprintf
|
#define vsnprintf upx_safe_vsnprintf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int upx_safe_vsnprintf_noexcept(char *str, upx_rsize_t max_size, const char *format,
|
||||||
|
va_list ap) noexcept {
|
||||||
|
#undef vsnprintf
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
// preconditions
|
||||||
|
assert_noexcept(max_size <= UPX_RSIZE_MAX_STR);
|
||||||
|
if (str != nullptr)
|
||||||
|
assert_noexcept(max_size > 0);
|
||||||
|
else
|
||||||
|
assert_noexcept(max_size == 0);
|
||||||
|
|
||||||
|
long long len = vsnprintf(str, max_size, format, ap);
|
||||||
|
assert_noexcept(len >= 0);
|
||||||
|
assert_noexcept(len < UPX_RSIZE_MAX_STR);
|
||||||
|
size = (size_t) len + 1;
|
||||||
|
|
||||||
|
// postconditions
|
||||||
|
assert_noexcept(size > 0);
|
||||||
|
assert_noexcept(size <= UPX_RSIZE_MAX_STR);
|
||||||
|
if (str != nullptr) {
|
||||||
|
assert_noexcept(size <= max_size);
|
||||||
|
assert_noexcept(str[size - 1] == '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return ACC_ICONV(int, size - 1); // snprintf() returns length, not size
|
||||||
|
#define vsnprintf upx_safe_vsnprintf
|
||||||
|
}
|
||||||
|
|
||||||
int upx_safe_snprintf(char *str, upx_rsize_t max_size, const char *format, ...) {
|
int upx_safe_snprintf(char *str, upx_rsize_t max_size, const char *format, ...) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int len;
|
int len;
|
||||||
|
|||||||
@ -46,6 +46,11 @@ char *upx_safe_xprintf(const char *format, ...) attribute_format(1, 2);
|
|||||||
|
|
||||||
upx_rsize_t upx_safe_strlen(const char *);
|
upx_rsize_t upx_safe_strlen(const char *);
|
||||||
|
|
||||||
|
// noexcept variants (these use "assert_noexcept")
|
||||||
|
int upx_safe_vsnprintf_noexcept(char *str, upx_rsize_t max_size, const char *format,
|
||||||
|
va_list ap) noexcept;
|
||||||
|
upx_rsize_t upx_safe_strlen_noexcept(const char *) noexcept;
|
||||||
|
|
||||||
// globally redirect some functions
|
// globally redirect some functions
|
||||||
#undef strlen
|
#undef strlen
|
||||||
#define strlen upx_safe_strlen
|
#define strlen upx_safe_strlen
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user