Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package haproxy for openSUSE:Factory checked 
in at 2026-02-20 17:42:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/haproxy (Old)
 and      /work/SRC/openSUSE:Factory/.haproxy.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "haproxy"

Fri Feb 20 17:42:06 2026 rev:177 rq:1333967 version:3.3.4+git0.c2bffae0a

Changes:
--------
--- /work/SRC/openSUSE:Factory/haproxy/haproxy.changes  2026-02-12 
17:30:57.244416434 +0100
+++ /work/SRC/openSUSE:Factory/.haproxy.new.1977/haproxy.changes        
2026-02-20 17:44:19.191652878 +0100
@@ -1,0 +2,38 @@
+Thu Feb 19 13:52:23 UTC 2026 - Marcus Rueckert <[email protected]>
+
+- Update to version 3.3.4+git0.c2bffae0a:
+  * [RELEASE] Released version 3.3.4
+  * BUG/MINOR: backend: check delay MUX before conn_prepare()
+  * BUG/MINOR: acme: fix X509_NAME leak when X509_set_issuer_name() fails
+  * CLEANUP: mux-h1: Remove unneeded null check
+  * BUG/MEDIUM: ssl: SSL backend sessions used after free
+  * CI: github: disable windows.yml by default on unofficials repo
+  * CI: vtest: move the vtest2 URL to vinyl-cache.org
+  * MINOR: stconn: Add missing SC_FL_NO_FASTFWD flag in sc_show_flags
+  * BUG/MINOR: http-ana: Stop to wait for body on client error/abort
+  * CLEANUP: compression: Remove unused static buffers
+  * BUG/MINOR: flt-trace: Properly compute length of the first DATA block
+  * DEV: term-events: Fix hanshake events decoding
+  * BUG/MEDIUM: applet: Fix test on shut flags for legacy applets (v2)
+  * BUG/MEDIUM: mux-h1: Stop sending vi fast-forward for unexpected states
+  * BUG/MEDIUM: mux-h2/quic: Stop sending via fast-forward if stream is closed
+  * BUG/MEDIUM: h3: reject frontend CONNECT as currently not implemented
+  * BUG/MAJOR: Revert "MEDIUM: mux-quic: add BUG_ON if sending on locally 
closed QCS"
+  * BUG/MINOR: ssl: error with ssl-f-use when no "crt"
+  * BUG/MINOR: ssl: clarify ssl-f-use errors in post-section parsing
+  * BUG/MINOR: ssl: fix leak in ssl-f-use parser upon error
+  * BUG/MINOR: ssl: double-free on error path w/ ssl-f-use parser
+  * BUG/MINOR: ssl: lack crtlist_dup_ssl_conf() declaration
+  * BUG/MINOR: deviceatlas: set cache_size on hot-reloaded atlas instance
+  * BUG/MINOR: deviceatlas: fix deinit to only finalize when initialized
+  * BUG/MINOR: deviceatlas: fix resource leak on hot-reload compile failure
+  * BUG/MINOR: deviceatlas: fix double-checked locking race in checkinst
+  * BUG/MINOR: deviceatlas: fix cookie vlen using wrong length after extraction
+  * BUG/MINOR: deviceatlas: fix off-by-one in da_haproxy_conv()
+  * BUG/MEDIUM: deviceatlas: fix resource leaks on init error paths
+  * BUG/MINOR: deviceatlas: add NULL checks on strdup() results in config 
parsers
+  * BUG/MINOR: deviceatlas: add missing return on error in config parsers
+  * DOC: proxy-proto: underline the packed attribute for struct pp2_tlv_ssl
+  * DOC: internals: addd mworker V3 internals
+
+-------------------------------------------------------------------

Old:
----
  haproxy-3.3.3+git0.465d8e2fc.tar.gz

New:
----
  haproxy-3.3.4+git0.c2bffae0a.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ haproxy.spec ++++++
--- /var/tmp/diff_new_pack.1zu7RP/_old  2026-02-20 17:44:21.947768719 +0100
+++ /var/tmp/diff_new_pack.1zu7RP/_new  2026-02-20 17:44:21.951768886 +0100
@@ -49,7 +49,7 @@
 %bcond_with ech
 
 Name:           haproxy
-Version:        3.3.3+git0.465d8e2fc
+Version:        3.3.4+git0.c2bffae0a
 Release:        0
 #
 Summary:        The Reliable, High Performance TCP/HTTP Load Balancer

++++++ _service ++++++
--- /var/tmp/diff_new_pack.1zu7RP/_old  2026-02-20 17:44:22.139776789 +0100
+++ /var/tmp/diff_new_pack.1zu7RP/_new  2026-02-20 17:44:22.143776957 +0100
@@ -6,7 +6,7 @@
     <param name="versionformat">@PARENT_TAG@+git@TAG_OFFSET@.%h</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="versionrewrite-replacement">\1</param>
-    <param name="revision">v3.3.3</param>
+    <param name="revision">v3.3.4</param>
     <param name="changesgenerate">enable</param>
   </service>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.1zu7RP/_old  2026-02-20 17:44:22.215779983 +0100
+++ /var/tmp/diff_new_pack.1zu7RP/_new  2026-02-20 17:44:22.219780151 +0100
@@ -5,7 +5,7 @@
   </service>
   <service name="tar_scm">
     <param name="url">http://git.haproxy.org/git/haproxy-3.3.git/</param>
