From cce8b4d15e080164c3194e7e8b73270518e93100 Mon Sep 17 00:00:00 2001 From: Winford Date: Fri, 23 May 2025 19:55:38 +0000 Subject: [PATCH] Support OTP-28 uncompressed literals Handle new OTP-28 uncompressed literals when running on OTP 28 and later, continues to support zlib compression for literals with earlier OTP versions. Adds OTP-28 to the workflow test matrix. Closes #30 Signed-off-by: Winford --- .github/workflows/build-and-test.yaml | 2 +- CHANGELOG.md | 2 +- src/packbeam_api.erl | 32 ++++++++++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index b94118c..8ce0475 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -13,7 +13,7 @@ jobs: runs-on: "ubuntu-24.04" strategy: matrix: - otp: ["25", "26", "27"] + otp: ["25", "26", "27", "28"] steps: # Setup diff --git a/CHANGELOG.md b/CHANGELOG.md index 7de9c57..4b6b58d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.7.4] - Unreleased - +- Add support for OTP-28 ## [0.7.3] (2024.06.06) diff --git a/src/packbeam_api.erl b/src/packbeam_api.erl index 1f93d2b..3d1dc29 100644 --- a/src/packbeam_api.erl +++ b/src/packbeam_api.erl @@ -586,7 +586,7 @@ filter_modules(Modules, ParsedFiles) -> %% @private parse_file(beam, _ModuleName, Data, IncludeLines) -> {ok, Module, Chunks} = beam_lib:all_chunks(Data), - {UncompressedChunks, UncompressedLiterals} = uncompress_literals(Chunks), + {UncompressedChunks, UncompressedLiterals} = maybe_uncompress_literals(Chunks), FilteredChunks = filter_chunks(UncompressedChunks, IncludeLines), {ok, Binary} = beam_lib:build_module(FilteredChunks), {ok, {Module, ChunkRefs}} = beam_lib:chunks(Data, [imports, exports, atoms]), @@ -707,23 +707,29 @@ strip_padding(Data) -> Data. %% @private -uncompress_literals(Chunks) -> +maybe_uncompress_literals(Chunks) -> case proplists:get_value("LitT", Chunks) of undefined -> {Chunks, undefined}; - <<_Header:4/binary, Data/binary>> -> - UncompressedData = zlib:uncompress(Data), - { - lists:keyreplace( - "LitT", - 1, - Chunks, - {"LitU", UncompressedData} - ), - UncompressedData - } + <<0:32, Data/binary>> -> + {Chunks, Data}; + <<_Size:4/binary, Data/binary>> -> + do_uncompress_literals(Chunks, Data) end. +%% @private +do_uncompress_literals(Chunks, Data) -> + UncompressedData = zlib:uncompress(Data), + { + lists:keyreplace( + "LitT", + 1, + Chunks, + {"LitU", UncompressedData} + ), + UncompressedData + }. + %% @private write_packbeam(OutputFilePath, ParsedFiles) -> PackedData =