]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2613 in SNORT/snort3 from ~KATHARVE/snort3:h2i_headers_close...
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Thu, 19 Nov 2020 14:18:01 +0000 (14:18 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Thu, 19 Nov 2020 14:18:01 +0000 (14:18 +0000)
Squashed commit of the following:

commit 85d3938fcd179b22ee2bceac441be1b1d9049738
Author: Katura Harvey <katharve@cisco.com>
Date:   Thu Oct 29 12:39:05 2020 -0400

    http2_inspect: handle connection close during headers frames

25 files changed:
src/service_inspectors/http2_inspect/http2_enum.h
src/service_inspectors/http2_inspect/http2_flow_data.h
src/service_inspectors/http2_inspect/http2_headers_frame.cc
src/service_inspectors/http2_inspect/http2_headers_frame_header.cc
src/service_inspectors/http2_inspect/http2_headers_frame_trailer.cc
src/service_inspectors/http2_inspect/http2_headers_frame_with_startline.cc
src/service_inspectors/http2_inspect/http2_headers_frame_with_startline.h
src/service_inspectors/http2_inspect/http2_hpack.cc
src/service_inspectors/http2_inspect/http2_hpack.h
src/service_inspectors/http2_inspect/http2_hpack_int_decode.cc
src/service_inspectors/http2_inspect/http2_hpack_int_decode.h
src/service_inspectors/http2_inspect/http2_hpack_string_decode.cc
src/service_inspectors/http2_inspect/http2_hpack_string_decode.h
src/service_inspectors/http2_inspect/http2_inspect.cc
src/service_inspectors/http2_inspect/http2_push_promise_frame.cc
src/service_inspectors/http2_inspect/http2_request_line.cc
src/service_inspectors/http2_inspect/http2_request_line.h
src/service_inspectors/http2_inspect/http2_start_line.h
src/service_inspectors/http2_inspect/http2_status_line.cc
src/service_inspectors/http2_inspect/http2_status_line.h
src/service_inspectors/http2_inspect/http2_stream_splitter.cc
src/service_inspectors/http2_inspect/http2_tables.cc
src/service_inspectors/http2_inspect/test/http2_hpack_int_decode_test.cc
src/service_inspectors/http2_inspect/test/http2_hpack_string_decode_test.cc
src/service_inspectors/http_inspect/http_stream_splitter_finish.cc

index 3ece39745d815ced43e5ad5ace8919df679c0c81..938a56c9b0e829f839b40d2a726ed29ddade7d86 100644 (file)
@@ -53,21 +53,21 @@ enum PEG_COUNT { PEG_FLOW = 0, PEG_CONCURRENT_SESSIONS, PEG_MAX_CONCURRENT_SESSI
 enum EventSid
 {
     EVENT__NONE = -1,
-    EVENT_INT_DECODE_FAILURE = 1,
+    EVENT_INVALID_FLAG = 1,
     EVENT_INT_LEADING_ZEROS = 2,
-    EVENT_STRING_DECODE_FAILURE = 3,
+    EVENT_INVALID_STREAM_ID = 3,
     EVENT_MISSING_CONTINUATION = 4,
     EVENT_UNEXPECTED_CONTINUATION = 5,
     EVENT_MISFORMATTED_HTTP2 = 6,
     EVENT_PREFACE_MATCH_FAILURE = 7,
     EVENT_REQUEST_WITHOUT_REQUIRED_FIELD = 8,
     EVENT_RESPONSE_WITHOUT_STATUS = 9,
-    EVENT_INVALID_HEADER = 10,
+    EVENT_CONNECT_WITH_SCHEME_OR_PATH = 10,
     EVENT_SETTINGS_FRAME_ERROR = 11,
     EVENT_SETTINGS_FRAME_UNKN_PARAM = 12,
     EVENT_FRAME_SEQUENCE = 13,
     EVENT_DYNAMIC_TABLE_OVERFLOW = 14,
-    EVENT_INVALID_STARTLINE = 15,
+    EVENT_INVALID_PROMISED_STREAM = 15,
     EVENT_PADDING_LEN = 16,
     EVENT_PSEUDO_HEADER_AFTER_REGULAR_HEADER = 17,
     EVENT_PSEUDO_HEADER_IN_TRAILERS = 18,
@@ -80,9 +80,6 @@ enum EventSid
     EVENT_BAD_PUSH_SEQUENCE = 25,
     EVENT_BAD_SETTINGS_VALUE = 26,
     EVENT_PUSH_WHEN_PROHIBITED = 27,
-    EVENT_INVALID_PROMISED_STREAM = 28,
-    EVENT_INVALID_STREAM_ID = 29,
-    EVENT_INVALID_FLAG = 30,
     EVENT__MAX_VALUE
 };
 
@@ -105,7 +102,7 @@ enum Infraction
     INF_C2S_PUSH = 12,
     INF_INVALID_PSEUDO_HEADER = 13,
     INF_PSEUDO_HEADER_AFTER_REGULAR_HEADER = 14,
-    INF_PSEUDO_HEADER_URI_FORM_MISMATCH = 15,
+    INF_REQUEST_WITHOUT_REQUIRED_FIELD = 15,
     INF_RESPONSE_WITHOUT_STATUS = 16,
     INF_HPACK_INDEX_OUT_OF_BOUNDS = 17,
     INF_INVALID_SETTINGS_FRAME = 18,
@@ -129,6 +126,10 @@ enum Infraction
     INF_INVALID_PROMISED_STREAM = 36,
     INF_INVALID_STREAM_ID = 37,
     INF_INVALID_FLAG = 38,
+    INF_TRUNCATED_HEADER_LINE = 39,
+    INF_REQUEST_WITHOUT_METHOD = 40,
+    INF_CONNECT_WITHOUT_AUTHORITY = 41,
+    INF_CONNECT_WITH_SCHEME_OR_PATH = 42,
     INF__MAX_VALUE
 };
 
index 72b11bcb9f77e3e22227400f6f0596b2e1f2e008..da25a60d4999af15e70c3af0d3cd3734e9c6f14e 100644 (file)
@@ -99,6 +99,7 @@ public:
     class Http2Stream* get_processing_stream();
     uint32_t get_processing_stream_id() const;
     void set_processing_stream_id(const HttpCommon::SourceId source_id);
+    bool is_processing_partial_header() const { return processing_partial_header; }
 
     Http2HpackDecoder* get_hpack_decoder(const HttpCommon::SourceId source_id)
     { return &hpack_decoder[source_id]; }
@@ -172,6 +173,7 @@ protected:
     uint8_t frame_type[2] = { Http2Enums::FT__NONE, Http2Enums::FT__NONE };
     bool abort_flow[2] = { false, false };
     std::queue<uint32_t> frame_lengths[2];
+    bool processing_partial_header = false;
 
     // Internal to reassemble()
     uint32_t frame_header_offset[2] = { 0, 0 };
index 69f32b586c53d8ce93c9da6b6a3e8f27da1446a3..70d0b1f75f18f4c30c42dad9d20cbe983285895a 100644 (file)
@@ -84,7 +84,14 @@ void Http2HeadersFrame::process_decoded_headers(HttpFlowData* http_flow, SourceI
     http1_header = hpack_decoder->get_decoded_headers(decoded_headers);
     StreamBuffer stream_buf;
 
+
     // http_inspect scan() of headers
+    // If we're processing a header truncated immediately after the start line, http1_header will
+    // be empty. Don't call scan on the empty buffer because it will create a cutter and the check
+    // for this condition in HI::finish() will fail. Truncated headers with non-empty http1_header
+    // buffers are still sent to HI::scan().
+    assert ((http1_header.length() > 0) or session_data->is_processing_partial_header());
+    if (http1_header.length() > 0)
     {
         uint32_t flush_offset;
         Http2DummyPacket dummy_pkt;
@@ -93,11 +100,19 @@ void Http2HeadersFrame::process_decoded_headers(HttpFlowData* http_flow, SourceI
         const StreamSplitter::Status header_scan_result =
             session_data->hi_ss[hi_source_id]->scan(&dummy_pkt, http1_header.start(),
             http1_header.length(), unused, &flush_offset);
-        assert(header_scan_result == StreamSplitter::FLUSH);
+        assert((session_data->is_processing_partial_header() and
+                (header_scan_result == StreamSplitter::SEARCH)) or
+            ((!session_data->is_processing_partial_header() and
+                (header_scan_result == StreamSplitter::FLUSH))));
+        assert(session_data->is_processing_partial_header() ^
+            ((int64_t)flush_offset == http1_header.length()));
         UNUSED(header_scan_result);
-        assert((int64_t)flush_offset == http1_header.length());
     }
 
+    // If this is a truncated headers frame, call http_inspect finish()
+    if (session_data->is_processing_partial_header())
+        session_data->hi_ss[hi_source_id]->finish(session_data->flow);
+
     // http_inspect reassemble() of headers
     {
         unsigned copied;
@@ -117,15 +132,10 @@ void Http2HeadersFrame::process_decoded_headers(HttpFlowData* http_flow, SourceI
         dummy_pkt.data = stream_buf.data;
         dummy_pkt.xtradata_mask = 0;
         session_data->hi->eval(&dummy_pkt);
-        // Following if condition won't get exercised until finish() (during Headers) is
-        // implemented for H2I. Without finish() H2I will only flush complete header blocks. Below
-        // ABORT is only possible if tcp connection closes unexpectedly in middle of a header.
         if (http_flow->get_type_expected(hi_source_id) == HttpEnums::SEC_ABORT)
         {
-            *session_data->infractions[source_id] += INF_INVALID_HEADER;
-            session_data->events[source_id]->create_event(EVENT_INVALID_HEADER);
-            stream->set_state(source_id, STREAM_ERROR);
-            return;
+            assert(session_data->is_processing_partial_header());
+            stream->set_state(hi_source_id, STREAM_ERROR);
         }
         detection_required = dummy_pkt.is_detection_required();
         xtradata_mask = dummy_pkt.xtradata_mask;
index f28db8f3c1579093b73c31ea9bc0b034d76dd064..af059d42337ea2b9ad0f23403f7bd4b72a21e19f 100644 (file)
@@ -57,17 +57,18 @@ Http2HeadersFrameHeader::Http2HeadersFrameHeader(const uint8_t* header_buffer,
     if (!hpack_decoder->decode_headers((data.start() + hpack_headers_offset), data.length() -
         hpack_headers_offset, decoded_headers, start_line_generator, false))
     {
-        session_data->abort_flow[source_id] = true;
-        session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
-        return;
+        if (!(*session_data->infractions[source_id] & INF_TRUNCATED_HEADER_LINE))
+        {
+            session_data->abort_flow[source_id] = true;
+            session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
+            return;
+        }
     }
 
     // process start line
-    if (!start_line_generator->generate_start_line(start_line))
+    if (!start_line_generator->generate_start_line(start_line, are_pseudo_headers_complete()))
     {
-        // FIXIT-E should only be a stream error
-        session_data->abort_flow[source_id] = true;
-        session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
+        stream->set_state(source_id, STREAM_ERROR);
     }
 }
 
index b737964005b30ba851ed7d0a3747c73f643a43da..df4315b7bf4fe011c3066b0120e72105fc9bed23 100644 (file)
@@ -59,8 +59,11 @@ Http2HeadersFrameTrailer::Http2HeadersFrameTrailer(const uint8_t* header_buffer,
     if (!hpack_decoder->decode_headers((data.start() + hpack_headers_offset), data.length() -
         hpack_headers_offset, decoded_headers, nullptr, true))
     {
-        session_data->abort_flow[source_id] = true;
-        session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
+        if (!(*session_data->infractions[source_id] & INF_TRUNCATED_HEADER_LINE))
+        {
+            session_data->abort_flow[source_id] = true;
+            session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
+        }
     }
 }
 
@@ -86,9 +89,8 @@ void Http2HeadersFrameTrailer::analyze_http1()
 
     if (http_flow->get_type_expected(source_id) != HttpEnums::SEC_TRAILER)
     {
-        // If there was no unflushed data on this stream when the trailers arrived, http_inspect
-        // will not yet be expecting trailers. Flush empty buffer through scan, reassemble, and
-        // eval to prepare http_inspect for trailers.
+        // http_inspect is not yet expecting trailers. Flush empty buffer through scan, reassemble,
+        // and eval to prepare http_inspect for trailers.
         assert(http_flow->get_type_expected(source_id) == HttpEnums::SEC_BODY_H2);
         stream->finish_msg_body(source_id, true, true); // calls http_inspect scan()
 
index 646fcbbe902414ed75eeec988f31702b82a0c7ec..5ce237eb4ade7bea31143b242af5a727fd5dce80 100644 (file)
@@ -92,8 +92,6 @@ bool Http2HeadersFrameWithStartline::process_start_line(HttpFlowData*& http_flow
         session_data->hi->eval(&dummy_pkt);
         if (http_flow->get_type_expected(hi_source_id) != HttpEnums::SEC_HEADER)
         {
-            *session_data->infractions[source_id] += INF_INVALID_STARTLINE;
-            session_data->events[source_id]->create_event(EVENT_INVALID_STARTLINE);
             stream->set_state(hi_source_id, STREAM_ERROR);
             return false;
         }
@@ -102,6 +100,14 @@ bool Http2HeadersFrameWithStartline::process_start_line(HttpFlowData*& http_flow
     return true;
 }
 
+// If we are not processing a truncated headers frame or we have seen a non-pseudoheader, we know
+// we've seen all the (valid) pseudoheaders in the frame. Otherwise we could be missing some due
+// to truncation
+bool Http2HeadersFrameWithStartline::are_pseudo_headers_complete()
+{
+    return !session_data->is_processing_partial_header() or
+        !hpack_decoder->are_pseudo_headers_allowed();
+}
 
 #ifdef REG_TEST
 void Http2HeadersFrameWithStartline::print_frame(FILE* output)
index f759496b7d1a4a527deda590edf372375fc62e97..845a208987dfe790bc6aad63d3770b36582b8106 100644 (file)
@@ -47,6 +47,7 @@ protected:
         Http2HeadersFrame(header_buffer, header_len, data_buffer, data_len, ssn_data, src_id,
             stream_) { }
     bool process_start_line(HttpFlowData*& http_flow, HttpCommon::SourceId hi_source_id);
+    bool are_pseudo_headers_complete();
 
     Http2StartLine* start_line_generator = nullptr;
     Field start_line;
index 1b2841c607f47d7d2429ca9266ba524048ec1075..5f15828a94ae7455c2eca864e36396a85d5d030b 100644 (file)
@@ -27,6 +27,7 @@
 #include "service_inspectors/http_inspect/http_test_manager.h"
 
 #include "http2_enum.h"
+#include "http2_flow_data.h"
 #include "http2_start_line.h"
 
 using namespace HttpCommon;
@@ -66,7 +67,8 @@ bool Http2HpackDecoder::decode_string_literal(const uint8_t* encoded_header_buff
     bytes_consumed = 0;
 
     if (!decode_string.translate(encoded_header_buffer, encoded_header_length, bytes_consumed,
-        decoded_header_buffer, decoded_header_length, bytes_written, events, infractions))
+        decoded_header_buffer, decoded_header_length, bytes_written, events, infractions,
+        session_data->is_processing_partial_header()))
     {
         return false;
     }
@@ -84,7 +86,7 @@ const HpackTableEntry* Http2HpackDecoder::get_hpack_table_entry(
     bytes_consumed = 0;
 
     if (!decode_int.translate(encoded_header_buffer, encoded_header_length, bytes_consumed,
-        index, events, infractions))
+        index, events, infractions, session_data->is_processing_partial_header()))
     {
         return nullptr;
     }
@@ -235,7 +237,8 @@ bool Http2HpackDecoder::handle_dynamic_size_update(const uint8_t* encoded_header
     bytes_consumed = 0;
 
     if (!decode_int5.translate(encoded_header_buffer, encoded_header_length,
-        encoded_bytes_consumed, decoded_int, events, infractions))
+        encoded_bytes_consumed, decoded_int, events, infractions,
+        session_data->is_processing_partial_header()))
     {
         return false;
     }
@@ -365,8 +368,10 @@ bool Http2HpackDecoder::decode_headers(const uint8_t* encoded_headers,
         decoded_headers_size += line_bytes_written;
     }
 
-    // Write the last CRLF to end the header
-    if (success)
+    // Write the last CRLF to end the header. A truncated header may not have encountered an error
+    // if the truncation is between header lines, but still shouldn't complete the header block
+    // with the final CRLF.
+    if (success and !session_data->is_processing_partial_header())
     {
         success = write_decoded_headers((const uint8_t*)"\r\n", 2, decoded_headers +
             decoded_headers_size, MAX_OCTETS - decoded_headers_size, line_bytes_written);
index e7f2a5f6ffc6d535a7cfead78cb2bedd70a1a646..aa95855a8dd49b50e83d3dc80a9d24bc28c66371 100644 (file)
@@ -21,6 +21,8 @@
 #define HTTP2_HPACK_H
 
 #include "service_inspectors/http_inspect/http_common.h"
+#include "utils/event_gen.h"
+#include "utils/infractions.h"
 
 #include "http2_hpack_int_decode.h"
 #include "http2_hpack_string_decode.h"
@@ -30,6 +32,10 @@ class Field;
 class Http2FlowData;
 class Http2StartLine;
 
+using Http2Infractions = Infractions<Http2Enums::INF__MAX_VALUE, Http2Enums::INF__NONE>;
+using Http2EventGen = EventGen<Http2Enums::EVENT__MAX_VALUE, Http2Enums::EVENT__NONE,
+    Http2Enums::HTTP2_GID>;
+
 // This class implements HPACK decompression. One instance is required in each direction for each
 // HTTP/2 flow
 class Http2HpackDecoder
@@ -37,7 +43,8 @@ class Http2HpackDecoder
 public:
     Http2HpackDecoder(Http2FlowData* flow_data, HttpCommon::SourceId src_id,
         Http2EventGen* const _events, Http2Infractions* const _infractions) :
-        events(_events), infractions(_infractions), decode_table(flow_data, src_id) { }
+        session_data(flow_data), events(_events), infractions(_infractions),
+        decode_table(flow_data, src_id) { }
     bool decode_headers(const uint8_t* encoded_headers, const uint32_t encoded_headers_length,
         uint8_t* decoded_headers, Http2StartLine* start_line, bool trailers);
     bool write_decoded_headers(const uint8_t* in_buffer, const uint32_t in_length,
@@ -76,11 +83,13 @@ public:
     const Field* get_start_line();
     Field get_decoded_headers(const uint8_t* const decoded_headers);
     HpackIndexTable* get_decode_table() { return &decode_table; }
+    bool are_pseudo_headers_allowed() { return pseudo_headers_allowed; }
 
 private:
     Http2StartLine* start_line;
     bool pseudo_headers_allowed;
     uint32_t decoded_headers_size;
+    Http2FlowData* session_data;
     Http2EventGen* const events;
     Http2Infractions* const infractions;
 
index 289698cc01f6583db30179f7dc34c33bdd9f9cae..8ac3f52ba930c074c720051a53255e85961e3250 100644 (file)
@@ -37,15 +37,17 @@ Http2HpackIntDecode::Http2HpackIntDecode(uint8_t prefix) : prefix_mask(((uint16_
 
 bool Http2HpackIntDecode::translate(const uint8_t* in_buff, const uint32_t in_len,
     uint32_t& bytes_consumed, uint64_t& result, Http2EventGen* const events,
-    Http2Infractions* const infractions) const
+    Http2Infractions* const infractions, bool partial_header) const
 {
     bytes_consumed = 0;
     result = 0;
 
     if (in_len == 0)
     {
-        *infractions += INF_INT_EMPTY_BUFF;
-        events->create_event(EVENT_INT_DECODE_FAILURE);
+        if (!partial_header)
+            *infractions += INF_INT_EMPTY_BUFF;
+        else
+            *infractions += INF_TRUNCATED_HEADER_LINE;
         return false;
     }
 
@@ -62,8 +64,10 @@ bool Http2HpackIntDecode::translate(const uint8_t* in_buff, const uint32_t in_le
     {
         if (bytes_consumed >= in_len)
         {
-            *infractions += INF_INT_MISSING_BYTES;
-            events->create_event(EVENT_INT_DECODE_FAILURE);
+            if (!partial_header)
+                *infractions += INF_INT_MISSING_BYTES;
+            else
+                *infractions += INF_TRUNCATED_HEADER_LINE;
             return false;
         }
         byte = in_buff[bytes_consumed++];
@@ -75,7 +79,6 @@ bool Http2HpackIntDecode::translate(const uint8_t* in_buff, const uint32_t in_le
                 ((result + ((uint64_t)(byte & VAL_MASK) << multiplier) + prefix_mask) < result))
             {
                 *infractions += INF_INT_OVERFLOW;
-                events->create_event(EVENT_INT_DECODE_FAILURE);
                 return false;
             }
         }
index f4ae9732aa2563bf6079ecb6fe3e3699ba056f07..0966ff5535edd046641b6afd9f0406c0a360f486 100644 (file)
@@ -35,7 +35,8 @@ class Http2HpackIntDecode
 public:
     Http2HpackIntDecode(uint8_t prefix);
     bool translate(const uint8_t* in_buff, const uint32_t in_len, uint32_t& bytes_consumed,
-        uint64_t& result, Http2EventGen* const events, Http2Infractions* const infractions) const;
+        uint64_t& result, Http2EventGen* const events, Http2Infractions* const infractions,
+        bool partial_header) const;
 
 private:
     const uint8_t prefix_mask;
index 7dabf14282d31303231beb580442a44c1cc55851..e9c7e33d5b79dae36d7fc6fb97ad4c352917e442 100644 (file)
@@ -38,15 +38,17 @@ static const uint8_t min_decode_len[HUFFMAN_LOOKUP_MAX + 1] =
 
 bool Http2HpackStringDecode::translate(const uint8_t* in_buff, const uint32_t in_len,
     uint32_t& bytes_consumed, uint8_t* out_buff, const uint32_t out_len, uint32_t& bytes_written,
-    Http2EventGen* const events, Http2Infractions* const infractions) const
+    Http2EventGen* const events, Http2Infractions* const infractions, bool partial_header) const
 {
     bytes_consumed = 0;
     bytes_written = 0;
 
     if (in_len == 0)
     {
-        *infractions += INF_STRING_EMPTY_BUFF;
-        events->create_event(EVENT_STRING_DECODE_FAILURE);
+        if (!partial_header)
+            *infractions += INF_STRING_EMPTY_BUFF;
+        else
+            *infractions += INF_TRUNCATED_HEADER_LINE;
         return false;
     }
 
@@ -54,13 +56,16 @@ bool Http2HpackStringDecode::translate(const uint8_t* in_buff, const uint32_t in
 
     // Get length
     uint64_t encoded_len;
-    if (!decode7.translate(in_buff, in_len, bytes_consumed, encoded_len, events, infractions))
+    if (!decode7.translate(in_buff, in_len, bytes_consumed, encoded_len, events, infractions,
+            partial_header))
         return false;
 
     if (encoded_len > (uint64_t)(in_len - bytes_consumed))
     {
-        *infractions += INF_STRING_MISSING_BYTES;
-        events->create_event(EVENT_STRING_DECODE_FAILURE);
+        if (!partial_header)
+            *infractions += INF_STRING_MISSING_BYTES;
+        else
+            *infractions += INF_TRUNCATED_HEADER_LINE;
         return false;
     }
 
@@ -69,20 +74,19 @@ bool Http2HpackStringDecode::translate(const uint8_t* in_buff, const uint32_t in
 
     if (!isHuffman)
         return get_string(in_buff, encoded_len, bytes_consumed, out_buff, out_len, bytes_written,
-                events, infractions);
+            infractions);
 
     return get_huffman_string(in_buff, encoded_len, bytes_consumed, out_buff, out_len,
-        bytes_written, events, infractions);
+        bytes_written, infractions);
 }
 
 bool Http2HpackStringDecode::get_string(const uint8_t* in_buff, const uint32_t encoded_len,
     uint32_t& bytes_consumed, uint8_t* out_buff, const uint32_t out_len, uint32_t& bytes_written,
-    Http2EventGen* const events, Http2Infractions* const infractions) const
+    Http2Infractions* const infractions) const
 {
     if (encoded_len > out_len)
     {
         *infractions += INF_DECODED_HEADER_BUFF_OUT_OF_SPACE;
-        events->create_event(EVENT_MISFORMATTED_HTTP2);
         return false;
     }
 
@@ -141,7 +145,7 @@ bool Http2HpackStringDecode::get_next_byte(const uint8_t* in_buff, const uint32_
 
 bool Http2HpackStringDecode::get_huffman_string(const uint8_t* in_buff, const uint32_t encoded_len,
     uint32_t& bytes_consumed, uint8_t* out_buff, const uint32_t out_len, uint32_t& bytes_written,
-    Http2EventGen* const events, Http2Infractions* const infractions) const
+    Http2Infractions* const infractions) const
 {
     const uint32_t last_encoded_byte = bytes_consumed + encoded_len;
     uint8_t byte;
@@ -155,7 +159,6 @@ bool Http2HpackStringDecode::get_huffman_string(const uint8_t* in_buff, const ui
     if (max_length > out_len)
     {
         *infractions += INF_DECODED_HEADER_BUFF_OUT_OF_SPACE;
-        events->create_event(EVENT_STRING_DECODE_FAILURE);
         return false;
     }
 
@@ -190,9 +193,7 @@ bool Http2HpackStringDecode::get_huffman_string(const uint8_t* in_buff, const ui
 
         case HUFFMAN_FAILURE:
             *infractions += INF_HUFFMAN_DECODED_EOS;
-            events->create_event(EVENT_STRING_DECODE_FAILURE);
             return false;
-            break;
 
         default:
             break;
@@ -229,14 +230,12 @@ bool Http2HpackStringDecode::get_huffman_string(const uint8_t* in_buff, const ui
         if (byte != 0xff)
         {
             *infractions += INF_HUFFMAN_BAD_PADDING;
-            events->create_event(EVENT_STRING_DECODE_FAILURE);
             return false;
         }
     }
     else if (result.state != HUFFMAN_MATCH)
     {
         *infractions += INF_HUFFMAN_INCOMPLETE_CODE_PADDING;
-        events->create_event(EVENT_STRING_DECODE_FAILURE);
         return false;
     }
 
index 7869ec377175bcc8685ff06efab90d8296b62cd4..7e5a2934aa310dc469e4b0e9cc87d86362aacc05 100644 (file)
@@ -33,15 +33,16 @@ public:
     Http2HpackStringDecode() : decode7(7) { }
     bool translate(const uint8_t* in_buff, const uint32_t in_len, uint32_t& bytes_consumed,
         uint8_t* out_buff, const uint32_t out_len, uint32_t& bytes_written,
-        Http2EventGen* const events, Http2Infractions* const infractions) const;
+        Http2EventGen* const events, Http2Infractions* const infractions,
+        bool partial_header) const;
 
 private:
     bool get_string(const uint8_t* in_buff, const uint32_t encoded_len, uint32_t& bytes_consumed,
-        uint8_t* out_buff, const uint32_t out_len, uint32_t& bytes_written, Http2EventGen* const
-        events, Http2Infractions* const infractions) const;
+        uint8_t* out_buff, const uint32_t out_len, uint32_t& bytes_written,
+        Http2Infractions* const infractions) const;
     bool get_huffman_string(const uint8_t* in_buff, const uint32_t encoded_len,
         uint32_t& bytes_consumed, uint8_t* out_buff, const uint32_t out_len, uint32_t&
-        bytes_written, Http2EventGen* const events, Http2Infractions* const infractions) const;
+        bytes_written, Http2Infractions* const infractions) const;
     bool get_next_byte(const uint8_t* in_buff, const uint32_t last_byte,
         uint32_t& bytes_consumed, uint8_t& cur_bit, uint8_t match_len, uint8_t& byte,
         bool& another_search) const;
index 8d4bbd7a261c569a4c237a6ab21302ccd24a915e..b812a80bb5e6fc3ebe0fad61f312199f5dbfdb91 100644 (file)
@@ -184,6 +184,7 @@ void Http2Inspect::clear(Packet* p)
     stream->clear_frame();
     session_data->stream_in_hi = NO_STREAM_ID;
     session_data->processing_stream_id = NO_STREAM_ID;
+    session_data->processing_partial_header = false;
 }
 
 #ifdef REG_TEST
index 46c23e73aa6e84ae8a6601420e2a68b53af3f50c..35222c7565483f9be8c9b5685304d6b74e20fdb3 100644 (file)
@@ -76,9 +76,11 @@ Http2PushPromiseFrame::Http2PushPromiseFrame(const uint8_t* header_buffer,
     if (!hpack_decoder->decode_headers((data.start() + hpack_headers_offset), data.length() -
         hpack_headers_offset, decoded_headers, start_line_generator, false))
     {
-        session_data->abort_flow[source_id] = true;
-        session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
-        return;
+        if (!(*session_data->infractions[source_id] & INF_TRUNCATED_HEADER_LINE))
+        {
+            session_data->abort_flow[source_id] = true;
+            session_data->events[source_id]->create_event(EVENT_MISFORMATTED_HTTP2);
+        }
     }
 }
 
@@ -116,7 +118,7 @@ bool Http2PushPromiseFrame::valid_sequence(Http2Enums::StreamState)
 
 void Http2PushPromiseFrame::analyze_http1()
 {
-    if (!start_line_generator->generate_start_line(start_line))
+    if (!start_line_generator->generate_start_line(start_line, are_pseudo_headers_complete()))
     {
         // can't send request or push-promise headers to http_inspect, but response will still
         // be processed
index b1351502ffdb9fdf61fcd92838a876c75d2320c2..7e3fb9e2acc90299657fde3a047911fa74c19afe 100644 (file)
@@ -77,19 +77,23 @@ void Http2RequestLine::process_pseudo_header(const Field& name, const Field& val
 }
 
 // Select the appropriate URI form based on the provided pseudo-headers and generate the start line
-bool Http2RequestLine::generate_start_line(Field& start_line)
+bool Http2RequestLine::generate_start_line(Field& start_line, bool pseudo_headers_complete)
 {
     uint32_t bytes_written = 0;
 
-    // Asterisk form - used for OPTIONS requests
-    if (path.length() > 0 and path.start()[0] == '*')
+    if (method.length() <= 0)
     {
-        if (method.length() <= 0)
+        if (pseudo_headers_complete)
         {
-            *infractions += INF_PSEUDO_HEADER_URI_FORM_MISMATCH;
+            *infractions += INF_REQUEST_WITHOUT_METHOD;
             events->create_event(EVENT_REQUEST_WITHOUT_REQUIRED_FIELD);
-            return false;
         }
+        return false;
+    }
+
+    // Asterisk form - used for OPTIONS requests
+    if (path.length() > 0 and path.start()[0] == '*')
+    {
         start_line_length = method.length() + path.length() + http_version_length +
             NUM_REQUEST_LINE_EXTRA_CHARS;
         start_line_buffer = new uint8_t[start_line_length];
@@ -113,15 +117,18 @@ bool Http2RequestLine::generate_start_line(Field& start_line)
         // FIXIT-L May want to be more lenient than RFC on generating start line
         if (authority.length() <= 0)
         {
-            *infractions += INF_PSEUDO_HEADER_URI_FORM_MISMATCH;
-            events->create_event(EVENT_REQUEST_WITHOUT_REQUIRED_FIELD);
+            if (pseudo_headers_complete)
+            {
+                *infractions += INF_CONNECT_WITHOUT_AUTHORITY;
+                events->create_event(EVENT_REQUEST_WITHOUT_REQUIRED_FIELD);
+            }
             return false;
         }
         // Should not have a scheme or path
         if ( scheme.length() > 0 or path.length() > 0)
         {
-            *infractions += INF_PSEUDO_HEADER_URI_FORM_MISMATCH;
-            events->create_event(EVENT_INVALID_HEADER);
+            *infractions += INF_CONNECT_WITH_SCHEME_OR_PATH;
+            events->create_event(EVENT_CONNECT_WITH_SCHEME_OR_PATH);
         }
         start_line_length = method.length() + authority.length() + http_version_length +
             NUM_REQUEST_LINE_EXTRA_CHARS;
@@ -139,7 +146,7 @@ bool Http2RequestLine::generate_start_line(Field& start_line)
         bytes_written += http_version_length;
     }
     // HTTP/2 requests with URIs in absolute or origin form must have a method, scheme, and length
-    else if (method.length() > 0 and scheme.length() > 0 and path.length() > 0)
+    else if (scheme.length() > 0 and path.length() > 0)
     {
         // If there is an authority, the URI is in absolute form
         if (authority.length() > 0)
@@ -188,8 +195,11 @@ bool Http2RequestLine::generate_start_line(Field& start_line)
     else
     {
         // FIXIT-E May want to be more lenient than RFC on generating start line
-        *infractions += INF_PSEUDO_HEADER_URI_FORM_MISMATCH;
-        events->create_event(EVENT_REQUEST_WITHOUT_REQUIRED_FIELD);
+        if (pseudo_headers_complete)
+        {
+            *infractions += INF_REQUEST_WITHOUT_REQUIRED_FIELD;
+            events->create_event(EVENT_REQUEST_WITHOUT_REQUIRED_FIELD);
+        }
         return false;
     }
 
index 32d9460c2bbc17eae95ba3bc571946098c4dd764..565dc5bcbb192b3eee67d5c08da7f316f9a2860b 100644 (file)
@@ -32,7 +32,7 @@ public:
     Http2RequestLine(Http2EventGen* const evs, Http2Infractions* const infrs) :
         Http2StartLine(evs, infrs) { }
     void process_pseudo_header(const Field& name, const Field& value) override;
-    bool generate_start_line(Field& start_line) override;
+    bool generate_start_line(Field& start_line, bool pseudo_headers_complete) override;
 
 private:
     Field method;
index c453169d7f9ed0df037a9eebe94676d4f3a1c1bd..3d116727c5c5ed12fefd102a12ee4db95378d1ed 100644 (file)
@@ -40,7 +40,7 @@ public:
 
     friend class Http2Hpack;
 
-    virtual bool generate_start_line(Field& start_line) = 0;
+    virtual bool generate_start_line(Field& start_line, bool pseudo_headers_complete) = 0;
     virtual void process_pseudo_header(const Field& name, const Field& value) = 0;
 
 protected:
index 6d0c8b03c039f9f1c9a0d3ef6af994a7f0bf7c1c..433f98b0936feef9cae548a3380f276c8e35ff71 100644 (file)
@@ -52,7 +52,7 @@ void Http2StatusLine::process_pseudo_header(const Field& name, const Field& valu
     }
 }
 
-bool Http2StatusLine::generate_start_line(Field& start_line)
+bool Http2StatusLine::generate_start_line(Field& start_line, bool pseudo_headers_complete)
 {
     uint32_t bytes_written = 0;
 
@@ -61,8 +61,11 @@ bool Http2StatusLine::generate_start_line(Field& start_line)
 
     if (status.length() <= 0)
     {
-        *infractions += INF_RESPONSE_WITHOUT_STATUS;
-        events->create_event(EVENT_RESPONSE_WITHOUT_STATUS);
+        if (pseudo_headers_complete)
+        {
+            *infractions += INF_RESPONSE_WITHOUT_STATUS;
+            events->create_event(EVENT_RESPONSE_WITHOUT_STATUS);
+        }
         return false;
     }
 
index 0ccdc14cc5b3925c86aee99529f6ca0fd15dee54..ca3a61fc30d6c3a8bf40b2534c837bdc2846198b 100644 (file)
@@ -32,7 +32,7 @@ public:
         Http2StartLine(evs, infrs) { }
 
     void process_pseudo_header(const Field& name, const Field& value) override;
-    bool generate_start_line(Field& start_line) override;
+    bool generate_start_line(Field& start_line, bool pseudo_headers_complete) override;
 
 private:
     Field status;
index 03ad730ea72fb85de2604041c85fc12a199b3279..e92f352aa5ef96202fe60c25b6230e38af030d66 100644 (file)
@@ -215,15 +215,33 @@ bool Http2StreamSplitter::finish(Flow* flow)
     }
 #endif
 
-    // Loop through all nonzero streams and call NHI finish()
     bool need_reassemble = false;
+
+    // First check if there is a partial header that needs to be processed. If we have a partial
+    // trailer don't call finish on that stream below
+    if (((session_data->frame_type[source_id] == FT_HEADERS) or
+            (session_data->frame_type[source_id] == FT_PUSH_PROMISE)) and
+        ((session_data->scan_remaining_frame_octets[source_id] > 0) or
+            (session_data->continuation_expected[source_id])))
+    {
+        session_data->processing_partial_header = true;
+        need_reassemble = true;
+#ifdef REG_TEST
+        if (HttpTestManager::use_test_input(HttpTestManager::IN_HTTP2))
+            HttpTestManager::get_test_input_source()->flush(0);
+#endif
+    }
+
+    // Loop through all nonzero streams with open message bodies and call NHI finish()
     for (const Http2FlowData::StreamInfo& stream_info : session_data->streams)
     {
         if ((stream_info.id == 0)                                                 ||
             (stream_info.stream->get_state(source_id) >= STREAM_COMPLETE)         ||
             (stream_info.stream->get_hi_flow_data() == nullptr)                   ||
             (stream_info.stream->get_hi_flow_data()->get_type_expected(source_id)
-                != HttpEnums::SEC_BODY_H2))
+                != HttpEnums::SEC_BODY_H2)                                        ||
+            (session_data->processing_partial_header &&
+                (stream_info.id == session_data->current_stream[source_id])))
         {
             continue;
         }
index e3265a1c2b6d8ccc2ea076dcf0d1c4267dd8789a..f4573b81c61af64deda256092020c6a6c589c39e 100644 (file)
@@ -31,21 +31,21 @@ using namespace snort;
 
 const RuleMap Http2Module::http2_events[] =
 {
-    { EVENT_INT_DECODE_FAILURE, "error in HPACK integer value" },
+    { EVENT_INVALID_FLAG, "invalid flag set on HTTP/2 frame" },
     { EVENT_INT_LEADING_ZEROS, "HPACK integer value has leading zeros" },
-    { EVENT_STRING_DECODE_FAILURE, "error in HPACK string value" },
+    { EVENT_INVALID_STREAM_ID, "HTTP/2 stream initiated with invalid stream id" },
     { EVENT_MISSING_CONTINUATION, "missing HTTP/2 continuation frame" },
     { EVENT_UNEXPECTED_CONTINUATION, "unexpected HTTP/2 continuation frame" },
     { EVENT_MISFORMATTED_HTTP2, "misformatted HTTP/2 traffic" },
     { EVENT_PREFACE_MATCH_FAILURE, "HTTP/2 connection preface does not match" },
     { EVENT_REQUEST_WITHOUT_REQUIRED_FIELD, "HTTP/2 request missing required header field" },
     { EVENT_RESPONSE_WITHOUT_STATUS, "HTTP/2 response has no status code" },
-    { EVENT_INVALID_HEADER, "HTTP/2 invalid header field" },
+    { EVENT_CONNECT_WITH_SCHEME_OR_PATH, "HTTP/2 CONNECT request with scheme or path" },
     { EVENT_SETTINGS_FRAME_ERROR, "error in HTTP/2 settings frame" },
     { EVENT_SETTINGS_FRAME_UNKN_PARAM, "unknown parameter in HTTP/2 settings frame" },
     { EVENT_FRAME_SEQUENCE, "invalid HTTP/2 frame sequence" },
     { EVENT_DYNAMIC_TABLE_OVERFLOW, "HTTP/2 dynamic table size limit exceeded" },
-    { EVENT_INVALID_STARTLINE, "invalid HTTP/2 start line" },
+    { EVENT_INVALID_PROMISED_STREAM, "HTTP/2 push promise frame with invalid promised stream id" },
     { EVENT_PADDING_LEN, "HTTP/2 padding length is bigger than frame data size" },
     { EVENT_PSEUDO_HEADER_AFTER_REGULAR_HEADER, "HTTP/2 pseudo-header after regular header" },
     { EVENT_PSEUDO_HEADER_IN_TRAILERS, "HTTP/2 pseudo-header in trailers" },
@@ -58,9 +58,6 @@ const RuleMap Http2Module::http2_events[] =
     { EVENT_BAD_PUSH_SEQUENCE, "HTTP/2 push promise frame sent at invalid time" },
     { EVENT_BAD_SETTINGS_VALUE, "invalid parameter value sent in HTTP/2 settings frame" },
     { EVENT_PUSH_WHEN_PROHIBITED, "HTTP/2 push promise frame sent when prohibited by receiver" },
-    { EVENT_INVALID_PROMISED_STREAM, "HTTP/2 push promise frame with invalid promised stream id" },
-    { EVENT_INVALID_STREAM_ID, "HTTP/2 stream initiated with invalid stream id" },
-    { EVENT_INVALID_FLAG, "invalid flag set on HTTP/2 frame" },
     { 0, nullptr }
 };
 
index ed23e3516d8ea0758243d8b4be6ae4606bf67473..8eec00d41eb9ecff32a23953cb3c90db5ffb9b00 100644 (file)
@@ -61,7 +61,7 @@ TEST(http2_hpack_int_decode_success, 10_using_5_bits)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode->translate(&buf, 1, bytes_processed, res, &events, &inf);
+    bool success = decode->translate(&buf, 1, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == 10);
@@ -75,7 +75,7 @@ TEST(http2_hpack_int_decode_success, 10_using_5_bits_wtail)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode->translate(buf, 2, bytes_processed, res, &events, &inf);
+    bool success = decode->translate(buf, 2, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == 10);
@@ -89,7 +89,7 @@ TEST(http2_hpack_int_decode_success, 1337_using_5_bits)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode->translate(buf, 3, bytes_processed, res, &events, &inf);
+    bool success = decode->translate(buf, 3, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == 1337);
@@ -105,7 +105,7 @@ TEST(http2_hpack_int_decode_success, 42_using_8_bits)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode_8.translate(&buf, 1, bytes_processed, res, &events, &inf);
+    bool success = decode_8.translate(&buf, 1, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == 42);
@@ -119,7 +119,7 @@ TEST(http2_hpack_int_decode_success, max_val_using_5_bit)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode->translate(buf, 11, bytes_processed, res, &events, &inf);
+    bool success = decode->translate(buf, 11, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == 0xFFFFFFFFFFFFFFFF);
@@ -133,7 +133,7 @@ TEST(http2_hpack_int_decode_success, 31_using_5_bits)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode->translate(buf, 2, bytes_processed, res, &events, &inf);
+    bool success = decode->translate(buf, 2, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == 31);
@@ -147,7 +147,7 @@ TEST(http2_hpack_int_decode_success, 0_using_5_bits)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode->translate(&buf, 1, bytes_processed, res, &events, &inf);
+    bool success = decode->translate(&buf, 1, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == 0);
@@ -163,7 +163,7 @@ TEST(http2_hpack_int_decode_success, MAX_UINT32_using_7_bits)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode_7.translate(buf, 6, bytes_processed, res, &events, &inf);
+    bool success = decode_7.translate(buf, 6, bytes_processed, res, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(res == UINT32_MAX);
@@ -188,12 +188,12 @@ TEST(http2_hpack_int_decode_failure, 0_len_field)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = decode_8.translate(&buf, 0, bytes_processed, res, &local_events, &local_inf);
+    bool success = decode_8.translate(&buf, 0, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 0);
     CHECK(local_inf.get_raw() == (1<<INF_INT_EMPTY_BUFF));
-    CHECK(local_events.get_raw() == (1<<(EVENT_INT_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_int_decode_failure, too_short)
@@ -207,12 +207,12 @@ TEST(http2_hpack_int_decode_failure, too_short)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = local_decode.translate(buf, 2, bytes_processed, res, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 2, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 2);
     CHECK(local_inf.get_raw() == (1<<INF_INT_MISSING_BYTES));
-    CHECK(local_events.get_raw() == (1<<(EVENT_INT_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_int_decode_failure, multiplier_bigger_than_63)
@@ -226,12 +226,12 @@ TEST(http2_hpack_int_decode_failure, multiplier_bigger_than_63)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = local_decode.translate(buf, 13, bytes_processed, res, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 13, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 11);
     CHECK(local_inf.get_raw() == (1<<INF_INT_OVERFLOW));
-    CHECK(local_events.get_raw() == (1<<(EVENT_INT_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_int_decode_failure, add_val_overflow)
@@ -245,12 +245,12 @@ TEST(http2_hpack_int_decode_failure, add_val_overflow)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = local_decode.translate(buf, 12, bytes_processed, res, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 12, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 11);
     CHECK(local_inf.get_raw() == (1<<INF_INT_OVERFLOW));
-    CHECK(local_events.get_raw() == (1<<(EVENT_INT_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_int_decode_failure, add_val_overflow2)
@@ -264,12 +264,12 @@ TEST(http2_hpack_int_decode_failure, add_val_overflow2)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = local_decode.translate(buf, 11, bytes_processed, res, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 11, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 11);
     CHECK(local_inf.get_raw() == (1<<INF_INT_OVERFLOW));
-    CHECK(local_events.get_raw() == (1<<(EVENT_INT_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_int_decode_failure, 2_64_using_5_bit)
@@ -283,12 +283,12 @@ TEST(http2_hpack_int_decode_failure, 2_64_using_5_bit)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = local_decode.translate(buf, 11, bytes_processed, res, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 11, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 11);
     CHECK(local_inf.get_raw() == (1<<INF_INT_OVERFLOW));
-    CHECK(local_events.get_raw() == (1<<(EVENT_INT_DECODE_FAILURE-1)));
 }
 
 //
@@ -310,7 +310,8 @@ TEST(http2_hpack_int_decode_leading_zeros, leading_zeros)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = local_decode.translate(buf, 3, bytes_processed, res, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 3, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(res == 31);
@@ -331,7 +332,8 @@ TEST(http2_hpack_int_decode_leading_zeros, leading_0_byte_11)
     // decode
     uint32_t bytes_processed = 0;
     uint64_t res = 0;
-    bool success = local_decode.translate(buf, 11, bytes_processed, res, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 11, bytes_processed, res, &local_events, &local_inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(res == 0x7FFFFFFFFFFFFFFF);
index 2716cd54c54bbbfafad4157dc44b8dbe1ad79c3b..6e69ae2c0b6a3ceb4a9fd59f7901d7f3544a8a98 100644 (file)
@@ -65,7 +65,8 @@ TEST(http2_hpack_string_decode_success, custom_key_len_10)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[10];
-    bool success = decode->translate(buf, 11, bytes_processed, res, 10, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 11, bytes_processed, res, 10, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(memcmp(res, "custom-key", 10) == 0);
@@ -80,7 +81,8 @@ TEST(http2_hpack_string_decode_success, custom_key_len_10_wtail)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[12];
-    bool success = decode->translate(buf, 12, bytes_processed, res, 12, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 12, bytes_processed, res, 12, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(memcmp(res, "custom-key", 10) == 0);
@@ -98,7 +100,8 @@ TEST(http2_hpack_string_decode_success, int_is_more_than_1_byte)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[130];
-    bool success = decode->translate(buf, 130, bytes_processed, res, 130, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 130, bytes_processed, res, 130, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 130);
@@ -113,7 +116,8 @@ TEST(http2_hpack_string_decode_success, empty_string)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res = 10; // random value, just to check it wasn't overwritten
-    bool success = decode->translate(&buf, 1, bytes_processed, &res, 1, bytes_written, &events, &inf);
+    bool success = decode->translate(&buf, 1, bytes_processed, &res, 1, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 1);
@@ -128,7 +132,8 @@ TEST(http2_hpack_string_decode_success, string_len_1)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res = 0;
-    bool success = decode->translate(buf, 2, bytes_processed, &res, 1, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 2, bytes_processed, &res, 1, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 2);
@@ -149,7 +154,7 @@ TEST(http2_hpack_string_decode_success, max_field_length)
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[MAX_OCTETS];
     bool success = decode->translate(buf, MAX_OCTETS, bytes_processed, res,
-        MAX_OCTETS, bytes_written, &events, &inf);
+        MAX_OCTETS, bytes_written, &events, &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == MAX_OCTETS);
@@ -164,7 +169,8 @@ TEST(http2_hpack_string_decode_success, huffman_1_byte)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[1];
-    bool success = decode->translate(buf, 2, bytes_processed, res, 1, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 2, bytes_processed, res, 1, bytes_written, &events, &inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 2);
@@ -179,7 +185,8 @@ TEST(http2_hpack_string_decode_success, huffman_1_byte_star)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[1];
-    bool success = decode->translate(buf, 2, bytes_processed, res, 1, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 2, bytes_processed, res, 1, bytes_written, &events, &inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 2);
@@ -194,7 +201,8 @@ TEST(http2_hpack_string_decode_success, huffman_2_bytes_aligned)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[3];
-    bool success = decode->translate(buf, 3, bytes_processed, res, 3, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 3, bytes_processed, res, 3, bytes_written, &events, &inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 3);
@@ -209,7 +217,8 @@ TEST(http2_hpack_string_decode_success, huffman_2_bytes_unaligned)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[3];
-    bool success = decode->translate(buf, 3, bytes_processed, res, 3, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 3, bytes_processed, res, 3, bytes_written, &events, &inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 3);
@@ -224,7 +233,8 @@ TEST(http2_hpack_string_decode_success, huffman_rfc_example1)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[19];
-    bool success = decode->translate(buf, 13, bytes_processed, res, 19, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 13, bytes_processed, res, 19, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 13);
@@ -239,7 +249,8 @@ TEST(http2_hpack_string_decode_success, huffman_rfc_example2)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[9];
-    bool success = decode->translate(buf, 7, bytes_processed, res, 9, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 7, bytes_processed, res, 9, bytes_written, &events, &inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 7);
@@ -254,7 +265,8 @@ TEST(http2_hpack_string_decode_success, huffman_rfc_example3)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[12];
-    bool success = decode->translate(buf, 9, bytes_processed, res, 12, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 9, bytes_processed, res, 12, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 9);
@@ -269,7 +281,8 @@ TEST(http2_hpack_string_decode_success, huffman_rfc_example4)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[14];
-    bool success = decode->translate(buf, 10, bytes_processed, res, 14, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 10, bytes_processed, res, 14, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 10);
@@ -285,7 +298,8 @@ TEST(http2_hpack_string_decode_success, huffman_rfc_example5)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[35];
-    bool success = decode->translate(buf, 23, bytes_processed, res, 35, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 23, bytes_processed, res, 35, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 23);
@@ -303,7 +317,8 @@ TEST(http2_hpack_string_decode_success, huffman_rfc_example6)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[73];
-    bool success = decode->translate(buf, 46, bytes_processed, res, 73, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 46, bytes_processed, res, 73, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 46);
@@ -318,7 +333,8 @@ TEST(http2_hpack_string_decode_success, huffman_unaligned_then_aligned)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[6];
-    bool success = decode->translate(buf, 5, bytes_processed, res, 6, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 5, bytes_processed, res, 6, bytes_written, &events, &inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 5);
@@ -334,7 +350,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_1)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[32];
-    bool success = decode->translate(buf, 21, bytes_processed, res, 32, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 21, bytes_processed, res, 32, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 21);
@@ -350,7 +367,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_2)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[36];
-    bool success = decode->translate(buf, 24, bytes_processed, res, 36, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 24, bytes_processed, res, 36, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 24);
@@ -365,7 +383,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_3)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[12];
-    bool success = decode->translate(buf, 9, bytes_processed, res, 12, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 9, bytes_processed, res, 12, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 9);
@@ -382,7 +401,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_4)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[70];
-    bool success = decode->translate(buf, 45, bytes_processed, res, 70, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 45, bytes_processed, res, 70, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 45);
@@ -401,7 +421,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[88];
     uint8_t expected[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
-    bool success = decode->translate(buf, 55, bytes_processed, res, 88, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 55, bytes_processed, res, 88, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 55);
@@ -420,7 +441,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[93];
     uint8_t expected[16] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
-    bool success = decode->translate(buf, 58, bytes_processed, res, 93, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 58, bytes_processed, res, 93, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 58);
@@ -439,7 +461,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[79];
     uint8_t expected[17] = {0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F};
-    bool success = decode->translate(buf, 49, bytes_processed, res, 79, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 49, bytes_processed, res, 79, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 49);
@@ -458,7 +481,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[76];
     uint8_t expected[16] = {0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F};
-    bool success = decode->translate(buf, 47, bytes_processed, res, 76, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 47, bytes_processed, res, 76, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 47);
@@ -476,7 +500,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[74];
     uint8_t expected[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF};
-    bool success = decode->translate(buf, 46, bytes_processed, res, 74, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 46, bytes_processed, res, 74, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 46);
@@ -495,7 +520,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[73];
     uint8_t expected[16] = {0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF};
-    bool success = decode->translate(buf, 45, bytes_processed, res, 73, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 45, bytes_processed, res, 73, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 45);
@@ -515,7 +541,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[80];
     uint8_t expected[16] = {0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF};
-    bool success = decode->translate(buf, 50, bytes_processed, res, 80, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 50, bytes_processed, res, 80, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 50);
@@ -535,7 +562,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[82];
     uint8_t expected[16] = {0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF};
-    bool success = decode->translate(buf, 51, bytes_processed, res, 82, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 51, bytes_processed, res, 82, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 51);
@@ -554,7 +582,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[76];
     uint8_t expected[16] = {0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF};
-    bool success = decode->translate(buf, 47, bytes_processed, res, 76, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 47, bytes_processed, res, 76, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 47);
@@ -574,7 +603,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_all_possible_symbols_he
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[88];
     uint8_t expected[16] = {0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF};
-    bool success = decode->translate(buf, 55, bytes_processed, res, 88, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 55, bytes_processed, res, 88, bytes_written, &events,
+        &inf, false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 55);
@@ -590,7 +620,8 @@ TEST(http2_hpack_string_decode_success, huffman_decoding_tail_lookup_unsucessful
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[3];
-    bool success = decode->translate(buf, 3, bytes_processed, res, 3, bytes_written, &events, &inf);
+    bool success = decode->translate(buf, 3, bytes_processed, res, 3, bytes_written, &events, &inf,
+        false);
     // check results
     CHECK(success == true);
     CHECK(bytes_processed == 3);
@@ -615,13 +646,13 @@ TEST(http2_hpack_string_decode_infractions, 0_len_field)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res;
-    bool success = local_decode.translate(&buf, 0, bytes_processed, &res, 1, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(&buf, 0, bytes_processed, &res, 1, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 0);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_STRING_EMPTY_BUFF));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, missing_bytes)
@@ -635,13 +666,13 @@ TEST(http2_hpack_string_decode_infractions, missing_bytes)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[2];
-    bool success = local_decode.translate(&buf, 1, bytes_processed, res, 2, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(&buf, 1, bytes_processed, res, 2, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_written == 0);
     CHECK(bytes_processed == 1);
     CHECK(local_inf.get_raw() == (1<<INF_STRING_MISSING_BYTES));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, bad_int)
@@ -655,13 +686,13 @@ TEST(http2_hpack_string_decode_infractions, bad_int)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[2];
-    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 2);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_INT_MISSING_BYTES));
-    CHECK(local_events.get_raw() == (1<<(EVENT_INT_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, max_field_length_plus_1)
@@ -681,13 +712,12 @@ TEST(http2_hpack_string_decode_infractions, max_field_length_plus_1)
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[MAX_OCTETS];
     bool success = local_decode.translate(buf, MAX_OCTETS, bytes_processed, res,
-        MAX_OCTETS, bytes_written, &local_events, &local_inf);
+        MAX_OCTETS, bytes_written, &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 4);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_STRING_MISSING_BYTES));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, out_buf_out_of_space)
@@ -707,13 +737,12 @@ TEST(http2_hpack_string_decode_infractions, out_buf_out_of_space)
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[MAX_OCTETS-5];
     bool success = local_decode.translate(buf, MAX_OCTETS, bytes_processed, res,
-        MAX_OCTETS-5, bytes_written, &local_events, &local_inf);
+        MAX_OCTETS-5, bytes_written, &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 4);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_DECODED_HEADER_BUFF_OUT_OF_SPACE));
-    CHECK(local_events.get_raw() == (1<<(EVENT_MISFORMATTED_HTTP2-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, huffman_1_byte_bad_padding)
@@ -727,13 +756,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_1_byte_bad_padding)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[2];
-    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 2);
     CHECK(bytes_written == 1);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_BAD_PADDING));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, huffman_1_byte_incomplete_FF)
@@ -747,13 +776,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_1_byte_incomplete_FF)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[2];
-    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 2);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_INCOMPLETE_CODE_PADDING));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, huffman_1_byte_incomplete_FE)
@@ -767,13 +796,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_1_byte_incomplete_FE)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[2];
-    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 2, bytes_processed, res, 2, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 2);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_INCOMPLETE_CODE_PADDING));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, huffman_2_bytes_incomplete_FF_FE)
@@ -787,13 +816,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_2_bytes_incomplete_FF_FE)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[5];
-    bool success = local_decode.translate(buf, 3, bytes_processed, res, 5, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 3, bytes_processed, res, 5, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 3);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_INCOMPLETE_CODE_PADDING));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, huffman_3_bytes_incomplete)
@@ -807,13 +836,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_3_bytes_incomplete)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[7];
-    bool success = local_decode.translate(buf, 4, bytes_processed, res, 7, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 4, bytes_processed, res, 7, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 4);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_INCOMPLETE_CODE_PADDING));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 TEST(http2_hpack_string_decode_infractions, huffman_FB_incomplete_FF)
@@ -827,13 +856,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_FB_incomplete_FF)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[5];
-    bool success = local_decode.translate(buf, 3, bytes_processed, res, 5, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 3, bytes_processed, res, 5, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 3);
     CHECK(bytes_written == 1);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_INCOMPLETE_CODE_PADDING));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
     CHECK(memcmp(res, ";", 1) == 0);
 }
 