-    <param 
name="changesrevision">465d8e2fcfcbf4bbcf36c3f53a801369f4e7e922</param>
+    <param 
name="changesrevision">c2bffae0a2a44f7562c6ebd455cd8d2e79001fff</param>
   </service>
 </servicedata>
 (No newline at EOF)

++++++ haproxy-3.3.3+git0.465d8e2fc.tar.gz -> 
haproxy-3.3.4+git0.c2bffae0a.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.3.3+git0.465d8e2fc/.github/workflows/windows.yml 
new/haproxy-3.3.4+git0.c2bffae0a/.github/workflows/windows.yml
--- old/haproxy-3.3.3+git0.465d8e2fc/.github/workflows/windows.yml      
2026-02-12 14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/.github/workflows/windows.yml      
2026-02-19 14:03:31.000000000 +0100
@@ -18,6 +18,7 @@
   msys2:
     name: ${{ matrix.name }}
     runs-on: ${{ matrix.os }}
+    if: ${{ github.repository_owner == 'haproxy' || github.event_name == 
'workflow_dispatch' }}
     defaults:
       run:
         shell: msys2 {0}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/CHANGELOG 
new/haproxy-3.3.4+git0.c2bffae0a/CHANGELOG
--- old/haproxy-3.3.3+git0.465d8e2fc/CHANGELOG  2026-02-12 14:25:57.000000000 
+0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/CHANGELOG  2026-02-19 14:03:31.000000000 
+0100
@@ -1,6 +1,40 @@
 ChangeLog :
 ===========
 
+2026/02/19 : 3.3.4
+    - DOC: internals: addd mworker V3 internals
+    - DOC: proxy-proto: underline the packed attribute for struct pp2_tlv_ssl
+    - BUG/MINOR: deviceatlas: add missing return on error in config parsers
+    - BUG/MINOR: deviceatlas: add NULL checks on strdup() results in config 
parsers
+    - BUG/MEDIUM: deviceatlas: fix resource leaks on init error paths
+    - BUG/MINOR: deviceatlas: fix off-by-one in da_haproxy_conv()
+    - BUG/MINOR: deviceatlas: fix cookie vlen using wrong length after 
extraction
+    - BUG/MINOR: deviceatlas: fix double-checked locking race in checkinst
+    - BUG/MINOR: deviceatlas: fix resource leak on hot-reload compile failure
+    - BUG/MINOR: deviceatlas: fix deinit to only finalize when initialized
+    - BUG/MINOR: deviceatlas: set cache_size on hot-reloaded atlas instance
+    - BUG/MINOR: ssl: lack crtlist_dup_ssl_conf() declaration
+    - BUG/MINOR: ssl: double-free on error path w/ ssl-f-use parser
+    - BUG/MINOR: ssl: fix leak in ssl-f-use parser upon error
+    - BUG/MINOR: ssl: clarify ssl-f-use errors in post-section parsing
+    - BUG/MINOR: ssl: error with ssl-f-use when no "crt"
+    - BUG/MAJOR: Revert "MEDIUM: mux-quic: add BUG_ON if sending on locally 
closed QCS"
+    - BUG/MEDIUM: h3: reject frontend CONNECT as currently not implemented
+    - BUG/MEDIUM: mux-h2/quic: Stop sending via fast-forward if stream is 
closed
+    - BUG/MEDIUM: mux-h1: Stop sending vi fast-forward for unexpected states
+    - BUG/MEDIUM: applet: Fix test on shut flags for legacy applets (v2)
+    - DEV: term-events: Fix hanshake events decoding
+    - BUG/MINOR: flt-trace: Properly compute length of the first DATA block
+    - CLEANUP: compression: Remove unused static buffers
+    - BUG/MINOR: http-ana: Stop to wait for body on client error/abort
+    - MINOR: stconn: Add missing SC_FL_NO_FASTFWD flag in sc_show_flags
+    - CI: vtest: move the vtest2 URL to vinyl-cache.org
+    - CI: github: disable windows.yml by default on unofficials repo
+    - BUG/MEDIUM: ssl: SSL backend sessions used after free
+    - CLEANUP: mux-h1: Remove unneeded null check
+    - BUG/MINOR: acme: fix X509_NAME leak when X509_set_issuer_name() fails
+    - BUG/MINOR: backend: check delay MUX before conn_prepare()
+
 2026/02/12 : 3.3.3
     - MEDIUM: h1: strictly verify quoting in chunk extensions
     - DOC: internals: cleanup few typos in master-worker documentation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/VERDATE 
new/haproxy-3.3.4+git0.c2bffae0a/VERDATE
--- old/haproxy-3.3.3+git0.465d8e2fc/VERDATE    2026-02-12 14:25:57.000000000 
+0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/VERDATE    2026-02-19 14:03:31.000000000 
+0100
@@ -1,2 +1,2 @@
 $Format:%ci$
-2026/02/12
+2026/02/19
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/VERSION 
new/haproxy-3.3.4+git0.c2bffae0a/VERSION
--- old/haproxy-3.3.3+git0.465d8e2fc/VERSION    2026-02-12 14:25:57.000000000 
+0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/VERSION    2026-02-19 14:03:31.000000000 
+0100
@@ -1 +1 @@
-3.3.3
+3.3.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/addons/deviceatlas/da.c 
new/haproxy-3.3.4+git0.c2bffae0a/addons/deviceatlas/da.c
--- old/haproxy-3.3.3+git0.465d8e2fc/addons/deviceatlas/da.c    2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/addons/deviceatlas/da.c    2026-02-19 
14:03:31.000000000 +0100
@@ -57,6 +57,10 @@
                return -1;
        }
        global_deviceatlas.jsonpath = strdup(args[1]);
