diff --git a/pkg/noun/retrieve.c b/pkg/noun/retrieve.c index 9bf554cb99..83a183dd12 100644 --- a/pkg/noun/retrieve.c +++ b/pkg/noun/retrieve.c @@ -1949,11 +1949,11 @@ c3_w* u3r_word_buffer(u3_atom* a, c3_w* len_w) { if ( _(u3a_is_cat(*a)) ) { - *len_w = 1; + if ( len_w ) *len_w = 1; return a; } u3a_atom* pug_u = u3a_to_ptr(*a); - *len_w = pug_u->len_w; + if ( len_w ) *len_w = pug_u->len_w; return pug_u->buf_w; } diff --git a/pkg/vere/io/cttp.c b/pkg/vere/io/cttp.c index af0e88e9ee..27c40b0d1b 100644 --- a/pkg/vere/io/cttp.c +++ b/pkg/vere/io/cttp.c @@ -78,6 +78,7 @@ static void _cttp_bods_free(u3_hbod* bod_u) { while ( bod_u ) { + u3z(bod_u->atom); u3_hbod* nex_u = bod_u->nex_u; c3_free(bod_u); @@ -91,6 +92,8 @@ static u3_hbod* _cttp_bod_new(c3_w len_w, c3_c* hun_c) { u3_hbod* bod_u = c3_malloc(1 + len_w + sizeof(*bod_u)); + bod_u->atom = u3_nul; + bod_u->hun_y = (c3_y*)(bod_u + 1); bod_u->hun_y[len_w] = 0; bod_u->len_w = len_w; memcpy(bod_u->hun_y, (const c3_y*)hun_c, len_w); @@ -106,6 +109,8 @@ _cttp_bod_from_hed(u3_hhed* hed_u) { c3_w len_w = hed_u->nam_w + 2 + hed_u->val_w + 2; u3_hbod* bod_u = c3_malloc(1 + len_w + sizeof(*bod_u)); + bod_u->atom = u3_nul; + bod_u->hun_y = (c3_y*)(bod_u + 1); bod_u->hun_y[len_w] = 0; memcpy(bod_u->hun_y, hed_u->nam_c, hed_u->nam_w); @@ -137,6 +142,9 @@ _cttp_bods_to_octs(u3_hbod* bod_u) bid_u = bid_u->nex_u; } } + if ( c3n == u3a_is_cat(len_w) ) { + u3m_bail(c3__fail); + } buf_y = c3_malloc(1 + len_w); buf_y[len_w] = 0; @@ -166,17 +174,28 @@ _cttp_bod_from_octs(u3_noun oct) } len_w = u3h(oct); - { - u3_hbod* bod_u = c3_malloc(1 + len_w + sizeof(*bod_u)); + if ( !_(u3ud(u3t(oct))) ) { + u3m_bail(c3__fail); + } + + c3_w len_buf_w = u3r_met(3, u3t(oct)); + u3_hbod* bod_u; + if ( len_buf_w <= len_w ) { + bod_u = c3_malloc(1 + len_w + sizeof(*bod_u)); + bod_u->atom = u3_nul; + bod_u->hun_y = (c3_y*)(bod_u + 1); bod_u->hun_y[len_w] = 0; - bod_u->len_w = len_w; u3r_bytes(0, len_w, bod_u->hun_y, u3t(oct)); - - bod_u->nex_u = 0; - - u3z(oct); - return bod_u; } + else { + bod_u = c3_malloc(sizeof(*bod_u)); + bod_u->atom = u3k(u3t(oct)); + bod_u->hun_y = (c3_y*)u3r_word_buffer(&bod_u->atom, NULL); + } + bod_u->len_w = len_w; + bod_u->nex_u = 0; + u3z(oct); + return bod_u; } /* _cttp_bods_to_vec(): translate body buffers to array of h2o_iovec_t diff --git a/pkg/vere/io/http.c b/pkg/vere/io/http.c index 2abfb9a3a8..b7ae670a4b 100644 --- a/pkg/vere/io/http.c +++ b/pkg/vere/io/http.c @@ -187,6 +187,7 @@ static void _cttp_bods_free(u3_hbod* bod_u) { while ( bod_u ) { + u3z(bod_u->atom); u3_hbod* nex_u = bod_u->nex_u; c3_free(bod_u); @@ -206,17 +207,28 @@ _cttp_bod_from_octs(u3_noun oct) } len_w = u3h(oct); - { - u3_hbod* bod_u = c3_malloc(1 + len_w + sizeof(*bod_u)); + if ( !_(u3ud(u3t(oct))) ) { + u3m_bail(c3__fail); + } + + c3_w len_buf_w = u3r_met(3, u3t(oct)); + u3_hbod* bod_u; + if ( len_buf_w <= len_w ) { + bod_u = c3_malloc(1 + len_w + sizeof(*bod_u)); + bod_u->atom = u3_nul; + bod_u->hun_y = (c3_y*)(bod_u + 1); bod_u->hun_y[len_w] = 0; - bod_u->len_w = len_w; u3r_bytes(0, len_w, bod_u->hun_y, u3t(oct)); - - bod_u->nex_u = 0; - - u3z(oct); - return bod_u; } + else { + bod_u = c3_malloc(sizeof(*bod_u)); + bod_u->atom = u3k(u3t(oct)); + bod_u->hun_y = (c3_y*)u3r_word_buffer(&bod_u->atom, NULL); + } + bod_u->len_w = len_w; + bod_u->nex_u = 0; + u3z(oct); + return bod_u; } /* _cttp_bods_to_vec(): translate body buffers to array of h2o_iovec_t diff --git a/pkg/vere/vere.h b/pkg/vere/vere.h index 4bd901efea..3ff8fe0194 100644 --- a/pkg/vere/vere.h +++ b/pkg/vere/vere.h @@ -39,8 +39,9 @@ */ typedef struct _u3_hbod { struct _u3_hbod* nex_u; + u3_atom atom; // set if hun_y is owned by that atom, else 0 c3_w len_w; - c3_y hun_y[0]; + c3_y* hun_y; } u3_hbod; /* u3_lane: ames lane (IP address and port)