Willy,

I know you dislike adjusting code to please static analyzers, but I'd argue
that using the new IST_NULL + isttest() combination is easier to understand 
for humans as well. A simple .ptr == NULL check might also be slightly faster
compared to isteq() with an empty string?

I have verified that reg-tests pass, but as this is deep within the internals
please check this carefully.

Best regards
Tim Düsterhus

Apply with `git am --scissors` to automatically cut the commit message.

-- >8 --
Clang Static Analyzer (scan-build) was having a hard time to understand that
`hpack_encode_header` would never be called with a garbage value for `v`.

It failed to detect that `if (isteq(n, ist(""))) break;` would exist the
loop in all cases. By setting `n` to `IST_NULL` and checking with
`isttest()` it no longer complains.

The check must be moved to the beginning of the loop to prevent a NULL
pointer derefence for the pseudo header skip.
---
 src/mux_h2.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/mux_h2.c b/src/mux_h2.c
index 013ef86f8..b353c4d7c 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -4617,7 +4617,7 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, 
struct htx *htx)
        }
 
        /* marker for end of headers */
-       list[hdr].n = ist("");
+       list[hdr].n = IST_NULL;
 
        if (h2s->status == 204 || h2s->status == 304) {
                /* no contents, claim c-len is present and set to zero */
@@ -4660,6 +4660,9 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, 
struct htx *htx)
 
        /* encode all headers, stop at empty name */
        for (hdr = 0; hdr < sizeof(list)/sizeof(list[0]); hdr++) {
+               if (!isttest(list[hdr].n))
+                       break; // end
+
                /* these ones do not exist in H2 and must be dropped. */
                if (isteq(list[hdr].n, ist("connection")) ||
                    isteq(list[hdr].n, ist("proxy-connection")) ||
@@ -4672,9 +4675,6 @@ static size_t h2s_frt_make_resp_headers(struct h2s *h2s, 
struct htx *htx)
                if (*(list[hdr].n.ptr) == ':')
                        continue;
 
-               if (isteq(list[hdr].n, ist("")))
-                       break; // end
-
                if (!hpack_encode_header(&outbuf, list[hdr].n, list[hdr].v)) {
                        /* output full */
                        if (b_space_wraps(mbuf))
@@ -4870,7 +4870,7 @@ static size_t h2s_bck_make_req_headers(struct h2s *h2s, 
struct htx *htx)
        }
 
        /* marker for end of headers */
-       list[hdr].n = ist("");
+       list[hdr].n = IST_NULL;
 
        mbuf = br_tail(h2c->mbuf);
  retry:
@@ -5007,6 +5007,9 @@ static size_t h2s_bck_make_req_headers(struct h2s *h2s, 
struct htx *htx)
                struct ist n = list[hdr].n;
                struct ist v = list[hdr].v;
 
+               if (!isttest(n))
+                       break; // end
+
                /* these ones do not exist in H2 and must be dropped. */
                if (isteq(n, ist("connection")) ||
                    (auth.len && isteq(n, ist("host"))) ||
@@ -5030,9 +5033,6 @@ static size_t h2s_bck_make_req_headers(struct h2s *h2s, 
struct htx *htx)
                if (*(n.ptr) == ':')
                        continue;
 
-               if (isteq(n, ist("")))
-                       break; // end
-
                if (!hpack_encode_header(&outbuf, n, v)) {
                        /* output full */
                        if (b_space_wraps(mbuf))
-- 
2.25.2


Reply via email to