+       if (unlikely(global_deviceatlas.jsonpath == NULL)) {
+               memprintf(err, "deviceatlas json file : out of memory.\n");
+               return -1;
+       }
        return 0;
 }
 
@@ -73,6 +77,7 @@
        loglevel = atol(args[1]);
        if (loglevel < 0 || loglevel > 3) {
                memprintf(err, "deviceatlas log level : expects a log level 
between 0 and 3, %s given.\n", args[1]);
+               return -1;
        } else {
                global_deviceatlas.loglevel = (da_severity_t)loglevel;
        }
@@ -101,6 +106,10 @@
                return -1;
        } else {
                global_deviceatlas.cookiename = strdup(args[1]);
+               if (unlikely(global_deviceatlas.cookiename == NULL)) {
+                       memprintf(err, "deviceatlas cookie name : out of 
memory.\n");
+                       return -1;
+               }
        }
        global_deviceatlas.cookienamelen = 
strlen(global_deviceatlas.cookiename);
        return 0;
@@ -119,6 +128,7 @@
     cachesize = atol(args[1]);
     if (cachesize < 0 || cachesize > DA_CACHE_MAX) {
         memprintf(err, "deviceatlas cache size : expects a cache size between 
0 and %d, %s given.\n", DA_CACHE_MAX, args[1]);
+       return -1;
     } else {
 #ifdef APINOCACHE
         fprintf(stdout, "deviceatlas cache size : no-op, its support is 
disabled.\n");
@@ -180,6 +190,8 @@
                if (status != DA_OK) {
                        ha_alert("deviceatlas : '%s' json file is invalid.\n",
                                 global_deviceatlas.jsonpath);
+                       free(global_deviceatlas.atlasimgptr);
+                       da_fini();
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
@@ -189,6 +201,8 @@
 
                if (status != DA_OK) {
                        ha_alert("deviceatlas : data could not be compiled.\n");
+                       free(global_deviceatlas.atlasimgptr);
+                       da_fini();
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto out;
                }
@@ -197,6 +211,14 @@
 
                if (global_deviceatlas.cookiename == 0) {
                        global_deviceatlas.cookiename = 
strdup(DA_COOKIENAME_DEFAULT);
+                       if (unlikely(global_deviceatlas.cookiename == NULL)) {
+                               ha_alert("deviceatlas : out of memory.\n");
+                               da_atlas_close(&global_deviceatlas.atlas);
+                               free(global_deviceatlas.atlasimgptr);
+                               da_fini();
+                               err_code |= ERR_ALERT | ERR_FATAL;
+                               goto out;
+                       }
                        global_deviceatlas.cookienamelen = 
strlen(global_deviceatlas.cookiename);
                }
 
@@ -231,15 +253,13 @@
                free(global_deviceatlas.cookiename);
                da_atlas_close(&global_deviceatlas.atlas);
                free(global_deviceatlas.atlasimgptr);
+               da_fini();
        }
 
        if (global_deviceatlas.atlasfd != -1) {
                munmap(global_deviceatlas.atlasmap, ATLASTOKSZ);
                close(global_deviceatlas.atlasfd);
-               shm_unlink(ATLASMAPNM);
        }
-
-       da_fini();
 }
 
 static void da_haproxy_checkinst(void)
@@ -258,6 +278,10 @@
             da_property_decl_t extraprops[1] = {{NULL, 0}};
 #ifdef USE_THREAD
             HA_SPIN_LOCK(OTHER_LOCK, &dadwsch_lock);
+            if (base[0] == 0) {
+                HA_SPIN_UNLOCK(OTHER_LOCK, &dadwsch_lock);
+                return;
+            }
 #endif
             strlcpy2(atlasp, base + sizeof(char), sizeof(atlasp));
             jsonp = fopen(atlasp, "r");
@@ -275,6 +299,7 @@
             fclose(jsonp);
             if (status == DA_OK) {
                 if (da_atlas_open(&inst, extraprops, cnew, atlassz) == DA_OK) {
+                    inst.config.cache_size = global_deviceatlas.cachesize;
                     da_atlas_close(&global_deviceatlas.atlas);
                     free(global_deviceatlas.atlasimgptr);
                     global_deviceatlas.atlasimgptr = cnew;
@@ -286,6 +311,8 @@
                     ha_alert("deviceatlas : instance update failed.\n");
                     free(cnew);
                 }
+            } else {
+                free(cnew);
             }
 #ifdef USE_THREAD
             HA_SPIN_UNLOCK(OTHER_LOCK, &dadwsch_lock);
@@ -371,8 +398,7 @@
 {
        da_deviceinfo_t devinfo;
        da_status_t status;
-       const char *useragent;
-       char useragentbuf[1024] = { 0 };
+       char useragentbuf[1024];
        int i;
 
        if (global_deviceatlas.daset == 0 || smp->data.u.str.data == 0) {
@@ -381,14 +407,12 @@
 
        da_haproxy_checkinst();
 
-       i = smp->data.u.str.data > sizeof(useragentbuf) ? sizeof(useragentbuf) 
: smp->data.u.str.data;
-       memcpy(useragentbuf, smp->data.u.str.area, i - 1);
-       useragentbuf[i - 1] = 0;
-
-       useragent = (const char *)useragentbuf;
+       i = smp->data.u.str.data > sizeof(useragentbuf) - 1 ? 
sizeof(useragentbuf) - 1 : smp->data.u.str.data;
+       memcpy(useragentbuf, smp->data.u.str.area, i);
+       useragentbuf[i] = 0;
 
        status = da_search(&global_deviceatlas.atlas, &devinfo,
-               global_deviceatlas.useragentid, useragent, 0);
+               global_deviceatlas.useragentid, useragentbuf, 0);
 
        return status != DA_OK ? 0 : da_haproxy(args, smp, &devinfo);
 }
@@ -445,13 +469,12 @@
 
                memcpy(hbuf, n.ptr, n.len);
                hbuf[n.len] = 0;
-               pval = v.ptr;
-               vlen = v.len;
                evid = -1;
                i = v.len > sizeof(tval) - 1 ? sizeof(tval) - 1 : v.len;
                memcpy(tval, v.ptr, i);
                tval[i] = 0;
                pval = tval;
+               vlen = i;
 
                if (strcasecmp(hbuf, "Accept-Language") == 0) {
                        evid = 
da_atlas_accept_language_evidence_id(&global_deviceatlas.atlas);
@@ -469,7 +492,7 @@
                                continue;
                        }
 
-                       vlen -= global_deviceatlas.cookienamelen - 1;
+                       vlen = pl;
                        pval = p;
                        evid = 
da_atlas_clientprop_evidence_id(&global_deviceatlas.atlas);
                } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.3.3+git0.465d8e2fc/dev/term_events/term_events.c 
new/haproxy-3.3.4+git0.c2bffae0a/dev/term_events/term_events.c
--- old/haproxy-3.3.3+git0.465d8e2fc/dev/term_events/term_events.c      
2026-02-12 14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/dev/term_events/term_events.c      
2026-02-19 14:03:31.000000000 +0100
@@ -30,10 +30,10 @@
 };
 
 static const char *tevt_hs_types[16] = {
-       [ 0] = "-",       [ 1] = "-", [ 2] = "-", [ 3] = "rcv_err",
-       [ 4] = "snd_err", [ 5] = "-", [ 6] = "-", [ 7] = "-",
-       [ 8] = "-",       [ 9] = "-", [10] = "-", [11] = "-",
-       [12] = "-",       [13] = "-", [14] = "-", [15] = "-",
+       [ 0] = "-",       [ 1] = "-",               [ 2] = "-",                 
[ 3] = "-",
+       [ 4] = "snd_err", [ 5] = "truncated_shutr", [ 6] = "truncated_rcv_err", 
[ 7] = "-",
+       [ 8] = "-",       [ 9] = "-",               [10] = "-",                 
[11] = "-",
+       [12] = "-",       [13] = "-",               [14] = "-",                 
[15] = "-",
 };
 
 static const char *tevt_xprt_types[16] = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/doc/configuration.txt 
new/haproxy-3.3.4+git0.c2bffae0a/doc/configuration.txt
--- old/haproxy-3.3.3+git0.465d8e2fc/doc/configuration.txt      2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/doc/configuration.txt      2026-02-19 
14:03:31.000000000 +0100
@@ -3,7 +3,7 @@
                           Configuration Manual
                          ----------------------
                               version 3.3
-                              2026/02/12
+                              2026/02/19
 
 
 This document covers the configuration language as implemented in the version
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.3.3+git0.465d8e2fc/doc/internals/mworker.md 
new/haproxy-3.3.4+git0.c2bffae0a/doc/internals/mworker.md
--- old/haproxy-3.3.3+git0.465d8e2fc/doc/internals/mworker.md   2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/doc/internals/mworker.md   2026-02-19 
14:03:31.000000000 +0100
@@ -208,3 +208,38 @@
 Version 3.0 got rid of the libsystemd dependencies for sd_notify() after the
 events of xz/openssh, the function is now implemented directly in haproxy in
 src/systemd.c.
+
+### mworker V3
+
+This version was implemented with HAProxy 3.1, the goal was to stop parsing and
+applying the configuration in the master process.
+
+One of the caveats of the previous implementation was that the parser could 
take
+a lot of time, and the master process would be stuck in the parser instead of
+handling its polling loop, signals etc. Some parts of the configuration parsing
+could also be less reliable with third-party code (EXTRA_OBJS), it could, for
+example, allow opening FDs and not closing them before the reload which
+would crash the master after a few reloads.
+
+The startup of the master-worker was reorganized this way:
+
+- the "discovery" mode, which is a lighter configuration parsing step, only
+  applies the configuration which need to be effective for the master process.
+  For example, "master-worker", "mworker-max-reloads" and less than 20 other
+  keywords that are identified by KWF_DISCOVERY in the code. It is really fast
+  as it don't need all the configuration to be applied in the master process.
+
+- the master will then fork a worker, with a PROC_O_INIT flag. This worker has
+  a temporary sockpair connected to the master CLI. Once the worker is forked,
+  the master initializes its configuration and starts its polling loop.
+
+- The newly forked worker will try to parse the configuration, which could
+  result in a failure (exit 1), or any bad error code. In case of success, the
+  worker will send a "READY" message to the master CLI then close this FD. At
+  this step everything was initialized and the worker can enter its polling
+  loop.
+
+- The master then waits for the worker, it could:
+   * receive the READY message over the mCLI, resulting in a successful loading
+     of haproxy
+   * receive a SIGCHLD, meaning the worker exited and couldn't load
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/doc/proxy-protocol.txt 
new/haproxy-3.3.4+git0.c2bffae0a/doc/proxy-protocol.txt
--- old/haproxy-3.3.3+git0.465d8e2fc/doc/proxy-protocol.txt     2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/doc/proxy-protocol.txt     2026-02-19 
14:03:31.000000000 +0100
@@ -625,7 +625,10 @@
                 uint8_t  client;
                 uint32_t verify;
                 struct pp2_tlv sub_tlv[0];
-        };
+        } __attribute__((packed));
+
+Note the "packed" attribute which indicates that each field starts immediately
+after the previous one (i.e. without type-specific alignment nor padding).
 
 The <verify> field will be zero if the client presented a certificate
 and it was successfully verified, and non-zero otherwise.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.3.3+git0.465d8e2fc/include/haproxy/qmux_http.h 
