From c378131c18c90ae8592bff09681b30f6d6d181e9 Mon Sep 17 00:00:00 2001 From: Pavel Shevaev Date: Wed, 7 May 2025 12:15:25 +0300 Subject: [PATCH] Adding bundle patching support for fmt1 --- pack.inc.php | 99 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 13 deletions(-) diff --git a/pack.inc.php b/pack.inc.php index e78d2d8..2e665c3 100644 --- a/pack.inc.php +++ b/pack.inc.php @@ -92,7 +92,17 @@ function config_patch_bundle(ConfigPackParams $params, string $packed_data) : st $patched_data = null; - if($params->binary_format == 2) + if($params->binary_format == 1) + { + $patched_data = _config_patch_bundle_fmt1( + $packed_data, + $params->cache_entries, + $params->use_lz4, + $params->use_config_refs, + $params->version, + ); + } + else if($params->binary_format == 2) { $patched_data = _config_patch_bundle_fmt2( $packed_data, @@ -158,12 +168,12 @@ function _config_pack_bundle_fmt1( $STRIDMAP[$strid_crc] = $entry->strid; $header[] = array( - $payloads[$idx][2], + $payloads[$idx][2], //format $entry->id, crc32($entry->strid), $entry->class_id, - $payloads[$idx][0], - $payloads[$idx][3] + $payloads[$idx][0], //offset + $payloads[$idx][3] //size ); } @@ -344,12 +354,72 @@ function _config_encode_strid_as_indices(string $strid, array &$STRIDMAP, array return $strids_indices; } +function _config_patch_bundle_fmt1( + string $packed_data, + array $patch_entries, + bool $use_lz4, + bool $use_config_refs, + int $version +) : string +{ + list($header, $_, $payloads_bundle) = + _config_unpack_bundle_fmt1(packed_data: $packed_data, unpack_entries: false); + + foreach($patch_entries as $idx => $patch_entry) + { + list($patch_format, $patch_payload) = _config_get_payload($patch_entry, $use_lz4, $use_config_refs); + + $headers_found = array_filter($header, fn($item) => $item[1] == $patch_entry->id); + if($headers_found) + { + $header_idx = key($headers_found); + $header_entry = current($headers_found); + + $current_offset = $header_entry[4]; + $current_size = $header_entry[5]; + + if($current_size >= strlen($patch_payload)) + { + //let's do the inline patching + $payloads_bundle = substr_replace($payloads_bundle, $patch_payload, $current_offset, strlen($patch_payload)); + + $header_entry[0] = $patch_format; + $header_entry[5] = strlen($patch_payload); + $header[$header_idx] = $header_entry; + } + else + { + //let's add it to the end + $header_entry[0] = $patch_format; + $header_entry[4] = strlen($payloads_bundle); //offset + $header_entry[5] = strlen($patch_payload); + $header[$header_idx] = $header_entry; + + $payloads_bundle .= $patch_payload; + } + } + else + throw new Exception("Patched entry {$patch_entry->id} not found in config bundle"); + } + + $header_msgpack = config_msgpack_pack($header); + + $patched_data = + pack("C", 1) . + pack("V", $version) . + pack("V", strlen($header_msgpack)) . + $header_msgpack . + $payloads_bundle; + + return $patched_data; +} + function _config_patch_bundle_fmt2( string $packed_data, array $patch_entries, bool $use_lz4, bool $use_config_refs, - int $version, + int $version ) : string { list($strids, $header, $_, $payloads_bundle) = @@ -523,7 +593,8 @@ function config_unpack_bundle(string $packed_data) : array if($info['format'] === 1) { - return _config_unpack_bundle_fmt1($packed_data); + list($_, $entries) = _config_unpack_bundle_fmt1($packed_data); + return $entries; } else if($info['format'] === 2) { @@ -539,7 +610,7 @@ function config_unpack_bundle(string $packed_data) : array throw new Exception("Unknown format: {$info['format']}"); } -function _config_unpack_bundle_fmt1(string $packed_data) : array +function _config_unpack_bundle_fmt1(string $packed_data, bool $unpack_entries = true) : array { $packed_info = substr($packed_data, 0, 1+4+4); @@ -554,16 +625,19 @@ function _config_unpack_bundle_fmt1(string $packed_data) : array $payloads_bundle = substr($packed_data, 1+4+4+$info['header_len']); $entries = array(); - foreach($header as $item) + if($unpack_entries) { - list($format, $id, $strid_crc, $class_id, $offset, $size) = $item; + foreach($header as $item) + { + list($format, $id, $strid_crc, $class_id, $offset, $size) = $item; - $payload = substr($payloads_bundle, $offset, $size); + $payload = substr($payloads_bundle, $offset, $size); - $entries[$id] = array($class_id, _config_unpack_payload($format, $payload)); + $entries[$id] = array($class_id, _config_unpack_payload($format, $payload)); + } } - return $entries; + return array($header, $entries, $unpack_entries ? null : $payloads_bundle); } function _config_unpack_bundle_fmt2(string $packed_data, bool $unpack_entries = true) : array @@ -584,7 +658,6 @@ function _config_unpack_bundle_fmt2(string $packed_data, bool $unpack_entries = $payloads_bundle = substr($packed_data, 1+4+4+4+$info['strids_len']+$info['header_len']); $entries = array(); - if($unpack_entries) { foreach($header as $item)