{"app_name":"Debian Janitor","binary_packages":["amqp-tools-dbgsym","amqp-tools","librabbitmq-dev","librabbitmq4-dbgsym","librabbitmq4"],"branch_url":"git+ssh://git@salsa.debian.org/debian/librabbitmq.git","build_distribution":"sid","build_log_highlight_lines":[],"build_log_line_count":2635,"build_log_name":"build.log","campaign":"control","change_set":"cc47cc1c-177a-4056-9f6d-86bc9b10581c","codebase":"librabbitmq","codemod_log_name":"codemod.log","command":"brz up '--revision=git-v1:c06a1c0c5de743a97d937add52a81121828d8317'","current_year":"2026","description":"","is_admin":false,"lintian_result":{"groups":[{"group_id":"librabbitmq_0.15.0-1~jan+control1","input_files":[{"hints":[],"path":"amqp-tools-dbgsym_0.15.0-1~jan+control1_amd64.deb"},{"hints":[{"experimental":false,"note":"control != sid","pointer":{"item":{"index":"amqp-tools_0.15.0-1~jan+control1_amd64.deb (installed)","name":"usr/share/doc/amqp-tools/changelog.Debian.gz"},"line_position":1},"tag":"changelog-distribution-does-not-match-changes-file","visibility":"warning"}],"path":"amqp-tools_0.15.0-1~jan+control1_amd64.deb"},{"hints":[{"experimental":false,"note":"control != sid","pointer":{"item":{"index":"librabbitmq-dev_0.15.0-1~jan+control1_amd64.deb (installed)","name":"usr/share/doc/librabbitmq-dev/changelog.Debian.gz"},"line_position":1},"tag":"changelog-distribution-does-not-match-changes-file","visibility":"warning"}],"path":"librabbitmq-dev_0.15.0-1~jan+control1_amd64.deb"},{"hints":[],"path":"librabbitmq4-dbgsym_0.15.0-1~jan+control1_amd64.deb"},{"hints":[{"experimental":false,"note":"control != sid","pointer":{"item":{"index":"librabbitmq4_0.15.0-1~jan+control1_amd64.deb (installed)","name":"usr/share/doc/librabbitmq4/changelog.Debian.gz"},"line_position":1},"tag":"changelog-distribution-does-not-match-changes-file","visibility":"warning"}],"path":"librabbitmq4_0.15.0-1~jan+control1_amd64.deb"},{"hints":[{"experimental":false,"note":"","pointer":{"item":{"index":"librabbitmq_0.15.0-1~jan+control1.dsc (patched)","name":"debian/changelog"},"line_position":1},"tag":"no-nmu-in-changelog","visibility":"warning"},{"experimental":false,"note":"0.15.0-1~jan+control1","pointer":{"item":{"index":"librabbitmq_0.15.0-1~jan+control1.dsc (patched)","name":"debian/changelog"},"line_position":1},"tag":"source-nmu-has-incorrect-version-number","visibility":"warning"}],"path":"librabbitmq_0.15.0-1~jan+control1.dsc"},{"hints":[],"path":"librabbitmq_0.15.0-1~jan+control1_amd64.buildinfo"},{"hints":[{"experimental":false,"note":"sid control","tag":"distribution-and-changes-mismatch","visibility":"warning"}],"path":"librabbitmq_0.15.0-1~jan+control1_amd64.changes"}],"source_name":"librabbitmq","source_version":"0.15.0-1~jan+control1"}],"lintian_version":"2.143.0"},"logs":{"build":{"description":"build","name":"build.log","url":"/control/c/librabbitmq/cc47cc1c-177a-4056-9f6d-86bc9b10581c/logs/build.log"},"codemod":{"description":"codemod","name":"codemod.log","url":"/control/c/librabbitmq/cc47cc1c-177a-4056-9f6d-86bc9b10581c/logs/codemod.log"},"worker":{"content":"[2026-11-08T01:09:32Z INFO  janitor_worker] Opening branch at https://salsa.debian.org/debian/librabbitmq.git\n[2026-11-08T01:09:35Z INFO  janitor_worker] Cached branch URL http://janitor.debian.net/git/librabbitmq missing: http://janitor.debian.net/git/librabbitmq/\n[2026-11-08T01:09:35Z DEBUG janitor_worker] Workspace path: /srv/worker/output/1/janitor-worker-GKYg8F/librabbitmq\n[2026-11-08T01:09:35Z DEBUG silver_platter::workspace] Creating sprout from git+ssh://git@salsa.debian.org/debian/librabbitmq.git\nTotal 1660 (delta 404), reused 475 (delta 259), pack-reused 950 (from 1)\n[2026-11-08T01:09:39Z DEBUG silver_platter::utils] Colocated branch experimental not found, skipping\n[2026-11-08T01:09:39Z DEBUG silver_platter::utils] Colocated branch vendor not found, skipping\nTotal 72 (delta 17), reused 57 (delta 12), pack-reused 0 (from 0)\nTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\n\nNothing to delete.\n[2026-11-08T01:09:45Z DEBUG silver_platter::workspace] Fetching colocated branches: {\"experimental\": \"experimental\", \"upstream\": \"upstream\", \"pristine-tar\": \"pristine-tar\", \"vendor\": \"vendor\"}\nTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\n[2026-11-08T01:09:48Z DEBUG silver_platter::workspace] Successfully fetched colocated branch upstream -> upstream\nTotal 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)\n[2026-11-08T01:09:50Z DEBUG silver_platter::workspace] Successfully fetched colocated branch pristine-tar -> pristine-tar\n[2026-11-08T01:09:50Z INFO  janitor_worker] Workspace ready - starting.\n[2026-11-08T01:09:50Z INFO  janitor_worker::debian] Running [\"brz\", \"up\", \"--revision=git-v1:c06a1c0c5de743a97d937add52a81121828d8317\"]\n[2026-11-08T01:09:50Z INFO  silver_platter::debian::codemod] Assuming changelog does not need to be updated, since all entries in last changelog entry are prefixed by git shas.\nfound 801 deltas to reuse\n[2026-11-08T01:09:53Z INFO  ognibuild::debian::fix_build] Using fixers: [PgBuildExtOutOfDateControlFixer, MissingConfigureFixer, MissingAutomakeInputFixer, MissingConfigStatusInputFixer, MissingPerlFileFixer, DebcargoUnacceptablePredicateFixer, DebcargoUnacceptableComparatorFixer, RetryAptFetchFailure, PackageDependencyFixer]\n[2026-11-08T01:09:53Z DEBUG ognibuild::debian::build] Adding dummy changelog entry 0.15.0-1~jan+control1 for build\n[2026-11-08T01:09:53Z DEBUG ognibuild::debian::build] Writing build log to /srv/worker/output/1/janitor-worker-GKYg8F/build.log\n[2026-11-08T01:09:53Z INFO  ognibuild::debian::build] Building debian packages, running sbuild --chroot-mode=unshare --no-clean-source -A -s -v -d sid.\n[2026-11-08T01:16:09Z INFO  ognibuild::debian::build] Build succeeded.\n[2026-11-08T01:16:09Z INFO  janitor_worker::debian::build] Built [\"/srv/worker/output/1/janitor-worker-GKYg8F/librabbitmq_0.15.0-1~jan+control1_amd64.changes\", \"/srv/worker/output/1/janitor-worker-GKYg8F/librabbitmq_0.15.0-1~jan+control1_amd64.buildinfo\"].\n[2026-11-08T01:16:09Z DEBUG janitor_worker::debian::lintian] Running lintian: cd \"/srv/worker/output/1/janitor-worker-GKYg8F\" && \"lintian\" \"--exp-output=format=json\" \"--allow-root\" \"/srv/worker/output/1/janitor-worker-GKYg8F/librabbitmq_0.15.0-1~jan+control1_amd64.changes\" \"/srv/worker/output/1/janitor-worker-GKYg8F/librabbitmq_0.15.0-1~jan+control1_amd64.buildinfo\"\n[2026-11-08T01:16:13Z INFO  janitor_worker] Pushing result branch to http://janitor.debian.net/git/librabbitmq\nfound 0 deltas to reuse\n[2026-11-08T01:16:14Z INFO  janitor_worker::vcs] Pushing packaging branch cache to http://janitor.debian.net/git/librabbitmq,branch=debian%2Flatest\nfound 57 deltas to reuse\n[2026-11-08T01:16:16Z INFO  janitor_worker::vcs] Pushed packaging branch cache to http://janitor.debian.net/git/librabbitmq,branch=debian%2Flatest\n","description":"worker","name":"worker.log","url":"/control/c/librabbitmq/cc47cc1c-177a-4056-9f6d-86bc9b10581c/logs/worker.log"}},"my_review":null,"other_reviews":[],"primary_log":"worker","publish_history":[],"queue_position":1,"result_code":"success","resume_from":null,"reviews":[],"revision":"git-v1:c06a1c0c5de743a97d937add52a81121828d8317","run":{"branch_url":"git+ssh://git@salsa.debian.org/debian/librabbitmq.git","build_version":null,"change_set":"cc47cc1c-177a-4056-9f6d-86bc9b10581c","codebase":"librabbitmq","command":"brz up '--revision=git-v1:c06a1c0c5de743a97d937add52a81121828d8317'","context":null,"debian_build_distribution":"sid","debian_build_version":null,"description":"","duration_seconds":406,"failure_stage":null,"failure_transient":null,"finish_time":"2026-11-08T01:16:16.698406Z","id":"cc47cc1c-177a-4056-9f6d-86bc9b10581c","logfilenames":["worker.log","codemod.log","build.log"],"main_branch_revision":"git-v1:769d91f0501a05dd5cba2ce5c242542246256270","publish_status":"unknown","result_branches":[{"absorbed":false,"base_revision":"git-v1:769d91f0501a05dd5cba2ce5c242542246256270","diff":"diff --git a/CMakeLists.txt b/CMakeLists.txt\nindex 629f340..72eb6f7 100644\n--- a/CMakeLists.txt\n+++ b/CMakeLists.txt\n@@ -14,7 +14,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)\n # 4. If any interfaces have been removed since the last public release, then set age to 0.\n \n set(RMQ_SOVERSION_CURRENT   11)\n-set(RMQ_SOVERSION_REVISION  4)\n+set(RMQ_SOVERSION_REVISION  0)\n set(RMQ_SOVERSION_AGE       7)\n \n include(VersionFunctions)\n@@ -167,7 +167,7 @@ if(BUILD_EXAMPLES)\n endif()\n \n if(BUILD_TOOLS)\n-  find_package(POPT 1.14 REQUIRED)\n+  find_package(POPT REQUIRED)\n   if(BUILD_TOOLS_DOCS)\n     find_package(XMLTO REQUIRED)\n   endif()\n@@ -207,9 +207,7 @@ endif ()\n foreach (lib ${SOCKET_LIBRARIES})\n     set(libs_private \"${libs_private} -l${lib}\")\n endforeach(lib)\n-if(LIBRT)\n-  set(libs_private \"${libs_private} -l${LIBRT}\")\n-endif()\n+set(libs_private \"${libs_private} -l${LIBRT}\")\n if (ENABLE_SSL_SUPPORT)\n   set(libs_private \"${libs_private} -lssl -lcrypto ${CMAKE_THREAD_LIBS_INIT}\")\n endif()\n@@ -220,15 +218,6 @@ cmake_path(APPEND libdir \"\\${exec_prefix}\" \"${CMAKE_INSTALL_LIBDIR}\")\n cmake_path(APPEND includedir \"\\${prefix}\" \"${CMAKE_INSTALL_INCLUDEDIR}\")\n \n configure_file(cmake/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq/config.h)\n-\n-set(RMQ_LIBRARY_NAME rabbitmq)\n-if(WIN32)\n-  if(BUILD_SHARED_LIBS)\n-    set(RMQ_LIBRARY_NAME \"rabbitmq.${RMQ_SOVERSION}\")\n-  else()\n-    set(RMQ_LIBRARY_NAME \"librabbitmq.${RMQ_SOVERSION}\")\n-  endif()\n-endif()\n configure_file(librabbitmq.pc.in ${CMAKE_CURRENT_BINARY_DIR}/librabbitmq.pc @ONLY)\n \n include(CMakePackageConfigHelpers)\ndiff --git a/ChangeLog.md b/ChangeLog.md\nindex a339789..cc3ba21 100644\n--- a/ChangeLog.md\n+++ b/ChangeLog.md\n@@ -1,57 +1,4 @@\n # Change Log\n-## v0.18.1 - 2026-10-12\n-\n-### Security\n-- Fix heap buffer over-read in `amqp_read_message` when a content header frame with a non-basic class id is received; `AMQP_STATUS_BAD_AMQP_DATA` is now returned (found by OSS-Fuzz)\n-\n-### Added\n-- Add `fuzz_read_message` OSS-Fuzz fuzzer target for socket message reading\n-\n-## v0.18.0 - 2026-09-14\n-\n-### Security\n-- Fix client-side memory-exhaustion DoS in `amqp_handle_input` (GHSA-5fp7-wg2f-hhgp, #899)\n-\n-### Fixed\n-- `amqp_login`/`amqp_login_with_properties` return an error instead of crashing on `NULL` SASL credentials for `AMQP_SASL_METHOD_PLAIN`; `NULL` and `\"\"` are now accepted for the `AMQP_SASL_METHOD_EXTERNAL` identity argument (#898, #900)\n-- Fix pkgconfig bindings on Windows (#897)\n-\n-## v0.17.0 - 2026-07-01\n-\n-### Security\n-- Fix size_t overflow in `amqp_decode_bytes` bounds check leading to out-of-bounds read (GHSA-jgjf-7fwf-f3c7, #888)\n-- Fix heap buffer overflow in `amqp_frame_to_bytes` for oversized body frames (GHSA-hfjv-vcp3-39wh, #892)\n-\n-### Added\n-- `librabbitmq-tools` fall back to the `AMQP_URL` environment variable when no connection options are given on the command line (#887)\n-\n-### Fixed\n-- Fix undefined behavior in `amqp_decode_properties` when decoding content-header property flags (#883, #885)\n-- Fix `ioctlsocket` type mismatch on Windows (#890)\n-- Document buffer lifetime requirement of `amqp_decode_table`'s encoded buffer to prevent use-after-free misuse (#895)\n-\n-### Changed\n-- `librabbitmq-tools` now enable default SSL certificate verification paths unless `--no-default-cert-paths` is passed (fixes #868, #893)\n-- Building the tools now requires POPT v1.14 or newer (#889)\n-\n-## v0.16.0 - 2026-06-08\n-\n-### Security\n-- Fix out-of-bounds read via undersized frames in `amqp_handle_input` (GHSA-9mmv-r8g3-qp46, #878)\n-- Fix client crash when server negotiates `frame_max` below the AMQP protocol minimum (GHSA-jh48-qjf5-fx5v)\n-\n-### Added\n-- Add `amqp_bytes_from_buffer` macro to create `amqp_bytes_t` from an arbitrary byte buffer with explicit length (#856, #866)\n-\n-### Fixed\n-- Fix NULL pointer dereferences on allocation failure in `tools/publish.c` (#860, #861)\n-- Fix NULL pointer dereference in `tools/consume.c` `stringify_bytes()` on allocation failure (#858)\n-- Fix file stream leak in `tools/common.c` `read_authfile()` (#859)\n-- Fix handling of absolute `CMAKE_INSTALL_INCLUDEDIR` in exported CMake targets (#849)\n-\n-### Changed\n-- `amqp_literal_bytes` macro now uses an explicit `(void *)` cast (#853)\n-\n ## v0.15.0 - 2024-11-19\n ## Fixed\n - Warning on MacOS about incompatible function declaration\ndiff --git a/README.md b/README.md\nindex c403b1e..7c02d52 100644\n--- a/README.md\n+++ b/README.md\n@@ -177,4 +177,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n-SOFTWARE.\n+SOFTWARE.\n\\ No newline at end of file\ndiff --git a/cmake/FindPOPT.cmake b/cmake/FindPOPT.cmake\nindex 099c470..e315f72 100644\n--- a/cmake/FindPOPT.cmake\n+++ b/cmake/FindPOPT.cmake\n@@ -4,12 +4,6 @@\n #  POPT_FOUND - System has popt\n #  POPT_INCLUDE_DIR - The popt include directory\n #  POPT_LIBRARY - The libraries needed to use popt\n-#  POPT_VERSION - The version of popt that was found\n-#\n-# This module also supports version requirements, e.g.\n-# find_package(POPT 1.14 REQUIRED). popt does not expose its release\n-# version in popt.h, so the version is obtained from pkg-config. A version\n-# requirement therefore needs pkg-config and the popt.pc file to be available.\n \n # use pkg-config to get the directories and then use these values\n # in the FIND_PATH() and FIND_LIBRARY() calls\ndiff --git a/debian/changelog b/debian/changelog\nindex 2c1f09e..dc93a3b 100644\n--- a/debian/changelog\n+++ b/debian/changelog\n@@ -1,45 +1,3 @@\n-librabbitmq (0.18.1-1) unstable; urgency=medium\n-\n-  * [b04d09f] New upstream version 0.18.1\n-  * [6f4847e] d/copyright: update for new upstream release\n-\n- -- Florian Ernst <florian@debian.org>  Tue, 13 Oct 2026 15:26:53 +0200\n-\n-librabbitmq (0.18.0-1) unstable; urgency=medium\n-\n-  * [1e6e7e0] d/changelog: add security info to latest entry now that CVE IDs\n-    are available\n-  * [bfac81f] New upstream version 0.18.0\n-    - Fix client-side memory-exhaustion DoS in amqp_handle_input\n-      (GHSA-5fp7-wg2f-hhgp)\n-\n- -- Florian Ernst <florian@debian.org>  Tue, 15 Sep 2026 16:37:35 +0200\n-\n-librabbitmq (0.17.0-1) unstable; urgency=medium\n-\n-  * [9a53c6e] New upstream version 0.17.0\n-    - Fix size_t overflow in amqp_decode_bytes bounds check leading to\n-      out-of-bounds read (GHSA-jgjf-7fwf-f3c7, CVE-2026-59986)\n-    - Fix heap buffer overflow in amqp_frame_to_bytes for oversized body\n-      frames (GHSA-hfjv-vcp3-39wh, CVE-2026-61547)\n-  * [24919ea] d/copyright: adjust for new upstream release\n-\n- -- Florian Ernst <florian@debian.org>  Thu, 02 Jul 2026 16:16:32 +0200\n-\n-librabbitmq (0.16.0-1) unstable; urgency=medium\n-\n-  * [f5432c5] New upstream version 0.16.0\n-    - Fix out-of-bounds read via undersized frames in amqp_handle_input\n-      (GHSA-9mmv-r8g3-qp46, CVE-2026-44235)\n-    - Fix client crash when server negotiates frame_max below the AMQP\n-      protocol minimum (GHSA-jh48-qjf5-fx5v, CVE-2026-44236)\n-  * [e4322ce] d/watch: update file format version to 5,\n-    using the GitHub template\n-  * [5d11b47] d/control: drop now-obsolete fields\n-  * [1f0a930] d/control: Standards-Version: 4.7.4, no changes needed\n-\n- -- Florian Ernst <florian@debian.org>  Tue, 09 Jun 2026 15:50:03 +0200\n-\n librabbitmq (0.15.0-1) unstable; urgency=medium\n \n   * [0dd9015] New upstream version 0.15.0\ndiff --git a/debian/control b/debian/control\nindex 5cc25d6..b014066 100644\n--- a/debian/control\n+++ b/debian/control\n@@ -1,4 +1,5 @@\n Source: librabbitmq\n+Priority: optional\n Section: libs\n Maintainer: Florian Ernst <florian@debian.org>\n Build-Depends:\n@@ -8,10 +9,11 @@ Build-Depends:\n  libpopt-dev,\n  libssl-dev,\n  libtool,\n-Standards-Version: 4.7.4\n+Standards-Version: 4.7.0\n Homepage: https://github.com/alanxz/rabbitmq-c\n Vcs-Git: https://salsa.debian.org/debian/librabbitmq.git\n Vcs-Browser: https://salsa.debian.org/debian/librabbitmq\n+Rules-Requires-Root: no\n \n Package: amqp-tools\n Architecture: any\ndiff --git a/debian/copyright b/debian/copyright\nindex 718e024..33234db 100644\n--- a/debian/copyright\n+++ b/debian/copyright\n@@ -6,14 +6,13 @@ Source: https://github.com/alanxz/rabbitmq-c\n Files: *\n Copyright: 2007-2012, VMware, Inc.\n            2009-2010, Tony Garnock-Jones\n-           2007-2026, Alan Antonuk and the rabbitmq-c contributors\n-           2007-2026, Arthur Chan and the rabbitmq-c contributors\n+           2007-2022, Alan Antonuk and the rabbitmq-c contributors\n License: Expat\n \n Files: debian/*\n Copyright: 2010, Monty Taylor <mordred@inaugust.com>\n            2013-2022, Michael Fladischer <fladi@debian.org>\n-           2024-2026, Florian Ernst <florian@debian.org>\n+           2024, Florian Ernst <florian@debian.org>\n License: Expat\n \n License: Expat\ndiff --git a/debian/watch b/debian/watch\nindex 72d5d8f..0fe2940 100644\n--- a/debian/watch\n+++ b/debian/watch\n@@ -1,7 +1,3 @@\n-Version: 5\n-\n-Uversionmangle: s/(\\d)[_\\.\\-\\+]?((RC|rc|pre|dev|beta|alpha)\\d*)$/$1~$2/\n-Filenamemangle: s/.+\\/v?(\\d\\S*)\\.tar\\.gz/librabbitmq-c-$1.tar.gz/\n-Template: GitHub\n-Owner: alanxz\n-Project: rabbitmq-c\n+version=4\n+opts=uversionmangle=s/(\\d)[_\\.\\-\\+]?((RC|rc|pre|dev|beta|alpha)\\d*)$/$1~$2/,filenamemangle=s/.+\\/v?(\\d\\S*)\\.tar\\.gz/librabbitmq-c-$1.tar.gz/ \\\n+https://github.com/alanxz/rabbitmq-c/tags .*/v?(\\d.*)@ARCHIVE_EXT@\ndiff --git a/examples/amqp_confirm_select.c b/examples/amqp_confirm_select.c\nindex 952a76d..9327fe7 100644\n--- a/examples/amqp_confirm_select.c\n+++ b/examples/amqp_confirm_select.c\n@@ -26,7 +26,7 @@\n \n #define SUMMARY_EVERY_US 5000\n \n-static void send_batch(amqp_connection_state_t conn, amqp_bytes_t queue_name,\n+static void send_batch(amqp_connection_state_t conn, char const *queue_name,\n                        int rate_limit, int message_count) {\n   uint64_t start_time = now_microseconds();\n   int i;\n@@ -48,8 +48,9 @@ static void send_batch(amqp_connection_state_t conn, amqp_bytes_t queue_name,\n   for (i = 0; i < message_count; i++) {\n     uint64_t now = now_microseconds();\n \n-    die_on_error(amqp_basic_publish(conn, 1, amqp_literal_bytes(\"amq.direct\"),\n-                                    queue_name, 0, 0, NULL, message_bytes),\n+    die_on_error(amqp_basic_publish(conn, 1, amqp_cstring_bytes(\"amq.direct\"),\n+                                    amqp_cstring_bytes(queue_name), 0, 0, NULL,\n+                                    message_bytes),\n                  \"Publishing\");\n     sent++;\n     if (now > next_summary_time) {\n@@ -176,7 +177,7 @@ int main(int argc, char const *const *argv) {\n   amqp_confirm_select(conn, 1);\n   die_on_amqp_error(amqp_get_rpc_reply(conn), \"Enable confirm-select\");\n \n-  send_batch(conn, amqp_literal_bytes(\"test queue\"), rate_limit, message_count);\n+  send_batch(conn, \"test queue\", rate_limit, message_count);\n \n   wait_for_acks(conn);\n   die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS),\ndiff --git a/examples/amqp_producer.c b/examples/amqp_producer.c\nindex da41b53..34cd75a 100644\n--- a/examples/amqp_producer.c\n+++ b/examples/amqp_producer.c\n@@ -13,7 +13,7 @@\n \n #define SUMMARY_EVERY_US 1000000\n \n-static void send_batch(amqp_connection_state_t conn, amqp_bytes_t queue_name,\n+static void send_batch(amqp_connection_state_t conn, char const *queue_name,\n                        int rate_limit, int message_count) {\n   uint64_t start_time = now_microseconds();\n   int i;\n@@ -35,8 +35,9 @@ static void send_batch(amqp_connection_state_t conn, amqp_bytes_t queue_name,\n   for (i = 0; i < message_count; i++) {\n     uint64_t now = now_microseconds();\n \n-    die_on_error(amqp_basic_publish(conn, 1, amqp_literal_bytes(\"amq.direct\"),\n-                                    queue_name, 0, 0, NULL, message_bytes),\n+    die_on_error(amqp_basic_publish(conn, 1, amqp_cstring_bytes(\"amq.direct\"),\n+                                    amqp_cstring_bytes(queue_name), 0, 0, NULL,\n+                                    message_bytes),\n                  \"Publishing\");\n     sent++;\n     if (now > next_summary_time) {\n@@ -106,7 +107,7 @@ int main(int argc, char const *const *argv) {\n   amqp_channel_open(conn, 1);\n   die_on_amqp_error(amqp_get_rpc_reply(conn), \"Opening channel\");\n \n-  send_batch(conn, amqp_literal_bytes(\"test queue\"), rate_limit, message_count);\n+  send_batch(conn, \"test queue\", rate_limit, message_count);\n \n   die_on_amqp_error(amqp_channel_close(conn, 1, AMQP_REPLY_SUCCESS),\n                     \"Closing channel\");\ndiff --git a/examples/amqp_rpc_sendstring_client.c b/examples/amqp_rpc_sendstring_client.c\nindex 97cfa77..4f743fd 100644\n--- a/examples/amqp_rpc_sendstring_client.c\n+++ b/examples/amqp_rpc_sendstring_client.c\n@@ -85,14 +85,14 @@ int main(int argc, char *argv[]) {\n     props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG |\n                    AMQP_BASIC_DELIVERY_MODE_FLAG | AMQP_BASIC_REPLY_TO_FLAG |\n                    AMQP_BASIC_CORRELATION_ID_FLAG;\n-    props.content_type = amqp_literal_bytes(\"text/plain\");\n+    props.content_type = amqp_cstring_bytes(\"text/plain\");\n     props.delivery_mode = 2; /* persistent delivery mode */\n     props.reply_to = amqp_bytes_malloc_dup(reply_to_queue);\n     if (props.reply_to.bytes == NULL) {\n       fprintf(stderr, \"Out of memory while copying queue name\");\n       return 1;\n     }\n-    props.correlation_id = amqp_literal_bytes(\"1\");\n+    props.correlation_id = amqp_cstring_bytes(\"1\");\n \n     /*\n       publish\ndiff --git a/examples/amqp_sendstring.c b/examples/amqp_sendstring.c\nindex bfcaea5..28b8a7c 100644\n--- a/examples/amqp_sendstring.c\n+++ b/examples/amqp_sendstring.c\n@@ -54,7 +54,7 @@ int main(int argc, char const *const *argv) {\n   {\n     amqp_basic_properties_t props;\n     props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;\n-    props.content_type = amqp_literal_bytes(\"text/plain\");\n+    props.content_type = amqp_cstring_bytes(\"text/plain\");\n     props.delivery_mode = 2; /* persistent delivery mode */\n     die_on_error(amqp_basic_publish(conn, 1, amqp_cstring_bytes(exchange),\n                                     amqp_cstring_bytes(routingkey), 0, 0,\ndiff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt\nindex 18ab974..06d9e78 100644\n--- a/fuzz/CMakeLists.txt\n+++ b/fuzz/CMakeLists.txt\n@@ -17,19 +17,4 @@ if(BUILD_OSSFUZZ)\n \n   add_executable(fuzz_server fuzz_server.c)\n   target_link_libraries(fuzz_server rabbitmq-static)\n-\n-  add_executable(fuzz_method_decode fuzz_method_decode.c)\n-  target_link_libraries(fuzz_method_decode rabbitmq-static)\n-\n-  add_executable(fuzz_properties_decode fuzz_properties_decode.c)\n-  target_link_libraries(fuzz_properties_decode rabbitmq-static)\n-\n-  add_executable(fuzz_handle_input fuzz_handle_input.c)\n-  target_link_libraries(fuzz_handle_input rabbitmq-static)\n-\n-  add_executable(fuzz_codec fuzz_codec.c)\n-  target_link_libraries(fuzz_codec rabbitmq-static)\n-\n-  add_executable(fuzz_read_message fuzz_read_message.c)\n-  target_link_libraries(fuzz_read_message rabbitmq-static)\n endif ()\ndiff --git a/fuzz/fuzz_codec.c b/fuzz/fuzz_codec.c\ndeleted file mode 100644\nindex f1c5076..0000000\n--- a/fuzz/fuzz_codec.c\n+++ /dev/null\n@@ -1,132 +0,0 @@\n-// Copyright 2007 - 2026, Arthur Chan and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include <stdint.h>\n-#include <stdlib.h>\n-#include <string.h>\n-\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-// Round-trips the AMQP codecs. The existing fuzzers only decode; the generated\n-// serializers (amqp_encode_method/properties/table) and amqp_table_clone are\n-// unreachable from hand-written input. Each mode decodes attacker bytes into the\n-// in-memory struct, then re-encodes/clones it -- the decoder supplies the\n-// adversarial-but-valid structs the encoders would otherwise never see.\n-\n-#define ENC_BUF_SIZE (1u << 20)\n-\n-static void roundtrip_method(const uint8_t *p, size_t n) {\n-  amqp_pool_t pool;\n-  void *decoded = NULL;\n-  amqp_method_number_t method_id;\n-  amqp_bytes_t encoded;\n-\n-  if (n < 4) {\n-    return;\n-  }\n-  method_id = ((amqp_method_number_t)p[0] << 24) |\n-              ((amqp_method_number_t)p[1] << 16) |\n-              ((amqp_method_number_t)p[2] << 8) | (amqp_method_number_t)p[3];\n-  encoded.len = n - 4;\n-  encoded.bytes = (void *)(p + 4);\n-\n-  init_amqp_pool(&pool, 4096);\n-  if (amqp_decode_method(method_id, &pool, encoded, &decoded) ==\n-          AMQP_STATUS_OK &&\n-      decoded != NULL) {\n-    void *buf = malloc(ENC_BUF_SIZE);\n-    if (buf != NULL) {\n-      amqp_bytes_t out;\n-      out.len = ENC_BUF_SIZE;\n-      out.bytes = buf;\n-      amqp_encode_method(method_id, decoded, out);\n-      free(buf);\n-    }\n-  }\n-  empty_amqp_pool(&pool);\n-}\n-\n-static void roundtrip_properties(const uint8_t *p, size_t n) {\n-  amqp_pool_t pool;\n-  void *decoded = NULL;\n-  uint16_t class_id;\n-  amqp_bytes_t encoded;\n-\n-  if (n < 2) {\n-    return;\n-  }\n-  class_id = ((uint16_t)p[0] << 8) | (uint16_t)p[1];\n-  encoded.len = n - 2;\n-  encoded.bytes = (void *)(p + 2);\n-\n-  init_amqp_pool(&pool, 4096);\n-  if (amqp_decode_properties(class_id, &pool, encoded, &decoded) ==\n-          AMQP_STATUS_OK &&\n-      decoded != NULL) {\n-    void *buf = malloc(ENC_BUF_SIZE);\n-    if (buf != NULL) {\n-      amqp_bytes_t out;\n-      out.len = ENC_BUF_SIZE;\n-      out.bytes = buf;\n-      amqp_encode_properties(class_id, decoded, out);\n-      free(buf);\n-    }\n-  }\n-  empty_amqp_pool(&pool);\n-}\n-\n-static void roundtrip_table(const uint8_t *p, size_t n) {\n-  amqp_pool_t pool;\n-  amqp_table_t decoded;\n-  amqp_bytes_t encoded;\n-  size_t offset = 0;\n-\n-  encoded.len = n;\n-  encoded.bytes = (void *)p;\n-\n-  init_amqp_pool(&pool, 4096);\n-  memset(&decoded, 0, sizeof(decoded));\n-  if (amqp_decode_table(encoded, &pool, &decoded, &offset) == AMQP_STATUS_OK) {\n-    void *buf = malloc(ENC_BUF_SIZE);\n-    if (buf != NULL) {\n-      amqp_bytes_t out;\n-      size_t out_off = 0;\n-      out.len = ENC_BUF_SIZE;\n-      out.bytes = buf;\n-      amqp_encode_table(out, &decoded, &out_off);\n-      free(buf);\n-    }\n-    {\n-      amqp_pool_t clone_pool;\n-      amqp_table_t clone;\n-      init_amqp_pool(&clone_pool, 4096);\n-      memset(&clone, 0, sizeof(clone));\n-      amqp_table_clone(&decoded, &clone, &clone_pool);\n-      empty_amqp_pool(&clone_pool);\n-    }\n-  }\n-  empty_amqp_pool(&pool);\n-}\n-\n-// First byte selects the codec; the remainder is the payload, framed like the\n-// matching decode fuzzer (method-id / class-id prefix where applicable).\n-extern int LLVMFuzzerTestOneInput(const char *data, size_t size) {\n-  const uint8_t *bytes = (const uint8_t *)data;\n-\n-  if (size < 1) {\n-    return 0;\n-  }\n-  switch (bytes[0] % 3) {\n-    case 0:\n-      roundtrip_method(bytes + 1, size - 1);\n-      break;\n-    case 1:\n-      roundtrip_properties(bytes + 1, size - 1);\n-      break;\n-    default:\n-      roundtrip_table(bytes + 1, size - 1);\n-      break;\n-  }\n-  return 0;\n-}\ndiff --git a/fuzz/fuzz_handle_input.c b/fuzz/fuzz_handle_input.c\ndeleted file mode 100644\nindex aab0063..0000000\n--- a/fuzz/fuzz_handle_input.c\n+++ /dev/null\n@@ -1,55 +0,0 @@\n-// Copyright 2007 - 2026, Arthur Chan and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include <errno.h>\n-#include <inttypes.h>\n-#include <stdio.h>\n-#include <stdlib.h>\n-#include <string.h>\n-\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-// Drives amqp_handle_input(), the byte->frame wire parser, feeding the input one\n-// frame at a time and advancing by the number of bytes it reports consuming.\n-extern int LLVMFuzzerTestOneInput(const char *data, size_t size) {\n-\n-  amqp_connection_state_t conn;\n-  amqp_bytes_t buffer;\n-  size_t iterations = 0;\n-\n-  if (size == 0) {\n-    return 0;\n-  }\n-\n-  conn = amqp_new_connection();\n-  if (conn == NULL) {\n-    return 0;\n-  }\n-\n-  buffer.bytes = (void *)data;\n-  buffer.len = size;\n-\n-  while (buffer.len > 0 && iterations < 4096) {\n-    amqp_frame_t frame;\n-    int res;\n-\n-    memset(&frame, 0, sizeof(frame));\n-    res = amqp_handle_input(conn, buffer, &frame);\n-    if (res <= 0) {\n-      break;\n-    }\n-\n-    buffer.bytes = (void *)((const char *)buffer.bytes + (size_t)res);\n-    buffer.len -= (size_t)res;\n-\n-    if (frame.frame_type != 0) {\n-      amqp_maybe_release_buffers_on_channel(conn, frame.channel);\n-    }\n-\n-    iterations++;\n-  }\n-\n-  amqp_destroy_connection(conn);\n-  return 0;\n-}\ndiff --git a/fuzz/fuzz_method_decode.c b/fuzz/fuzz_method_decode.c\ndeleted file mode 100644\nindex 442cf0e..0000000\n--- a/fuzz/fuzz_method_decode.c\n+++ /dev/null\n@@ -1,43 +0,0 @@\n-// Copyright 2007 - 2022, Alan Antonuk and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include <errno.h>\n-#include <inttypes.h>\n-#include <math.h>\n-#include <stdarg.h>\n-#include <stdio.h>\n-#include <stdlib.h>\n-#include <string.h>\n-\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-// Drives amqp_decode_method(), the generated decoder for every AMQP method\n-// frame. The first 4 bytes are the method id (big-endian), the rest the body.\n-extern int LLVMFuzzerTestOneInput(const char *data, size_t size) {\n-\n-  int unused_result;\n-  amqp_pool_t pool;\n-  amqp_method_number_t method_id;\n-\n-  if (size < 4) {\n-    return 0;\n-  }\n-\n-  method_id = ((amqp_method_number_t)(uint8_t)data[0] << 24) |\n-              ((amqp_method_number_t)(uint8_t)data[1] << 16) |\n-              ((amqp_method_number_t)(uint8_t)data[2] << 8) |\n-              ((amqp_method_number_t)(uint8_t)data[3]);\n-\n-  init_amqp_pool(&pool, 4096);\n-  {\n-    void *decoded = NULL;\n-    amqp_bytes_t encoded;\n-    encoded.len = size - 4;\n-    encoded.bytes = (void *)(data + 4);\n-\n-    unused_result = amqp_decode_method(method_id, &pool, encoded, &decoded);\n-  }\n-  empty_amqp_pool(&pool);\n-  return 0;\n-}\ndiff --git a/fuzz/fuzz_properties_decode.c b/fuzz/fuzz_properties_decode.c\ndeleted file mode 100644\nindex 279b223..0000000\n--- a/fuzz/fuzz_properties_decode.c\n+++ /dev/null\n@@ -1,42 +0,0 @@\n-// Copyright 2007 - 2026, Arthur Chan and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include <errno.h>\n-#include <inttypes.h>\n-#include <math.h>\n-#include <stdarg.h>\n-#include <stdio.h>\n-#include <stdlib.h>\n-#include <string.h>\n-\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-// Drives amqp_decode_properties(), the generated decoder for every AMQP\n-// content-header (properties) frame. The first 2 bytes are the class id\n-// (big-endian), the rest the body.\n-extern int LLVMFuzzerTestOneInput(const char *data, size_t size) {\n-\n-  int unused_result;\n-  amqp_pool_t pool;\n-  uint16_t class_id;\n-\n-  if (size < 2) {\n-    return 0;\n-  }\n-\n-  class_id = ((uint16_t)(uint8_t)data[0] << 8) |\n-             ((uint16_t)(uint8_t)data[1]);\n-\n-  init_amqp_pool(&pool, 4096);\n-  {\n-    void *decoded = NULL;\n-    amqp_bytes_t encoded;\n-    encoded.len = size - 2;\n-    encoded.bytes = (void *)(data + 2);\n-\n-    unused_result = amqp_decode_properties(class_id, &pool, encoded, &decoded);\n-  }\n-  empty_amqp_pool(&pool);\n-  return 0;\n-}\ndiff --git a/fuzz/fuzz_read_message.c b/fuzz/fuzz_read_message.c\ndeleted file mode 100644\nindex 1eafb9c..0000000\n--- a/fuzz/fuzz_read_message.c\n+++ /dev/null\n@@ -1,136 +0,0 @@\n-// Copyright 2007 - 2026, Alan Antonuk and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include <stdint.h>\n-#include <stdlib.h>\n-#include <string.h>\n-\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-#include \"amqp_socket.h\"\n-\n-#define MAX_INPUT_SIZE (1U << 20)\n-#define MAX_BODY_SIZE (1U << 20)\n-\n-struct fuzz_socket_t {\n-  const struct amqp_socket_class_t *klass;\n-  const uint8_t *data;\n-  size_t size;\n-  size_t offset;\n-};\n-\n-static ssize_t fuzz_socket_send(AMQP_UNUSED void *base,\n-                                AMQP_UNUSED const void *buf, size_t len,\n-                                AMQP_UNUSED int flags) {\n-  return (ssize_t)len;\n-}\n-\n-static ssize_t fuzz_socket_recv(void *base, void *buf, size_t len,\n-                                AMQP_UNUSED int flags) {\n-  struct fuzz_socket_t *socket = (struct fuzz_socket_t *)base;\n-  size_t remaining = socket->size - socket->offset;\n-  size_t count;\n-\n-  if (remaining == 0) {\n-    return AMQP_STATUS_CONNECTION_CLOSED;\n-  }\n-\n-  count = remaining < len ? remaining : len;\n-  memcpy(buf, socket->data + socket->offset, count);\n-  socket->offset += count;\n-  return (ssize_t)count;\n-}\n-\n-static int fuzz_socket_open(AMQP_UNUSED void *base,\n-                            AMQP_UNUSED const char *host,\n-                            AMQP_UNUSED int port,\n-                            AMQP_UNUSED const struct timeval *timeout) {\n-  return AMQP_STATUS_OK;\n-}\n-\n-static int fuzz_socket_close(AMQP_UNUSED void *base,\n-                             AMQP_UNUSED amqp_socket_close_enum force) {\n-  return AMQP_STATUS_OK;\n-}\n-\n-static int fuzz_socket_get_sockfd(AMQP_UNUSED void *base) { return 0; }\n-\n-static void fuzz_socket_delete(void *base) { free(base); }\n-\n-static const struct amqp_socket_class_t fuzz_socket_class = {\n-    fuzz_socket_send, fuzz_socket_recv,       fuzz_socket_open,\n-    fuzz_socket_close, fuzz_socket_get_sockfd, fuzz_socket_delete};\n-\n-static uint64_t read_be64(const uint8_t *data) {\n-  uint64_t value = 0;\n-  size_t i;\n-\n-  for (i = 0; i < 8; i++) {\n-    value = (value << 8) | data[i];\n-  }\n-  return value;\n-}\n-\n-static int body_sizes_are_bounded(const uint8_t *data, size_t size) {\n-  size_t offset = 0;\n-\n-  if (size >= 8 && memcmp(data, \"AMQP\", 4) == 0) {\n-    offset = 8;\n-  }\n-\n-  while (size - offset >= 8) {\n-    uint32_t payload_size = ((uint32_t)data[offset + 3] << 24) |\n-                            ((uint32_t)data[offset + 4] << 16) |\n-                            ((uint32_t)data[offset + 5] << 8) |\n-                            (uint32_t)data[offset + 6];\n-    size_t frame_size = (size_t)payload_size + 8;\n-\n-    if (frame_size > size - offset) {\n-      break;\n-    }\n-    if (data[offset] == AMQP_FRAME_HEADER && payload_size >= 12 &&\n-        read_be64(data + offset + 11) > MAX_BODY_SIZE) {\n-      return 0;\n-    }\n-    offset += frame_size;\n-  }\n-\n-  return 1;\n-}\n-\n-extern int LLVMFuzzerTestOneInput(const char *data, size_t size) {\n-  amqp_connection_state_t connection;\n-  amqp_message_t message;\n-  struct fuzz_socket_t *socket;\n-  amqp_rpc_reply_t reply;\n-\n-  if (size == 0 || size > MAX_INPUT_SIZE ||\n-      !body_sizes_are_bounded((const uint8_t *)data, size)) {\n-    return 0;\n-  }\n-\n-  connection = amqp_new_connection();\n-  if (connection == NULL) {\n-    return 0;\n-  }\n-\n-  socket = (struct fuzz_socket_t *)calloc(1, sizeof(*socket));\n-  if (socket == NULL) {\n-    amqp_destroy_connection(connection);\n-    return 0;\n-  }\n-\n-  socket->klass = &fuzz_socket_class;\n-  socket->data = (const uint8_t *)data;\n-  socket->size = size;\n-  amqp_set_socket(connection, (amqp_socket_t *)socket);\n-\n-  reply = amqp_read_message(connection, 1, &message, 0);\n-  if (reply.reply_type == AMQP_RESPONSE_NORMAL) {\n-    amqp_destroy_message(&message);\n-  }\n-\n-  amqp_destroy_connection(connection);\n-  return 0;\n-}\n\\ No newline at end of file\ndiff --git a/fuzz/fuzz_server.c b/fuzz/fuzz_server.c\nindex dcee9a9..458689e 100644\n--- a/fuzz/fuzz_server.c\n+++ b/fuzz/fuzz_server.c\n@@ -1,97 +1,152 @@\n // Copyright 2007 - 2022, Alan Antonuk and the rabbitmq-c contributors.\n // SPDX-License-Identifier: mit\n \n+#include <arpa/inet.h>\n+#include <errno.h>\n+#include <netinet/in.h>\n+#include <pthread.h>\n #include <stdint.h>\n+#include <stdio.h>\n #include <stdlib.h>\n #include <string.h>\n+#include <sys/socket.h>\n+#include <unistd.h>\n \n #include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n+#include <rabbitmq-c/tcp_socket.h>\n \n-#include \"amqp_private.h\"\n-#include \"amqp_socket.h\"\n+struct Fuzzer {\n+  int socket;\n+  uint16_t port;\n+  pthread_t thread;\n \n-// In-memory socket: feeds the fuzz buffer to the client as the bytes a broker\n-// would send, with no real socket or thread, so amqp_login() drives the full\n-// client handshake (Connection.Start -> Tune -> Open -> OpenOk) from the input.\n-\n-struct fuzz_socket_t {\n-  const struct amqp_socket_class_t *klass;\n-  const uint8_t *data;\n-  size_t size;\n-  size_t offset;\n+  uint64_t size;\n+  uint8_t *buffer;\n };\n+typedef struct Fuzzer Fuzzer;\n \n-static ssize_t fuzz_socket_send(AMQP_UNUSED void *base,\n-                                AMQP_UNUSED const void *buf, size_t len,\n-                                AMQP_UNUSED int flags) {\n-  return (ssize_t)len;\n-}\n+#define PORT 5672\n+#define kMinInputLength 8\n+#define kMaxInputLength 1024\n \n-static ssize_t fuzz_socket_recv(void *base, void *buf, size_t len,\n-                                AMQP_UNUSED int flags) {\n-  struct fuzz_socket_t *self = (struct fuzz_socket_t *)base;\n-  size_t remaining = self->size - self->offset;\n-  size_t n;\n+void client(Fuzzer *fuzzer);\n \n-  if (remaining == 0) {\n-    return AMQP_STATUS_CONNECTION_CLOSED;\n+void fuzzinit(Fuzzer *fuzzer) {\n+  struct sockaddr_in server_addr;\n+  int res;\n+  fuzzer->socket = socket(AF_INET, SOCK_STREAM, 0);\n+  if (fuzzer->socket == -1) {\n+    fprintf(stderr, \"socket failed %s\\n\", strerror(errno));\n+    exit(1);\n+  }\n+  memset(&server_addr, 0, sizeof(server_addr));\n+  server_addr.sin_family = AF_INET;\n+  server_addr.sin_port = htons(fuzzer->port);\n+  server_addr.sin_addr.s_addr = inet_addr(\"127.0.0.1\");\n+  res = setsockopt(fuzzer->socket, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int));\n+  if (res) {\n+    fprintf(stderr, \"setsockopt failed: %s\\n\", strerror(errno));\n+    exit(1);\n   }\n-  n = remaining < len ? remaining : len;\n-  memcpy(buf, self->data + self->offset, n);\n-  self->offset += n;\n-  return (ssize_t)n;\n-}\n \n-static int fuzz_socket_open(AMQP_UNUSED void *base, AMQP_UNUSED const char *host,\n-                            AMQP_UNUSED int port,\n-                            AMQP_UNUSED const struct timeval *timeout) {\n-  return AMQP_STATUS_OK;\n+  res = bind(fuzzer->socket, (struct sockaddr *)&server_addr, sizeof(server_addr));\n+  if (res) {\n+    fprintf(stderr, \"bind failed: %s\\n\", strerror(errno));\n+    exit(1);\n+  }\n+  res = listen(fuzzer->socket, 1);\n+  if (res) {\n+    fprintf(stderr, \"listen failed: %s\\n\", strerror(errno));\n+    exit(1);\n+  }\n }\n \n-static int fuzz_socket_close(AMQP_UNUSED void *base,\n-                             AMQP_UNUSED amqp_socket_close_enum force) {\n-  return AMQP_STATUS_OK;\n-}\n+void *Server(void *args) {\n+  Fuzzer *fuzzer = (Fuzzer *)args;\n \n-static int fuzz_socket_get_sockfd(AMQP_UNUSED void *base) {\n-  return 0; /* must be >= 0; -1 is treated as a closed connection */\n-}\n+  int client;\n+  int res;\n+  char clientData[10240];\n \n-static void fuzz_socket_delete(void *base) { free(base); }\n+  client = accept(fuzzer->socket, NULL, NULL);\n+  if (client == -1) {\n+    fprintf(stderr, \"accept failed: %s\\n\", strerror(errno));\n+    exit(1);\n+  }\n \n-static const struct amqp_socket_class_t fuzz_socket_class = {\n-    fuzz_socket_send, fuzz_socket_recv,       fuzz_socket_open,\n-    fuzz_socket_close, fuzz_socket_get_sockfd, fuzz_socket_delete};\n+  res = recv(client, clientData, sizeof(clientData), 0);\n+  if (res == -1) {\n+    fprintf(stderr, \"recv failed: %s\\n\", strerror(errno));\n+    exit(1);\n+  }\n+  res = send(client, fuzzer->buffer, fuzzer->size, 0);\n+  if (res == -1) {\n+    fprintf(stderr, \"send failed: %s\\n\", strerror(errno));\n+    exit(1);\n+  }\n+\n+  res = shutdown(client, SHUT_RDWR);\n+  close(client);\n+  return NULL;\n+}\n+\n+void clean(Fuzzer *fuzzer) {\n+  shutdown(fuzzer->socket, SHUT_RDWR);\n+  close(fuzzer->socket);\n+  free(fuzzer->buffer);\n+  free(fuzzer);\n+}\n \n extern int LLVMFuzzerTestOneInput(const char *data, size_t size) {\n-  amqp_connection_state_t conn;\n-  struct fuzz_socket_t *sock;\n \n-  if (size == 0) {\n+  if (size < kMinInputLength || size > kMaxInputLength) {\n     return 0;\n   }\n \n+  Fuzzer *fuzzer = (Fuzzer *)malloc(sizeof(Fuzzer));\n+  fuzzer->port = PORT;\n+\n+  fuzzer->size = size;\n+  fuzzer->buffer = malloc(fuzzer->size);\n+  memcpy(fuzzer->buffer, data, size);\n+\n+  fuzzinit(fuzzer);\n+\n+  pthread_create(&fuzzer->thread, NULL, Server, fuzzer);\n+\n+  client(fuzzer);\n+\n+  pthread_join(fuzzer->thread, NULL);\n+\n+  clean(fuzzer);\n+\n+  return 0;\n+}\n+\n+void client(Fuzzer *fuzzer) {\n+  char const *hostname;\n+  int status;\n+  amqp_socket_t *socket = NULL;\n+  amqp_connection_state_t conn;\n+\n+  hostname = \"127.0.0.1\";\n+\n   conn = amqp_new_connection();\n-  if (conn == NULL) {\n-    return 0;\n-  }\n \n-  sock = (struct fuzz_socket_t *)calloc(1, sizeof(*sock));\n-  if (sock == NULL) {\n-    amqp_destroy_connection(conn);\n-    return 0;\n+  socket = amqp_tcp_socket_new(conn);\n+  if (!socket) {\n+    exit(1);\n   }\n-  sock->klass = &fuzz_socket_class;\n-  sock->data = (const uint8_t *)data;\n-  sock->size = size;\n \n-  // Takes ownership; amqp_destroy_connection frees it via fuzz_socket_delete.\n-  amqp_set_socket(conn, (amqp_socket_t *)sock);\n+  status = amqp_socket_open(socket, hostname, fuzzer->port);\n+  if (status != AMQP_STATUS_OK) {\n+    int sav_errno = errno;\n+    fprintf(stderr, \"amqp_socket_open failed: %s\\n\", amqp_error_string2(status));\n+    fprintf(stderr, \"amqp_socket_open errno: %d: %s\\n\", sav_errno, strerror(sav_errno));\n+    exit(1);\n+  }\n \n-  amqp_login(conn, \"/\", 0, AMQP_DEFAULT_FRAME_SIZE, 0, AMQP_SASL_METHOD_PLAIN,\n-             \"guest\", \"guest\");\n+  amqp_login(conn, \"/\", 0, 131072, 0, AMQP_SASL_METHOD_PLAIN, \"guest\", \"guest\");\n \n   amqp_destroy_connection(conn);\n-  return 0;\n }\ndiff --git a/fuzz/input/fuzz_codec.raw b/fuzz/input/fuzz_codec.raw\ndeleted file mode 100644\nindex f26336d..0000000\nBinary files a/fuzz/input/fuzz_codec.raw and /dev/null differ\ndiff --git a/fuzz/input/fuzz_method_decode.raw b/fuzz/input/fuzz_method_decode.raw\ndeleted file mode 100644\nindex da475b1..0000000\nBinary files a/fuzz/input/fuzz_method_decode.raw and /dev/null differ\ndiff --git a/fuzz/input/fuzz_properties_decode.raw b/fuzz/input/fuzz_properties_decode.raw\ndeleted file mode 100644\nindex 9cf03e4..0000000\nBinary files a/fuzz/input/fuzz_properties_decode.raw and /dev/null differ\ndiff --git a/fuzz/input/fuzz_server.raw b/fuzz/input/fuzz_server.raw\nindex f9e0041..4f2ca96 100644\nBinary files a/fuzz/input/fuzz_server.raw and b/fuzz/input/fuzz_server.raw differ\ndiff --git a/fuzz/input/fuzz_server_ghsa-9mmv-r8g3-qp46.raw b/fuzz/input/fuzz_server_ghsa-9mmv-r8g3-qp46.raw\ndeleted file mode 100644\nindex 558e9f5..0000000\nBinary files a/fuzz/input/fuzz_server_ghsa-9mmv-r8g3-qp46.raw and /dev/null differ\ndiff --git a/include/rabbitmq-c/amqp.h b/include/rabbitmq-c/amqp.h\nindex d938bf5..2da9e38 100644\n--- a/include/rabbitmq-c/amqp.h\n+++ b/include/rabbitmq-c/amqp.h\n@@ -118,8 +118,8 @@ AMQP_BEGIN_DECLS\n  */\n \n #define AMQP_VERSION_MAJOR 0\n-#define AMQP_VERSION_MINOR 18\n-#define AMQP_VERSION_PATCH 1\n+#define AMQP_VERSION_MINOR 15\n+#define AMQP_VERSION_PATCH 0\n #define AMQP_VERSION_IS_RELEASE 1\n \n /**\n@@ -864,7 +864,7 @@ void AMQP_CALL amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount,\n  *\n  * \\since v0.15\n  */\n-#define amqp_literal_bytes(str) (amqp_bytes_t){sizeof(str) - 1, (void *)str}\n+#define amqp_literal_bytes(str) (amqp_bytes_t){sizeof(str) - 1, str}\n \n /**\n  * Wraps a c string in an amqp_bytes_t\n@@ -887,20 +887,6 @@ void AMQP_CALL amqp_pool_alloc_bytes(amqp_pool_t *pool, size_t amount,\n AMQP_EXPORT\n amqp_bytes_t AMQP_CALL amqp_cstring_bytes(char const *cstr);\n \n-/**\n- * Wraps a string of bytes in an amqp_bytes_t\n- *\n- * Takes a string of bytes and its length and creates an\n- * amqp_bytes_t that points to it. The input is not duplicated.\n- *\n- * \\param [in] ptr the string of bytes to wrap\n- * \\param [in] length the length of the string\n- * \\return an amqp_bytes_t that describes the string\n- *\n- * \\since v0.16\n- */\n-#define amqp_bytes_from_buffer(ptr, length) (amqp_bytes_t){length, (void *)ptr}\n-\n /**\n  * Duplicates an amqp_bytes_t buffer.\n  *\n@@ -1693,13 +1679,8 @@ amqp_rpc_reply_t AMQP_CALL amqp_get_rpc_reply(amqp_connection_state_t state);\n  *                 should be followed by two arguments in this order:\n  *                 const char* username, and const char* password.\n  *              -  AMQP_SASL_METHOD_EXTERNAL, the AMQP_SASL_METHOD_EXTERNAL\n- *                 argument must be followed by one argument:\n- *                 const char* identity. NULL and an empty string (\"\") are\n- *                 both accepted and are equivalent: they indicate the\n- *                 caller has no authorization identity to send, and the\n- *                 broker should rely on the identity established by the\n- *                 underlying transport (e.g. the TLS client certificate).\n- *                 See RFC 4422 Appendix A.\n+ *                 argument should be followed one argument:\n+ *                 const char* identity.\n  * \\return amqp_rpc_reply_t indicating success or failure.\n  *  - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully\n  *  - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors\n@@ -1764,13 +1745,8 @@ amqp_rpc_reply_t AMQP_CALL amqp_login(amqp_connection_state_t state,\n  *                should be followed by two arguments in this order:\n  *                const char* username, and const char* password.\n  *             -  AMQP_SASL_METHOD_EXTERNAL, the AMQP_SASL_METHOD_EXTERNAL\n- *                argument must be followed by one argument:\n- *                const char* identity. NULL and an empty string (\"\") are\n- *                both accepted and are equivalent: they indicate the\n- *                caller has no authorization identity to send, and the\n- *                broker should rely on the identity established by the\n- *                underlying transport (e.g. the TLS client certificate).\n- *                See RFC 4422 Appendix A.\n+ *                argument should be followed one argument:\n+ *                const char* identity.\n  * \\return amqp_rpc_reply_t indicating success or failure.\n  *  - r.reply_type == AMQP_RESPONSE_NORMAL. Login completed successfully\n  *  - r.reply_type == AMQP_RESPONSE_LIBRARY_EXCEPTION. In most cases errors\n@@ -2026,15 +2002,7 @@ const char *AMQP_CALL amqp_error_string2(int err);\n  * This is an internal function and is not typically used by\n  * client applications\n  *\n- * \\warning The decoded table entries contain direct references (pointers) into\n- *  the \\p encoded buffer rather than independent copies. The \\p encoded buffer\n- *  **must** remain valid and unmodified for as long as the decoded table (or\n- *  any data derived from it) is in use. Freeing or modifying \\p encoded while\n- *  the table is still live will result in use-after-free. Use\n- *  amqp_table_clone() if you need a fully independent copy of the table.\n- *\n- * \\param [in] encoded the buffer containing the serialized data. Must outlive\n- *             the decoded \\p output table.\n+ * \\param [in] encoded the buffer containing the serialized data\n  * \\param [in] pool memory pool used to allocate the table entries from\n  * \\param [in] output the amqp_table_t structure to fill in. Any existing\n  *             entries will be erased\ndiff --git a/librabbitmq.pc.in b/librabbitmq.pc.in\nindex f46a79c..711d01d 100644\n--- a/librabbitmq.pc.in\n+++ b/librabbitmq.pc.in\n@@ -8,6 +8,6 @@ Description: An AMQP 0-9-1 client library\n Version: @RMQ_VERSION@\n URL: https://github.com/alanxz/rabbitmq-c\n Requires.private: @requires_private@\n-Libs: -L${libdir} -l@RMQ_LIBRARY_NAME@\n+Libs: -L${libdir} -lrabbitmq\n Libs.private: @libs_private@\n Cflags: -I${includedir}\ndiff --git a/librabbitmq/CMakeLists.txt b/librabbitmq/CMakeLists.txt\nindex c7983ae..4466c9f 100644\n--- a/librabbitmq/CMakeLists.txt\n+++ b/librabbitmq/CMakeLists.txt\n@@ -29,7 +29,7 @@ endif()\n set(PUBLIC_INCLUDE_DIRS\n   $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>\n   $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>\n-  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>\n+  $<INSTALL_INTERFACE:include>\n )\n \n set(PRIVATE_INCLUDE_DIRS\ndiff --git a/librabbitmq/amqp_connection.c b/librabbitmq/amqp_connection.c\nindex 8b1c418..56ab8a8 100644\n--- a/librabbitmq/amqp_connection.c\n+++ b/librabbitmq/amqp_connection.c\n@@ -113,10 +113,6 @@ int amqp_tune_connection(amqp_connection_state_t state, int channel_max,\n \n   ENFORCE_STATE(state, CONNECTION_STATE_IDLE);\n \n-  if (frame_max < AMQP_FRAME_MIN_SIZE) {\n-    frame_max = AMQP_FRAME_MIN_SIZE;\n-  }\n-\n   state->channel_max = channel_max;\n   state->frame_max = frame_max;\n \n@@ -263,16 +259,6 @@ int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data,\n \n       channel = amqp_d16(amqp_offset(raw_frame, 1));\n \n-      /* channel_max == 0 means no explicit limit, AMQP sets this as 65535. */\n-      {\n-        amqp_channel_t max_channel = (0 != state->channel_max)\n-                                         ? (amqp_channel_t)state->channel_max\n-                                         : (amqp_channel_t)UINT16_MAX;\n-        if (channel > max_channel) {\n-          return AMQP_STATUS_BAD_AMQP_DATA;\n-        }\n-      }\n-\n       /* frame length is 3 bytes in */\n       frame_size = amqp_d32(amqp_offset(raw_frame, 3));\n       /* To prevent the target_size calculation below from overflowing, check\n@@ -334,13 +320,6 @@ int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data,\n \n       switch (decoded_frame->frame_type) {\n         case AMQP_FRAME_METHOD:\n-          /* A METHOD frame body must contain at least the 4-byte method id.\n-           * Reject undersized frames before subtracting from target_size to\n-           * avoid an unsigned underflow that would yield a huge encoded.len\n-           * and cause out-of-bounds reads in amqp_decode_method(). */\n-          if (state->target_size < HEADER_SIZE + 4 + FOOTER_SIZE) {\n-            return AMQP_STATUS_BAD_AMQP_DATA;\n-          }\n           decoded_frame->payload.method.id =\n               amqp_d32(amqp_offset(raw_frame, HEADER_SIZE));\n           encoded.bytes = amqp_offset(raw_frame, HEADER_SIZE + 4);\n@@ -356,15 +335,6 @@ int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data,\n           break;\n \n         case AMQP_FRAME_HEADER:\n-          /* A HEADER frame body must contain at least 12 bytes (class_id,\n-           * weight, body_size). Reject undersized frames before subtracting\n-           * from target_size to avoid an unsigned underflow that would yield\n-           * a huge encoded.len and cause out-of-bounds reads in\n-           * amqp_decode_properties() / the table decoder\n-           * (CVE: GHSA-9mmv-r8g3-qp46). */\n-          if (state->target_size < HEADER_SIZE + 12 + FOOTER_SIZE) {\n-            return AMQP_STATUS_BAD_AMQP_DATA;\n-          }\n           decoded_frame->payload.properties.class_id =\n               amqp_d16(amqp_offset(raw_frame, HEADER_SIZE));\n           /* unused 2-byte weight field goes here */\n@@ -384,9 +354,6 @@ int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data,\n           break;\n \n         case AMQP_FRAME_BODY:\n-          if (state->target_size < HEADER_SIZE + FOOTER_SIZE) {\n-            return AMQP_STATUS_BAD_AMQP_DATA;\n-          }\n           decoded_frame->payload.body_fragment.len =\n               state->target_size - HEADER_SIZE - FOOTER_SIZE;\n           decoded_frame->payload.body_fragment.bytes =\n@@ -394,15 +361,12 @@ int amqp_handle_input(amqp_connection_state_t state, amqp_bytes_t received_data,\n           break;\n \n         case AMQP_FRAME_HEARTBEAT:\n-          /* Heartbeat frames must be sent on the connection channel. */\n-          if (0 != decoded_frame->channel) {\n-            return AMQP_STATUS_BAD_AMQP_DATA;\n-          }\n           break;\n \n         default:\n-          /* Unrecognized frame type: this is a framing error per AMQP spec. */\n-          return AMQP_STATUS_BAD_AMQP_DATA;\n+          /* Ignore the frame */\n+          decoded_frame->frame_type = 0;\n+          break;\n       }\n \n       return_to_idle(state);\n@@ -477,14 +441,6 @@ static int amqp_frame_to_bytes(const amqp_frame_t *frame, amqp_bytes_t buffer,\n     case AMQP_FRAME_BODY: {\n       const amqp_bytes_t *body = &frame->payload.body_fragment;\n \n-      /* Ensure the body fragment fits within the outbound buffer, leaving\n-       * room for the frame header and footer. Without this check an\n-       * oversized body fragment would overflow the heap-allocated buffer. */\n-      if (buffer.len < HEADER_SIZE + FOOTER_SIZE ||\n-          body->len > buffer.len - (HEADER_SIZE + FOOTER_SIZE)) {\n-        return AMQP_STATUS_BAD_AMQP_DATA;\n-      }\n-\n       memcpy(amqp_offset(out_frame, HEADER_SIZE), body->bytes, body->len);\n \n       out_frame_len = body->len;\ndiff --git a/librabbitmq/amqp_consumer.c b/librabbitmq/amqp_consumer.c\nindex 81a82cf..f2ea617 100644\n--- a/librabbitmq/amqp_consumer.c\n+++ b/librabbitmq/amqp_consumer.c\n@@ -206,12 +206,6 @@ amqp_rpc_reply_t amqp_read_message(amqp_connection_state_t state,\n     goto error_out1;\n   }\n \n-  if (AMQP_BASIC_CLASS != frame.payload.properties.class_id) {\n-    ret.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;\n-    ret.library_error = AMQP_STATUS_BAD_AMQP_DATA;\n-    goto error_out1;\n-  }\n-\n   init_amqp_pool(&message->pool, 4096);\n   res = amqp_basic_properties_clone(frame.payload.properties.decoded,\n                                     &message->properties, &message->pool);\ndiff --git a/librabbitmq/amqp_framing.c b/librabbitmq/amqp_framing.c\nindex 9dc70de..35f026d 100644\n--- a/librabbitmq/amqp_framing.c\n+++ b/librabbitmq/amqp_framing.c\n@@ -1413,16 +1413,15 @@ int amqp_decode_properties(uint16_t class_id, amqp_pool_t *pool,\n   size_t offset = 0;\n \n   amqp_flags_t flags = 0;\n+  int flagword_index = 0;\n   uint16_t partial_flags;\n \n-  if (!amqp_decode_16(encoded, &offset, &partial_flags))\n-    return AMQP_STATUS_BAD_AMQP_DATA;\n-  /* No AMQP 0-9-1 class defines more than 14 properties, so all property\n-     flags fit in a single 16-bit flag word. Bit 0 is the continuation bit;\n-     if it is set the message declares further flag words, which we do not\n-     support, so reject the frame rather than misinterpret it. */\n-  if (partial_flags & 1) return AMQP_STATUS_BAD_AMQP_DATA;\n-  flags = partial_flags;\n+  do {\n+    if (!amqp_decode_16(encoded, &offset, &partial_flags))\n+      return AMQP_STATUS_BAD_AMQP_DATA;\n+    flags |= (partial_flags << (flagword_index * 16));\n+    flagword_index++;\n+  } while (partial_flags & 1);\n \n   switch (class_id) {\n     case 10: {\ndiff --git a/librabbitmq/amqp_private.h b/librabbitmq/amqp_private.h\nindex 93ee7f6..77a6904 100644\n--- a/librabbitmq/amqp_private.h\n+++ b/librabbitmq/amqp_private.h\n@@ -299,10 +299,7 @@ static inline int amqp_encode_bytes(amqp_bytes_t encoded, size_t *offset,\n   if (input.len == 0) {\n     return 1;\n   }\n-  *offset = o + input.len;\n-  /* Compare against remaining space rather than o + input.len to avoid size_t\n-   * overflow; o <= encoded.len, so encoded.len - o cannot underflow. */\n-  if (o <= encoded.len && input.len <= encoded.len - o) {\n+  if ((*offset = o + input.len) <= encoded.len) {\n     memcpy(amqp_offset(encoded.bytes, o), input.bytes, input.len);\n     return 1;\n   } else {\n@@ -313,12 +310,7 @@ static inline int amqp_encode_bytes(amqp_bytes_t encoded, size_t *offset,\n static inline int amqp_decode_bytes(amqp_bytes_t encoded, size_t *offset,\n                                     amqp_bytes_t *output, size_t len) {\n   size_t o = *offset;\n-  *offset = o + len;\n-  /* Compare against remaining space rather than o + len: with len read from the\n-   * wire (uint32_t), o + len can overflow size_t on 32-bit platforms and wrap\n-   * past the check, yielding an out-of-bounds amqp_bytes_t. o <= encoded.len,\n-   * so encoded.len - o cannot underflow. */\n-  if (o <= encoded.len && len <= encoded.len - o) {\n+  if ((*offset = o + len) <= encoded.len) {\n     output->bytes = amqp_offset(encoded.bytes, o);\n     output->len = len;\n     return 1;\ndiff --git a/librabbitmq/amqp_socket.c b/librabbitmq/amqp_socket.c\nindex ea27929..094ceb7 100644\n--- a/librabbitmq/amqp_socket.c\n+++ b/librabbitmq/amqp_socket.c\n@@ -174,6 +174,7 @@ start_poll:\n         return AMQP_STATUS_SOCKET_ERROR;\n     }\n   }\n+  return AMQP_STATUS_OK;\n #elif defined(HAVE_SELECT)\n   fd_set fds;\n   fd_set exceptfds;\n@@ -291,7 +292,6 @@ int amqp_open_socket_noblock(char const *hostname, int portnumber,\n #ifdef _WIN32\n static int connect_socket(struct addrinfo *addr, amqp_time_t deadline) {\n   int one = 1;\n-  u_long nonblocking = 1;\n   SOCKET sockfd;\n   int last_error;\n \n@@ -306,7 +306,7 @@ static int connect_socket(struct addrinfo *addr, amqp_time_t deadline) {\n   }\n \n   /* Set the socket to be non-blocking */\n-  if (SOCKET_ERROR == ioctlsocket(sockfd, FIONBIO, &nonblocking)) {\n+  if (SOCKET_ERROR == ioctlsocket(sockfd, FIONBIO, &one)) {\n     last_error = AMQP_STATUS_SOCKET_ERROR;\n     goto err;\n   }\n@@ -569,34 +569,23 @@ int sasl_mechanism_in_list(amqp_bytes_t mechanisms,\n }\n \n static amqp_bytes_t sasl_response(amqp_pool_t *pool,\n-                                  amqp_sasl_method_enum method, va_list args,\n-                                  int *status) {\n-  amqp_bytes_t response = amqp_empty_bytes;\n-\n-  *status = AMQP_STATUS_OK;\n+                                  amqp_sasl_method_enum method, va_list args) {\n+  amqp_bytes_t response;\n \n   switch (method) {\n     case AMQP_SASL_METHOD_PLAIN: {\n       char *username = va_arg(args, char *);\n+      size_t username_len = strlen(username);\n       char *password = va_arg(args, char *);\n-      size_t username_len;\n-      size_t password_len;\n+      size_t password_len = strlen(password);\n       char *response_buf;\n \n-      if (username == NULL || password == NULL) {\n-        *status = AMQP_STATUS_INVALID_PARAMETER;\n-        return response;\n-      }\n-\n-      username_len = strlen(username);\n-      password_len = strlen(password);\n-\n-      amqp_pool_alloc_bytes(pool, username_len + password_len + 2, &response);\n+      amqp_pool_alloc_bytes(pool, strlen(username) + strlen(password) + 2,\n+                            &response);\n       if (response.bytes == NULL)\n       /* We never request a zero-length block, because of the +2\n          above, so a NULL here really is ENOMEM. */\n       {\n-        *status = AMQP_STATUS_NO_MEMORY;\n         return response;\n       }\n \n@@ -609,27 +598,10 @@ static amqp_bytes_t sasl_response(amqp_pool_t *pool,\n     }\n     case AMQP_SASL_METHOD_EXTERNAL: {\n       char *identity = va_arg(args, char *);\n-      size_t identity_len;\n-\n-      /* NULL is treated the same as an empty identity: the caller has no\n-         authorization identity to send and the broker should rely on the\n-         identity established by the underlying transport (e.g. the TLS\n-         client certificate). See RFC 4422 Appendix A. */\n-      if (identity == NULL) {\n-        identity = \"\";\n-      }\n-\n-      identity_len = strlen(identity);\n-      if (identity_len == 0) {\n-        /* response is already amqp_empty_bytes; amqp_pool_alloc_bytes()\n-           would return NULL for a zero-length request, which is\n-           indistinguishable from ENOMEM, so skip the allocation entirely. */\n-        break;\n-      }\n+      size_t identity_len = strlen(identity);\n \n       amqp_pool_alloc_bytes(pool, identity_len, &response);\n       if (response.bytes == NULL) {\n-        *status = AMQP_STATUS_NO_MEMORY;\n         return response;\n       }\n \n@@ -1319,12 +1291,9 @@ static amqp_rpc_reply_t amqp_login_inner(amqp_connection_state_t state,\n       goto error_res;\n     }\n \n-    response_bytes = sasl_response(channel_pool, sasl_method, vl, &res);\n-    if (AMQP_STATUS_OK != res) {\n-      /* Note: response_bytes.bytes == NULL is not itself an error here: a\n-         zero-length response (e.g. AMQP_SASL_METHOD_EXTERNAL with an empty\n-         identity) is a valid, successful result. sasl_response() reports\n-         real allocation failures via res. */\n+    response_bytes = sasl_response(channel_pool, sasl_method, vl);\n+    if (response_bytes.bytes == NULL) {\n+      res = AMQP_STATUS_NO_MEMORY;\n       goto error_res;\n     }\n \n@@ -1418,7 +1387,6 @@ static amqp_rpc_reply_t amqp_login_inner(amqp_connection_state_t state,\n   if (res < 0) {\n     goto error_res;\n   }\n-  client_frame_max = (uint32_t)amqp_get_frame_max(state);\n \n   {\n     amqp_connection_tune_ok_t s;\ndiff --git a/librabbitmq/codegen.py b/librabbitmq/codegen.py\nindex e1c9115..9b04ce3 100644\n--- a/librabbitmq/codegen.py\n+++ b/librabbitmq/codegen.py\n@@ -313,7 +313,7 @@ def genErl(spec):\n \n     print(\"\"\"// Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.\n // SPDX-License-Identifier: mit\n-\n+    \n  /* Generated code. Do not edit. Edit and re-run codegen.py instead. */\n \n #ifdef HAVE_CONFIG_H\n@@ -330,7 +330,7 @@ def genErl(spec):\n     print(\"\"\"\n char const *amqp_constant_name(int constantNumber) {\n   switch (constantNumber) {\"\"\")\n-    for (c,_,_) in spec.constants:\n+    for (c,v,cls) in spec.constants:\n         print(\"    case %s: return \\\"%s\\\";\" % (cConstantName(c), cConstantName(c)))\n     print(\"\"\"    default: return \"(unknown)\";\n   }\n@@ -339,7 +339,7 @@ char const *amqp_constant_name(int constantNumber) {\n     print(\"\"\"\n amqp_boolean_t amqp_constant_is_hard_error(int constantNumber) {\n   switch (constantNumber) {\"\"\")\n-    for (c,_,cls) in spec.constants:\n+    for (c,v,cls) in spec.constants:\n         if cls == 'hard-error':\n             print(\"    case %s: return 1;\" % (cConstantName(c),))\n     print(\"\"\"    default: return 0;\n@@ -388,16 +388,15 @@ int amqp_decode_properties(uint16_t class_id,\n   size_t offset = 0;\n \n   amqp_flags_t flags = 0;\n+  int flagword_index = 0;\n   uint16_t partial_flags;\n \n-  if (!amqp_decode_16(encoded, &offset, &partial_flags))\n-    return AMQP_STATUS_BAD_AMQP_DATA;\n-  /* No AMQP 0-9-1 class defines more than 14 properties, so all property\n-     flags fit in a single 16-bit flag word. Bit 0 is the continuation bit;\n-     if it is set the message declares further flag words, which we do not\n-     support, so reject the frame rather than misinterpret it. */\n-  if (partial_flags & 1) return AMQP_STATUS_BAD_AMQP_DATA;\n-  flags = partial_flags;\n+  do {\n+    if (!amqp_decode_16(encoded, &offset, &partial_flags))\n+      return AMQP_STATUS_BAD_AMQP_DATA;\n+    flags |= (partial_flags << (flagword_index * 16));\n+    flagword_index++;\n+  } while (partial_flags & 1);\n \n   switch (class_id) {\"\"\")\n     for c in spec.allClasses(): genDecodeProperties(c)\n@@ -503,7 +502,7 @@ def genHrl(spec):\n \n     print(\"\"\"// Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.\n // SPDX-License-Identifier: mit\n-\n+    \n  /* Generated code. Do not edit. Edit and re-run codegen.py instead. */\n \n /** @file rabbitmq-c/framing.h */\ndiff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt\nindex 38f9331..8c0aee0 100644\n--- a/tests/CMakeLists.txt\n+++ b/tests/CMakeLists.txt\n@@ -23,10 +23,6 @@ add_executable(test_status_enum\n target_link_libraries(test_status_enum rabbitmq-static)\n add_test(status_enum test_status_enum)\n \n-add_executable(test_tune_connection test_tune_connection.c)\n-target_link_libraries(test_tune_connection rabbitmq-static)\n-add_test(tune_connection test_tune_connection)\n-\n add_executable(test_basic\n                test_basic.c)\n target_link_libraries(test_basic rabbitmq-static)\n@@ -45,14 +41,3 @@ add_executable(test_merge_capabilities test_merge_capabilities.c)\n target_link_libraries(test_merge_capabilities rabbitmq-static)\n add_test(merge_capabilities test_merge_capabilities)\n \n-add_executable(test_send_frame test_send_frame.c)\n-target_link_libraries(test_send_frame rabbitmq-static)\n-add_test(send_frame test_send_frame)\n-\n-add_executable(test_decode_bytes test_decode_bytes.c)\n-target_link_libraries(test_decode_bytes rabbitmq-static)\n-add_test(decode_bytes test_decode_bytes)\n-\n-add_executable(test_handle_input_frame_validation test_handle_input_frame_validation.c)\n-target_link_libraries(test_handle_input_frame_validation rabbitmq-static)\n-add_test(handle_input_frame_validation test_handle_input_frame_validation)\ndiff --git a/tests/test_basic.c b/tests/test_basic.c\nindex 514c7ce..25c7498 100644\n--- a/tests/test_basic.c\n+++ b/tests/test_basic.c\n@@ -110,9 +110,6 @@ char *basic_get(amqp_connection_state_t connection_state_,\n   assert(rpc_reply.reply_type == AMQP_RESPONSE_NORMAL);\n \n   char *body = malloc(message.body.len);\n-  if (body == NULL) {\n-    return NULL;\n-  }\n   memcpy(body, message.body.bytes, message.body.len);\n   *out_body_size_ = message.body.len;\n   amqp_destroy_message(&message);\n@@ -129,7 +126,6 @@ void publish_and_basic_get_message(const char *msg_to_publish) {\n   uint64_t body_size;\n   char *msg = basic_get(connection_state, test_queue_name, &body_size);\n \n-  assert(msg != NULL && \"Test errored: memory allocation failed!\");\n   assert(body_size == strlen(msg_to_publish));\n   assert(strncmp(msg_to_publish, msg, body_size) == 0);\n   free(msg);\n@@ -155,9 +151,6 @@ char *consume_message(amqp_connection_state_t connection_state_,\n \n   *out_body_size_ = envelope.message.body.len;\n   char *body = malloc(*out_body_size_);\n-  if (body == NULL) {\n-    return NULL;\n-  }\n   if (*out_body_size_) {\n     memcpy(body, envelope.message.body.bytes, *out_body_size_);\n   }\n@@ -175,7 +168,6 @@ void publish_and_consume_message(const char *msg_to_publish) {\n   uint64_t body_size;\n   char *msg = consume_message(connection_state, test_queue_name, &body_size);\n \n-  assert(msg != NULL && \"Test errored: memory allocation failed!\");\n   assert(body_size == strlen(msg_to_publish));\n   assert(strncmp(msg_to_publish, msg, body_size) == 0);\n   free(msg);\ndiff --git a/tests/test_decode_bytes.c b/tests/test_decode_bytes.c\ndeleted file mode 100644\nindex 17309f6..0000000\n--- a/tests/test_decode_bytes.c\n+++ /dev/null\n@@ -1,84 +0,0 @@\n-// Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include <stdint.h>\n-#include <stdio.h>\n-#include <stdlib.h>\n-\n-#include \"amqp_private.h\"\n-\n-/* Regression test for GHSA-jgjf-7fwf-f3c7: a size_t integer overflow in\n- * amqp_decode_bytes bypassed the bounds check on 32-bit systems, producing an\n- * out-of-bounds amqp_bytes_t (information disclosure / crash). The check must\n- * reject any (offset, len) pair that would read past the end of the buffer,\n- * including ones where offset + len wraps around SIZE_MAX. */\n-\n-static int failures = 0;\n-\n-static void expect_reject(const char *name, amqp_bytes_t encoded, size_t offset,\n-                          size_t len) {\n-  amqp_bytes_t output;\n-  size_t off = offset;\n-  output.bytes = NULL;\n-  output.len = 0;\n-  if (amqp_decode_bytes(encoded, &off, &output, len)) {\n-    fprintf(stderr,\n-            \"FAIL %s: amqp_decode_bytes accepted an out-of-bounds length \"\n-            \"(offset=%zu len=%zu buffer=%zu) -> output.len=%zu\\n\",\n-            name, offset, len, encoded.len, output.len);\n-    failures++;\n-  }\n-}\n-\n-static void expect_accept(const char *name, amqp_bytes_t encoded, size_t offset,\n-                          size_t len) {\n-  amqp_bytes_t output;\n-  size_t off = offset;\n-  output.bytes = NULL;\n-  output.len = 0;\n-  if (!amqp_decode_bytes(encoded, &off, &output, len)) {\n-    fprintf(stderr,\n-            \"FAIL %s: amqp_decode_bytes rejected a valid length \"\n-            \"(offset=%zu len=%zu buffer=%zu)\\n\",\n-            name, offset, len, encoded.len);\n-    failures++;\n-    return;\n-  }\n-  if (output.len != len || output.bytes != amqp_offset(encoded.bytes, offset)) {\n-    fprintf(stderr, \"FAIL %s: amqp_decode_bytes produced wrong output\\n\", name);\n-    failures++;\n-  }\n-}\n-\n-int main(void) {\n-  char buffer[16];\n-  amqp_bytes_t encoded;\n-  encoded.bytes = buffer;\n-  encoded.len = sizeof(buffer);\n-\n-  /* Normal, in-bounds decodes still work. */\n-  expect_accept(\"full buffer\", encoded, 0, sizeof(buffer));\n-  expect_accept(\"partial at offset\", encoded, 4, 8);\n-  expect_accept(\"zero length\", encoded, 8, 0);\n-\n-  /* Plain out-of-bounds (no overflow) is rejected. */\n-  expect_reject(\"len past end\", encoded, 0, sizeof(buffer) + 1);\n-  expect_reject(\"offset past end\", encoded, sizeof(buffer) + 1, 0);\n-\n-  /* The core of the advisory: a wire length large enough that offset + len\n-   * wraps around SIZE_MAX. On 32-bit platforms a uint32_t length of\n-   * 0xFFFFFFF5 with a small offset wraps to a tiny value; on any platform we\n-   * can force the wrap with a len near SIZE_MAX. Both must be rejected rather\n-   * than producing a multi-gigabyte amqp_bytes_t into a small buffer. */\n-  expect_reject(\"overflow to zero\", encoded, 11, (size_t)0 - 11);\n-  expect_reject(\"overflow wraps small\", encoded, 16, (size_t)0 - 8);\n-  expect_reject(\"max len\", encoded, 1, (size_t)-1);\n-  expect_reject(\"32-bit style len\", encoded, 11, (size_t)0xFFFFFFF5u);\n-\n-  if (failures) {\n-    fprintf(stderr, \"%d test(s) failed\\n\", failures);\n-    return 1;\n-  }\n-  printf(\"all amqp_decode_bytes bounds tests passed\\n\");\n-  return 0;\n-}\ndiff --git a/tests/test_handle_input_frame_validation.c b/tests/test_handle_input_frame_validation.c\ndeleted file mode 100644\nindex d9e3c6c..0000000\n--- a/tests/test_handle_input_frame_validation.c\n+++ /dev/null\n@@ -1,185 +0,0 @@\n-// Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-/* Regression test for a client-side memory-exhaustion DoS: frames on\n- * channels beyond channel_max, or with an unrecognized frame type, were\n- * accepted instead of rejected, letting a peer grow per-channel pool\n- * memory without bound. */\n-\n-#include \"amqp_private.h\"\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-#include <stdio.h>\n-#include <stdlib.h>\n-\n-static amqp_connection_state_t new_ready_state(int channel_max, int frame_max) {\n-  amqp_connection_state_t state = amqp_new_connection();\n-  if (state == NULL) {\n-    fprintf(stderr, \"amqp_new_connection failed\\n\");\n-    abort();\n-  }\n-\n-  /* Mirrors the private return_to_idle() helper, so amqp_handle_input()\n-   * parses an ordinary frame instead of expecting a protocol header. */\n-  state->inbound_buffer.bytes = state->header_buffer;\n-  state->inbound_buffer.len = sizeof(state->header_buffer);\n-  state->inbound_offset = 0;\n-  state->target_size = HEADER_SIZE;\n-  state->state = CONNECTION_STATE_IDLE;\n-  state->channel_max = channel_max;\n-  state->frame_max = frame_max;\n-\n-  return state;\n-}\n-\n-/* Builds a minimal frame: header (type, channel, size) + empty payload +\n- * frame-end footer. */\n-static size_t build_empty_frame(uint8_t *buf, uint8_t frame_type,\n-                                uint16_t channel) {\n-  buf[0] = frame_type;\n-  amqp_e16(channel, buf + 1);\n-  amqp_e32(0, buf + 3);\n-  buf[7] = AMQP_FRAME_END;\n-  return 8;\n-}\n-\n-static void test_channel_exceeding_channel_max_rejected(void) {\n-  amqp_connection_state_t state = new_ready_state(1, AMQP_FRAME_MIN_SIZE);\n-  amqp_frame_t frame;\n-  amqp_bytes_t data;\n-  uint8_t buf[8];\n-  int res;\n-\n-  data.len = build_empty_frame(buf, 0xff, 2);\n-  data.bytes = buf;\n-\n-  res = amqp_handle_input(state, data, &frame);\n-  if (res != AMQP_STATUS_BAD_AMQP_DATA) {\n-    fprintf(stderr,\n-            \"expected AMQP_STATUS_BAD_AMQP_DATA (%d) for channel > \"\n-            \"channel_max, got %d\\n\",\n-            AMQP_STATUS_BAD_AMQP_DATA, res);\n-    abort();\n-  }\n-\n-  if (amqp_get_channel_pool(state, 2) != NULL) {\n-    fprintf(stderr,\n-            \"channel pool was created for a channel beyond channel_max\\n\");\n-    abort();\n-  }\n-\n-  amqp_destroy_connection(state);\n-}\n-\n-/* channel_max == 0 means no explicit limit, which per spec caps channels\n- * at 65535 rather than leaving them unbounded. */\n-static void test_channel_max_zero_means_protocol_max(void) {\n-  amqp_connection_state_t state = new_ready_state(0, AMQP_FRAME_MIN_SIZE);\n-  amqp_frame_t frame;\n-  amqp_bytes_t data;\n-  uint8_t buf[8];\n-  int res;\n-\n-  data.len = build_empty_frame(buf, AMQP_FRAME_BODY, 65535);\n-  data.bytes = buf;\n-\n-  res = amqp_handle_input(state, data, &frame);\n-  if (res != (int)data.len) {\n-    fprintf(stderr, \"expected frame to be consumed (%d), got %d\\n\",\n-            (int)data.len, res);\n-    abort();\n-  }\n-  if (frame.frame_type != AMQP_FRAME_BODY || frame.channel != 65535) {\n-    fprintf(stderr, \"expected a body frame on channel 65535 to be accepted\\n\");\n-    abort();\n-  }\n-\n-  amqp_destroy_connection(state);\n-}\n-\n-static void test_heartbeat_on_nonzero_channel_rejected(void) {\n-  amqp_connection_state_t state = new_ready_state(0, AMQP_FRAME_MIN_SIZE);\n-  amqp_frame_t frame;\n-  amqp_bytes_t data;\n-  uint8_t buf[8];\n-  int res;\n-\n-  data.len = build_empty_frame(buf, AMQP_FRAME_HEARTBEAT, 1);\n-  data.bytes = buf;\n-\n-  res = amqp_handle_input(state, data, &frame);\n-  if (res != AMQP_STATUS_BAD_AMQP_DATA) {\n-    fprintf(stderr,\n-            \"expected AMQP_STATUS_BAD_AMQP_DATA (%d) for heartbeat on \"\n-            \"non-zero channel, got %d\\n\",\n-            AMQP_STATUS_BAD_AMQP_DATA, res);\n-    abort();\n-  }\n-\n-  amqp_destroy_connection(state);\n-}\n-\n-static void test_unknown_frame_type_rejected(void) {\n-  amqp_connection_state_t state = new_ready_state(1, AMQP_FRAME_MIN_SIZE);\n-  amqp_frame_t frame;\n-  amqp_bytes_t data;\n-  uint8_t buf[8];\n-  int res;\n-\n-  data.len = build_empty_frame(buf, 0xff, 1);\n-  data.bytes = buf;\n-\n-  res = amqp_handle_input(state, data, &frame);\n-  if (res != AMQP_STATUS_BAD_AMQP_DATA) {\n-    fprintf(stderr,\n-            \"expected AMQP_STATUS_BAD_AMQP_DATA (%d) for an unrecognized \"\n-            \"frame type, got %d\\n\",\n-            AMQP_STATUS_BAD_AMQP_DATA, res);\n-    abort();\n-  }\n-\n-  amqp_destroy_connection(state);\n-}\n-\n-/* Unlike test_unknown_frame_type_rejected, also checks that no pool memory\n- * accumulates before the rejection. */\n-static void test_unknown_frame_type_stream_rejected_immediately(void) {\n-  amqp_connection_state_t state = new_ready_state(1, AMQP_FRAME_MIN_SIZE);\n-  amqp_pool_t *pool;\n-  amqp_frame_t frame;\n-  amqp_bytes_t data;\n-  uint8_t buf[8];\n-  int res;\n-\n-  data.len = build_empty_frame(buf, 0xff, 1);\n-  data.bytes = buf;\n-\n-  res = amqp_handle_input(state, data, &frame);\n-  if (res != AMQP_STATUS_BAD_AMQP_DATA) {\n-    fprintf(stderr,\n-            \"expected the first unrecognized frame to be rejected \"\n-            \"immediately, got %d\\n\",\n-            res);\n-    abort();\n-  }\n-\n-  pool = amqp_get_channel_pool(state, 1);\n-  if (pool != NULL && pool->pages.num_blocks > 1) {\n-    fprintf(stderr,\n-            \"channel pool grew to %d pages after a single rejected frame\\n\",\n-            pool->pages.num_blocks);\n-    abort();\n-  }\n-\n-  amqp_destroy_connection(state);\n-}\n-\n-int main(void) {\n-  test_channel_exceeding_channel_max_rejected();\n-  test_channel_max_zero_means_protocol_max();\n-  test_heartbeat_on_nonzero_channel_rejected();\n-  test_unknown_frame_type_rejected();\n-  test_unknown_frame_type_stream_rejected_immediately();\n-  return 0;\n-}\ndiff --git a/tests/test_send_frame.c b/tests/test_send_frame.c\ndeleted file mode 100644\nindex 4d8e067..0000000\n--- a/tests/test_send_frame.c\n+++ /dev/null\n@@ -1,57 +0,0 @@\n-// Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include \"amqp_private.h\"\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-#include <stdio.h>\n-#include <stdlib.h>\n-#include <string.h>\n-\n-/* Regression test for GHSA-hfjv-vcp3-39wh: passing an oversized\n- * AMQP_FRAME_BODY to amqp_send_frame() must not overflow the outbound\n- * buffer. It should be rejected with AMQP_STATUS_BAD_AMQP_DATA. */\n-static void test_oversized_body_frame_rejected(void) {\n-  amqp_connection_state_t state = amqp_new_connection();\n-  amqp_frame_t frame;\n-  size_t body_len;\n-  char *body;\n-  int res;\n-\n-  if (state == NULL) {\n-    fprintf(stderr, \"amqp_new_connection failed\\n\");\n-    abort();\n-  }\n-\n-  /* The default outbound buffer is AMQP_DEFAULT_FRAME_SIZE bytes; use a\n-   * body fragment that is larger than that buffer can hold. */\n-  body_len = state->outbound_buffer.len + 1024;\n-  body = malloc(body_len);\n-  if (body == NULL) {\n-    fprintf(stderr, \"malloc failed\\n\");\n-    abort();\n-  }\n-  memset(body, 'A', body_len);\n-\n-  memset(&frame, 0, sizeof(frame));\n-  frame.frame_type = AMQP_FRAME_BODY;\n-  frame.channel = 1;\n-  frame.payload.body_fragment.bytes = body;\n-  frame.payload.body_fragment.len = body_len;\n-\n-  res = amqp_send_frame(state, &frame);\n-  if (res != AMQP_STATUS_BAD_AMQP_DATA) {\n-    fprintf(stderr, \"expected AMQP_STATUS_BAD_AMQP_DATA (%d), got %d\\n\",\n-            AMQP_STATUS_BAD_AMQP_DATA, res);\n-    abort();\n-  }\n-\n-  free(body);\n-  amqp_destroy_connection(state);\n-}\n-\n-int main(void) {\n-  test_oversized_body_frame_rejected();\n-  return 0;\n-}\ndiff --git a/tests/test_tune_connection.c b/tests/test_tune_connection.c\ndeleted file mode 100644\nindex 276e18d..0000000\n--- a/tests/test_tune_connection.c\n+++ /dev/null\n@@ -1,51 +0,0 @@\n-// Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.\n-// SPDX-License-Identifier: mit\n-\n-#include \"amqp_private.h\"\n-#include <rabbitmq-c/amqp.h>\n-#include <rabbitmq-c/framing.h>\n-\n-#include <stdio.h>\n-#include <stdlib.h>\n-\n-static void expect_frame_max(int requested, int expected) {\n-  int res;\n-  amqp_connection_state_t state = amqp_new_connection();\n-\n-  if (state == NULL) {\n-    fprintf(stderr, \"amqp_new_connection failed\\n\");\n-    abort();\n-  }\n-\n-  state->state = CONNECTION_STATE_IDLE;\n-\n-  res = amqp_tune_connection(state, 0, requested, 0);\n-  if (res != AMQP_STATUS_OK) {\n-    fprintf(stderr, \"amqp_tune_connection returned %d\\n\", res);\n-    abort();\n-  }\n-\n-  if (amqp_get_frame_max(state) != expected) {\n-    fprintf(stderr, \"expected frame_max %d, got %d\\n\", expected,\n-            amqp_get_frame_max(state));\n-    abort();\n-  }\n-\n-  if (state->outbound_buffer.len != (size_t)expected) {\n-    fprintf(stderr, \"expected outbound buffer length %d, got %zu\\n\", expected,\n-            state->outbound_buffer.len);\n-    abort();\n-  }\n-\n-  amqp_destroy_connection(state);\n-}\n-\n-int main(void) {\n-  expect_frame_max(0, AMQP_FRAME_MIN_SIZE);\n-  expect_frame_max(1, AMQP_FRAME_MIN_SIZE);\n-  expect_frame_max(AMQP_FRAME_MIN_SIZE - 1, AMQP_FRAME_MIN_SIZE);\n-  expect_frame_max(AMQP_FRAME_MIN_SIZE, AMQP_FRAME_MIN_SIZE);\n-  expect_frame_max(AMQP_DEFAULT_FRAME_SIZE, AMQP_DEFAULT_FRAME_SIZE);\n-\n-  return 0;\n-}\ndiff --git a/tools/common.c b/tools/common.c\nindex 31c93ae..7efe557 100644\n--- a/tools/common.c\n+++ b/tools/common.c\n@@ -136,13 +136,12 @@ static int amqp_ssl = 0;\n static char *amqp_cacert = \"/etc/ssl/certs/cacert.pem\";\n static char *amqp_key = NULL;\n static char *amqp_cert = NULL;\n-static int amqp_no_default_cert_paths = 0;\n #endif /* WITH_SSL */\n \n const char *connect_options_title = \"Connection options\";\n struct poptOption connect_options[] = {\n-    {\"url\", 'u', POPT_ARG_STRING, &amqp_url, 0,\n-     \"the AMQP URL to connect to (overrides AMQP_URL env var)\", \"amqp://...\"},\n+    {\"url\", 'u', POPT_ARG_STRING, &amqp_url, 0, \"the AMQP URL to connect to\",\n+     \"amqp://...\"},\n     {\"server\", 's', POPT_ARG_STRING, &amqp_server, 0,\n      \"the AMQP server to connect to\", \"hostname\"},\n     {\"port\", 0, POPT_ARG_INT, &amqp_port, 0, \"the port to connect on\", \"port\"},\n@@ -164,12 +163,10 @@ struct poptOption connect_options[] = {\n      \"path to the client private key file\", \"key.pem\"},\n     {\"cert\", 0, POPT_ARG_STRING, &amqp_cert, 0,\n      \"path to the client certificate file\", \"cert.pem\"},\n-    {\"no-default-cert-paths\", 0, POPT_ARG_NONE, &amqp_no_default_cert_paths, 0,\n-     \"do not use default certificate paths\", NULL},\n #endif /* WITH_SSL */\n     {NULL, '\\0', 0, NULL, 0, NULL, NULL}};\n \n-static void read_authfile(const char *path) {\n+void read_authfile(const char *path) {\n   size_t n;\n   FILE *fp = NULL;\n   char token[MAXAUTHTOKENLEN];\n@@ -211,7 +208,6 @@ static void read_authfile(const char *path) {\n   if (!feof(fp)) {\n     die(\"Malformed auth file (trailing data)\");\n   }\n-  fclose(fp);\n }\n \n static void init_connection_info(struct amqp_connection_info *ci) {\n@@ -224,17 +220,6 @@ static void init_connection_info(struct amqp_connection_info *ci) {\n \n   amqp_default_connection_info(ci);\n \n-  /* If no connection options were given on the CLI, fall back to AMQP_URL env\n-   * var. Any explicit CLI connection flag takes full precedence and bypasses\n-   * the env var entirely. */\n-  if (!amqp_url && !amqp_server && amqp_port < 0 && !amqp_username &&\n-      !amqp_password && !amqp_vhost) {\n-    const char *env_url = getenv(\"AMQP_URL\");\n-    if (env_url) {\n-      amqp_url = (char *)env_url;\n-    }\n-  }\n-\n   if (amqp_url)\n     die_amqp_error(amqp_parse_url(strdup(amqp_url), ci), \"Parsing URL '%s'\",\n                    amqp_url);\n@@ -364,9 +349,6 @@ amqp_connection_state_t make_connection(void) {\n     if (amqp_key) {\n       amqp_ssl_socket_set_key(socket, amqp_cert, amqp_key);\n     }\n-    if (!amqp_no_default_cert_paths) {\n-      amqp_ssl_socket_enable_default_verify_paths(socket);\n-    }\n #else\n     die(\"librabbitmq was not built with SSL/TLS support\");\n #endif\ndiff --git a/tools/consume.c b/tools/consume.c\nindex b4561b3..c2b0483 100644\n--- a/tools/consume.c\n+++ b/tools/consume.c\n@@ -16,9 +16,6 @@\n static char *stringify_bytes(amqp_bytes_t bytes) {\n   /* We will need up to 4 chars per byte, plus the terminating 0 */\n   char *res = malloc(bytes.len * 4 + 1);\n-  if (res == NULL) {\n-    return NULL;\n-  }\n   uint8_t *data = bytes.bytes;\n   char *p = res;\n   size_t i;\n@@ -70,10 +67,6 @@ static amqp_bytes_t setup_queue(amqp_connection_state_t conn, char *queue,\n       char *sq;\n       queue_bytes = amqp_bytes_malloc_dup(res->queue);\n       sq = stringify_bytes(queue_bytes);\n-      if (sq == NULL) {\n-        fprintf(stderr, \"Memory allocation failed.\\n\");\n-        exit(1);\n-      }\n       fprintf(stderr, \"Server provided queue name: %s\\n\", sq);\n       free(sq);\n     }\ndiff --git a/tools/doc/librabbitmq-tools.xml b/tools/doc/librabbitmq-tools.xml\nindex a4827c0..e7e98aa 100644\n--- a/tools/doc/librabbitmq-tools.xml\n+++ b/tools/doc/librabbitmq-tools.xml\n@@ -37,18 +37,6 @@\n     <refsect1>\n         <title>Common Options</title>\n         <variablelist>\n-            <varlistentry>\n-                <term><option>-u</option></term>\n-                <term><option>--url</option>=<replaceable class=\"parameter\">amqp://...</replaceable></term>\n-                <listitem>\n-                    <para>\n-                        The AMQP URL to connect to. Takes precedence\n-                        over the <envar>AMQP_URL</envar> environment\n-                        variable. If neither is given, the default\n-                        connection parameters are used.\n-                    </para>\n-                </listitem>\n-            </varlistentry>\n             <varlistentry>\n                 <term><option>-s</option></term>\n                 <term><option>--server</option>=<replaceable class=\"parameter\">hostname:port</replaceable></term>\n@@ -89,28 +77,6 @@\n         </variablelist>\n     </refsect1>\n \n-    <refsect1>\n-        <title>Environment Variables</title>\n-        <variablelist>\n-            <varlistentry>\n-                <term><envar>AMQP_URL</envar></term>\n-                <listitem>\n-                    <para>\n-                        Specifies the default AMQP URL to connect to.\n-                        Ignored if any connection option\n-                        (<option>--url</option>,\n-                        <option>--server</option>,\n-                        <option>--port</option>,\n-                        <option>--username</option>,\n-                        <option>--password</option>, or\n-                        <option>--vhost</option>) is given on the\n-                        command line.\n-                    </para>\n-                </listitem>\n-            </varlistentry>\n-        </variablelist>\n-    </refsect1>\n-\n     <refsect1>\n         <title>See also</title>\n         <para>\ndiff --git a/tools/publish.c b/tools/publish.c\nindex 7243ee7..6bc20da 100644\n--- a/tools/publish.c\n+++ b/tools/publish.c\n@@ -91,10 +91,6 @@ int main(int argc, const char **argv) {\n       amqp_table_t *table = &props.headers;\n       table->num_entries = num;\n       table->entries = calloc(num, sizeof(amqp_table_entry_t));\n-      if (table->entries == NULL) {\n-        fprintf(stderr, \"Memory allocation failed\\n\");\n-        return 1;\n-      }\n       int i = 0;\n       for (pos = headers; *pos; pos++) {\n         char *colon = strchr(*pos, ':');\n@@ -122,10 +118,6 @@ int main(int argc, const char **argv) {\n   } else {\n     if (line_buffered) {\n       body_bytes.bytes = (char *)malloc(MAX_LINE_LENGTH);\n-      if (body_bytes.bytes == NULL) {\n-        fprintf(stderr, \"Memory allocation failed\\n\");\n-        return 1;\n-      }\n       while (fgets(body_bytes.bytes, MAX_LINE_LENGTH, stdin)) {\n         body_bytes.len = strlen(body_bytes.bytes);\n         do_publish(conn, exchange, routing_key, &props, body_bytes);\n","remote_name":"debian/master","revision":"git-v1:c06a1c0c5de743a97d937add52a81121828d8317","role":"main"}],"result_code":"success","result_tags":[],"revision":"git-v1:c06a1c0c5de743a97d937add52a81121828d8317","start_time":"2026-11-08T01:09:30.217150Z","subpath":"","suite":"control","target_branch_url":null,"vcs_type":"git","worker":"tyr"},"run_id":"cc47cc1c-177a-4056-9f6d-86bc9b10581c","success_probability":1.0,"suite":"control","total_previous_runs":1,"utcnow":"2026-11-09T03:36:34.650537152+00:00","vcs_type":"git","vcs_url":"git+ssh://git@salsa.debian.org/debian/librabbitmq.git","version":"0.0.0","worker_log_name":"worker.log","worker_name":"tyr"}