new/haproxy-3.3.4+git0.c2bffae0a/include/haproxy/qmux_http.h
--- old/haproxy-3.3.3+git0.465d8e2fc/include/haproxy/qmux_http.h        
2026-02-12 14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/include/haproxy/qmux_http.h        
2026-02-19 14:03:31.000000000 +0100
@@ -13,6 +13,7 @@
 
 size_t qcs_http_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count,
                         char *fin);
+size_t qcs_http_reset_buf(struct qcs *qcs, struct buffer *buf, size_t count);
 
 #endif /* USE_QUIC */
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.3.3+git0.465d8e2fc/include/haproxy/ssl_crtlist.h 
new/haproxy-3.3.4+git0.c2bffae0a/include/haproxy/ssl_crtlist.h
--- old/haproxy-3.3.3+git0.465d8e2fc/include/haproxy/ssl_crtlist.h      
2026-02-12 14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/include/haproxy/ssl_crtlist.h      
2026-02-19 14:03:31.000000000 +0100
@@ -28,6 +28,7 @@
 
 /* crt-list entry functions */
 void ssl_sock_free_ssl_conf(struct ssl_bind_conf *conf);
+struct ssl_bind_conf *crtlist_dup_ssl_conf(struct ssl_bind_conf *src);
 char **crtlist_dup_filters(char **args, int fcount);
 void crtlist_free_filters(char **args);
 void crtlist_entry_free(struct crtlist_entry *entry);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/haproxy-3.3.3+git0.465d8e2fc/include/haproxy/stconn-t.h 