@@ -848,13 +877,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_07_incomplete_FF)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[5];
-    bool success = local_decode.translate(buf, 3, bytes_processed, res, 5, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 3, bytes_processed, res, 5, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 3);
     CHECK(bytes_written == 1);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_INCOMPLETE_CODE_PADDING));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
     CHECK(memcmp(res, "0", 1) == 0);
 }
 
@@ -869,13 +898,13 @@ TEST(http2_hpack_string_decode_infractions, huffman_decoded_eos)
     // decode
     uint32_t bytes_processed = 0, bytes_written = 0;
     uint8_t res[10];
-    bool success = local_decode.translate(buf, 5, bytes_processed, res, 10, bytes_written, &local_events, &local_inf);
+    bool success = local_decode.translate(buf, 5, bytes_processed, res, 10, bytes_written,
+        &local_events, &local_inf, false);
     // check results
     CHECK(success == false);
     CHECK(bytes_processed == 4);
     CHECK(bytes_written == 0);
     CHECK(local_inf.get_raw() == (1<<INF_HUFFMAN_DECODED_EOS));
-    CHECK(local_events.get_raw() == (1<<(EVENT_STRING_DECODE_FAILURE-1)));
 }
 
 int main(int argc, char** argv)
index 9aa85c24c8421d00d636f2fd2cf68cff41e483cb..0cd6adff997af90c11322f88070bcfe2f6f5bfe2 100644 (file)
@@ -107,7 +107,6 @@ bool HttpStreamSplitter::finish(Flow* flow)
         (session_data->cutter[source_id] == nullptr)                &&
         (session_data->section_type[source_id] == SEC__NOT_COMPUTE))
     {
-        assert(!session_data->for_http2);
         // Set up to process empty header section
         uint32_t not_used;
         prepare_flush(session_data, &not_used, SEC_HEADER, 0, 0, 0, false, 0, 0);