new/haproxy-3.3.4+git0.c2bffae0a/include/haproxy/stconn-t.h
--- old/haproxy-3.3.3+git0.465d8e2fc/include/haproxy/stconn-t.h 2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/include/haproxy/stconn-t.h 2026-02-19 
14:03:31.000000000 +0100
@@ -224,7 +224,7 @@
        _(SC_FL_NEED_BUFF, _(SC_FL_NEED_ROOM,
         _(SC_FL_RCV_ONCE, _(SC_FL_SND_ASAP, _(SC_FL_SND_NEVERWAIT, 
_(SC_FL_SND_EXP_MORE,
        _(SC_FL_ABRT_WANTED, _(SC_FL_SHUT_WANTED, _(SC_FL_ABRT_DONE, 
_(SC_FL_SHUT_DONE,
-       _(SC_FL_EOS, _(SC_FL_HAVE_BUFF))))))))))))))))))));
+       _(SC_FL_EOS, _(SC_FL_HAVE_BUFF, _(SC_FL_NO_FASTFWD)))))))))))))))))))));
        /* epilogue */
        _(~0U);
        return buf;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/scripts/build-vtest.sh 
new/haproxy-3.3.4+git0.c2bffae0a/scripts/build-vtest.sh
--- old/haproxy-3.3.3+git0.465d8e2fc/scripts/build-vtest.sh     2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/scripts/build-vtest.sh     2026-02-19 
14:03:31.000000000 +0100
@@ -2,7 +2,7 @@
 
 set -eux
 
-curl -fsSL https://github.com/vtest/VTest2/archive/main.tar.gz  -o VTest.tar.gz
+curl -fsSL "https://code.vinyl-cache.org/vtest/VTest2/archive/main.tar.gz"; -o 
VTest.tar.gz
 mkdir ../vtest
 tar xvf VTest.tar.gz -C ../vtest --strip-components=1
 # Special flags due to: https://github.com/vtest/VTest/issues/12
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/acme.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/acme.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/acme.c 2026-02-12 14:25:57.000000000 
+0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/acme.c 2026-02-19 14:03:31.000000000 
+0100
@@ -2681,8 +2681,10 @@
                goto mkcert_error;
        }
        /* Set issuer name as itself */
-       if (X509_set_issuer_name(newcrt, name) != 1)
+       if (X509_set_issuer_name(newcrt, name) != 1) {
+               X509_NAME_free(name);
                goto mkcert_error;
+       }
        X509_NAME_free(name);
 
        /* Autosign the certificate with the private key */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/applet.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/applet.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/applet.c       2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/applet.c       2026-02-19 
14:03:31.000000000 +0100
@@ -852,7 +852,7 @@
        /* Don't call I/O handler if the applet was shut (release callback was
         * already called)
         */
-       if (!se_fl_test(app->sedesc, SE_FL_SHR | SE_FL_SHW))
+       if (!se_fl_test(app->sedesc, SE_FL_SHR) || !se_fl_test(app->sedesc, 
SE_FL_SHW))
                app->applet->fct(app);
 
        TRACE_POINT(APPLET_EV_PROCESS, app);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/backend.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/backend.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/backend.c      2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/backend.c      2026-02-19 
14:03:31.000000000 +0100
@@ -2058,6 +2058,25 @@
                                        srv_conn->sni_hash = 
ssl_sock_sni_hash(sni);
                                }
                        }
+
+#if defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
+                       /* Delay mux initialization if SSL and ALPN/NPN is set
+                        * and server cache is not yet populated. Note that in
+                        * TCP mode this check is ignored as only mux-pt is
+                        * available.
+                        *
+                        * This check must be performed before conn_prepare()
+                        * to ensure consistency accross the whole stack, in
+                        * particular for QUIC between quic-conn and mux layer.
+                        */
+                       HA_RWLOCK_RDLOCK(SERVER_LOCK, 
&srv->path_params.param_lock);
+                       if (IS_HTX_STRM(s) && srv->use_ssl &&
+                           (srv->ssl_ctx.alpn_str || srv->ssl_ctx.npn_str) &&
+                           srv->path_params.nego_alpn[0] == 0)
+                               may_start_mux_now = 0;
+                       HA_RWLOCK_RDUNLOCK(SERVER_LOCK, 
&srv->path_params.param_lock);
+#endif /* TLSEXT_TYPE_application_layer_protocol_negotiation */
+
 #endif /* USE_OPENSSL */
 
                        if (conn_prepare(srv_conn, proto, srv->xprt)) {
@@ -2090,21 +2109,6 @@
                }
                srv_conn->ctx = s->scb;
 
-#if defined(USE_OPENSSL) && 
defined(TLSEXT_TYPE_application_layer_protocol_negotiation)
-               /* Delay mux initialization if SSL and ALPN/NPN is set. Note
-                * that this is skipped in TCP mode as we only want mux-pt
-                * anyway.
-                */
-               if (srv) {
-                       HA_RWLOCK_RDLOCK(SERVER_LOCK, 
&srv->path_params.param_lock);
-                       if (IS_HTX_STRM(s) && srv->use_ssl &&
-                           (srv->ssl_ctx.alpn_str || srv->ssl_ctx.npn_str) &&
-                           srv->path_params.nego_alpn[0] == 0)
-                               may_start_mux_now = 0;
-                       HA_RWLOCK_RDUNLOCK(SERVER_LOCK, 
&srv->path_params.param_lock);
-               }
-#endif
-
                /* process the case where the server requires the PROXY 
protocol to be sent */
                srv_conn->send_proxy_ofs = 0;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/cfgparse-ssl.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/cfgparse-ssl.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/cfgparse-ssl.c 2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/cfgparse-ssl.c 2026-02-19 
14:03:31.000000000 +0100
@@ -2558,11 +2558,14 @@
                }
 
                /* must set the ssl_conf in case of duplication of the 
crtlist_entry */
-               entry->ssl_conf = n->ssl_conf;
+               entry->ssl_conf = crtlist_dup_ssl_conf(n->ssl_conf);
 
                err_code |= crtlist_load_crt(n->ckch_conf->crt, n->ckch_conf, 
newlist, entry, n->filename, n->linenum, &err);
-               if (err_code & ERR_CODE)
+               if (err_code & ERR_CODE) {
+                       ha_alert("parsing [%s:%d] : %s", n->filename, 
n->linenum, err);
+                       ha_free(&err);
                        goto error;
+               }
 
                LIST_DELETE(&n->list);
                /* n->ssl_conf is reused so we don't free them here */
@@ -2574,7 +2577,8 @@
        if (newlist) {
 
                if (ebst_insert(&crtlists_tree, &newlist->node) != 
&newlist->node) {
-                       memprintf(&err, "Couldn't create the crt-list '%s', 
this name is already used by another crt-list!", crtlist_name);
+                       memprintf(&err, "parsing [%s:%d] : Couldn't create the 
crt-list '%s', this name is already used by another crt-list!",
+                                 curproxy->conf.file, curproxy->conf.line, 
crtlist_name);
                        err_code |= ERR_ALERT | ERR_FATAL;
                        goto error;
                }
@@ -2594,10 +2598,11 @@
 error:
 
        if (err)
-               ha_alert("%s.\n", err);
+               ha_alert("%s", err);
        free(err);
 
        list_for_each_entry_safe(n, r, &cur_crtlist, list) {
+               ha_free(&n->filename);
                ckch_conf_clean(n->ckch_conf);
                ha_free(&n->ckch_conf);
                ssl_sock_free_ssl_conf(n->ssl_conf);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/flt_http_comp.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/flt_http_comp.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/flt_http_comp.c        2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/flt_http_comp.c        2026-02-19 
14:03:31.000000000 +0100
@@ -44,9 +44,6 @@
 /* Pools used to allocate comp_state structs */
 DECLARE_STATIC_TYPED_POOL(pool_head_comp_state, "comp_state", struct 
comp_state);
 
-static THREAD_LOCAL struct buffer tmpbuf;
-static THREAD_LOCAL struct buffer zbuf;
-
 static int select_compression_request_header(struct comp_state *st,
                                             struct stream *s,
                                             struct http_msg *msg);
@@ -71,25 +68,6 @@
 }
 
 static int
-comp_flt_init_per_thread(struct proxy *px, struct flt_conf *fconf)
-{
-       if (b_alloc(&tmpbuf, DB_PERMANENT) == NULL)
-               return -1;
-       if (b_alloc(&zbuf, DB_PERMANENT) == NULL)
-               return -1;
-       return 0;
-}
-
-static void
-comp_flt_deinit_per_thread(struct proxy *px, struct flt_conf *fconf)
-{
-       if (tmpbuf.size)
-               b_free(&tmpbuf);
-       if (zbuf.size)
-               b_free(&zbuf);
-}
-
-static int
 comp_strm_init(struct stream *s, struct filter *filter)
 {
        struct comp_state *st;
@@ -789,8 +767,6 @@
 /***********************************************************************/
 struct flt_ops comp_ops = {
        .init              = comp_flt_init,
-       .init_per_thread   = comp_flt_init_per_thread,
-       .deinit_per_thread = comp_flt_deinit_per_thread,
 
        .attach = comp_strm_init,
        .detach = comp_strm_deinit,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/flt_trace.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/flt_trace.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/flt_trace.c    2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/flt_trace.c    2026-02-19 
14:03:31.000000000 +0100
@@ -162,7 +162,7 @@
 
        blk = htxret.blk;
        if (blk && htxret.ret && htx_get_blk_type(blk) == HTX_BLK_DATA) {
-               data += htxret.ret;
+               data += htx_get_blksz(blk) - htxret.ret;
                blk = htx_get_next_blk(htx, blk);
        }
        while (blk) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/h3.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/h3.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/h3.c   2026-02-12 14:25:57.000000000 
+0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/h3.c   2026-02-19 14:03:31.000000000 
+0100
@@ -812,6 +812,11 @@
                        goto out;
                }
        }
+       else {
+               h3s->err = H3_ERR_REQUEST_REJECTED;
+               len = -1;
+               goto out;
+       }
 
        flags |= HTX_SL_F_VER_11;
        flags |= HTX_SL_F_XFER_LEN;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/http_ana.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/http_ana.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/http_ana.c     2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/http_ana.c     2026-02-19 
14:03:31.000000000 +0100
@@ -4312,7 +4312,12 @@
        }
 
        /* we get here if we need to wait for more data */
-       if (!(chn_prod(chn)->flags & (SC_FL_EOS|SC_FL_ABRT_DONE))) {
+
+       if ((s->scf->flags & SC_FL_ERROR) ||
+           ((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
+            proxy_abrt_close_def(s->be, 1)))
+               ret = HTTP_RULE_RES_CONT;
+       else if (!(chn_prod(chn)->flags & 
(SC_FL_ERROR|SC_FL_EOS|SC_FL_ABRT_DONE))) {
                if (!tick_isset(chn->analyse_exp))
                        chn->analyse_exp = tick_add_ifset(now_ms, time);
                ret = HTTP_RULE_RES_YIELD;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/mux_h1.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/mux_h1.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/mux_h1.c       2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/mux_h1.c       2026-02-19 
14:03:31.000000000 +0100
@@ -1331,11 +1331,9 @@
                            H1_EV_H1C_NEW|H1_EV_STRM_NEW, h1c->conn, h1c->h1s);
        }
 
-       if (t) {
-               h1_set_idle_expiration(h1c);
-               t->expire = tick_first(t->expire, h1c->idle_exp);
-               task_queue(t);
-       }
+       h1_set_idle_expiration(h1c);
+       t->expire = tick_first(t->expire, h1c->idle_exp);
+       task_queue(t);
 
        /* prepare to read something */
        if (b_data(&h1c->ibuf))
@@ -4885,6 +4883,12 @@
                h1s->sd->iobuf.flags |= IOBUF_FL_NO_FF;
                goto out;
        }
+
+       if (h1m->state < H1_MSG_CHUNK_SIZE || h1m->state == H1_MSG_TRAILERS || 
h1m->state == H1_MSG_DONE) {
+               TRACE_STATE("Unexpected message state, disable fastfwd", 
H1_EV_STRM_SEND|H1_EV_STRM_ERR, h1c->conn, h1s);
+               h1s->sd->iobuf.flags |= IOBUF_FL_NO_FF;
+               goto out;
+       }
 
        if ((!(h1m->flags & H1_MF_RESP) && (h1s->flags & H1S_F_BODYLESS_REQ)) ||
            ((h1m->flags & H1_MF_RESP) && (h1s->flags & H1S_F_BODYLESS_RESP))) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/mux_h2.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/mux_h2.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/mux_h2.c       2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/mux_h2.c       2026-02-19 
14:03:31.000000000 +0100
@@ -8097,6 +8097,15 @@
 
        TRACE_ENTER(H2_EV_H2S_SEND|H2_EV_STRM_SEND, h2s->h2c->conn, h2s);
 
+       if (h2s->st >= H2_SS_HLOC) {
+               /* Cannot emit any new data if stream already closed. Data
+                * draining will be performed via snd_buf.
+                */
+               TRACE_DEVEL("stream already closed, disable FF", 
H2_EV_H2S_SEND, h2s->h2c->conn, h2s);
+               h2s->sd->iobuf.flags |= IOBUF_FL_NO_FF;
+               goto end;
+       }
+
        /* If we were not just woken because we wanted to send but couldn't,
         * and there's somebody else that is waiting to send, do nothing,
         * we will subscribe later and be put at the end of the list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/mux_quic.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/mux_quic.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/mux_quic.c     2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/mux_quic.c     2026-02-19 
14:03:31.000000000 +0100
@@ -4077,9 +4077,6 @@
 
        TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
 
-       /* Sending forbidden if QCS is locally closed (FIN or RESET_STREAM 
sent). */
-       BUG_ON(qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET));
-
        /* stream layer has been detached so no transfer must occur after. */
        BUG_ON_HOT(qcs->flags & QC_SF_DETACH);
 
@@ -4090,6 +4087,12 @@
                goto end;
        }
 
+       /* Cannot emit data after FIN/RESET_STREAM, drain extra payload. */
+       if (qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET)) {
+               ret = qcs_http_reset_buf(qcs, buf, count);
+               goto end;
+       }
+
        if (LIST_INLIST(&qcs->el_buf)) {
                TRACE_DEVEL("leaving on no buf avail", QMUX_EV_STRM_SEND, 
qcs->qcc->conn, qcs);
                goto end;
@@ -4145,9 +4148,6 @@
 
        TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
 
-       /* Sending forbidden if QCS is locally closed (FIN or RESET_STREAM 
sent). */
-       BUG_ON(qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET));
-
        /* stream layer has been detached so no transfer must occur after. */
        BUG_ON_HOT(qcs->flags & QC_SF_DETACH);
 
@@ -4165,6 +4165,15 @@
                qcs->sd->iobuf.flags |= IOBUF_FL_NO_FF;
                goto end;
        }
+
+       if (qcs_is_close_local(qcs) || (qcs->flags & QC_SF_TO_RESET)) {
+               /* Cannot emit any new data if stream already closed. Data
+                * draining will be performed via snd_buf.
+                */
+               TRACE_DEVEL("stream already closed", QMUX_EV_STRM_SEND, 
qcs->qcc->conn, qcs);
+               qcs->sd->iobuf.flags |= IOBUF_FL_NO_FF;
+               goto end;
+       }
 
        if (LIST_INLIST(&qcs->el_buf)) {
                TRACE_DEVEL("leaving on no buf avail", QMUX_EV_STRM_SEND, 
qcs->qcc->conn, qcs);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/qmux_http.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/qmux_http.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/qmux_http.c    2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/qmux_http.c    2026-02-19 
14:03:31.000000000 +0100
@@ -102,3 +102,23 @@
 
        return ret;
 }
+
+/* QUIC MUX snd_buf reset. HTX data stored in <buf> of length <count> will be
+ * cleared. This can be used when data should not be transmitted any longer.
+ *
+ * Return the size in bytes of cleared data.
+ */
+size_t qcs_http_reset_buf(struct qcs *qcs, struct buffer *buf, size_t count)
+{
+       struct htx *htx;
+
+       TRACE_ENTER(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
+
+       htx = htx_from_buf(buf);
+       htx_reset(htx);
+       htx_to_buf(htx, buf);
+
+       TRACE_LEAVE(QMUX_EV_STRM_SEND, qcs->qcc->conn, qcs);
+
+       return count;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/ssl_crtlist.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/ssl_crtlist.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/ssl_crtlist.c  2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/ssl_crtlist.c  2026-02-19 
14:03:31.000000000 +0100
@@ -515,6 +515,13 @@
        struct stat st;
        int cfgerr = 0;
 
+       if (!crt_path) {
+               memprintf(err, "%sTrying to load a certificate but no 'crt' 
keyword specified.\n",
+                        err && *err ? *err : "");
+               cfgerr |= ERR_ALERT | ERR_FATAL;
+               goto error;
+       }
+
        /* Look for a ckch_store or create one */
        ckchs = ckchs_lookup(crt_path);
        if (ckchs == NULL) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/haproxy-3.3.3+git0.465d8e2fc/src/ssl_sock.c 
new/haproxy-3.3.4+git0.c2bffae0a/src/ssl_sock.c
--- old/haproxy-3.3.3+git0.465d8e2fc/src/ssl_sock.c     2026-02-12 
14:25:57.000000000 +0100
+++ new/haproxy-3.3.4+git0.c2bffae0a/src/ssl_sock.c     2026-02-19 
14:03:31.000000000 +0100
@@ -6006,8 +6006,9 @@
                 * another thread */
 
                HA_RWLOCK_RDLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
-               if (s->ssl_ctx.reused_sess[tid].ptr)
-                       ha_free(&s->ssl_ctx.reused_sess[tid].ptr);
+               HA_RWLOCK_WRLOCK(SSL_SERVER_LOCK, 
&s->ssl_ctx.reused_sess[tid].sess_lock);
+               ha_free(&s->ssl_ctx.reused_sess[tid].ptr);
+               HA_RWLOCK_WRUNLOCK(SSL_SERVER_LOCK, 
&s->ssl_ctx.reused_sess[tid].sess_lock);
                HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
        }
 

Reply via email to