]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #761 in SNORT/snort3 from nhttp62 to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 21 Dec 2016 18:35:37 +0000 (13:35 -0500)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 21 Dec 2016 18:35:37 +0000 (13:35 -0500)
Squashed commit of the following:

commit ad012fd47facac9599f369baac37ae33b292af13
Author: Tom Peters <thopeter@cisco.com>
Date:   Wed Dec 14 11:18:29 2016 -0500

    Improve NHI Field class

31 files changed:
src/network_inspectors/appid/test/appid_http_event_test.cc
src/pub_sub/http_events.cc
src/service_inspectors/http_inspect/dev_notes.txt
src/service_inspectors/http_inspect/http_field.cc
src/service_inspectors/http_inspect/http_field.h
src/service_inspectors/http_inspect/http_flow_data.cc
src/service_inspectors/http_inspect/http_flow_data.h
src/service_inspectors/http_inspect/http_head_norm.cc
src/service_inspectors/http_inspect/http_inspect.cc
src/service_inspectors/http_inspect/http_inspect.h
src/service_inspectors/http_inspect/http_js_norm.cc
src/service_inspectors/http_inspect/http_js_norm.h
src/service_inspectors/http_inspect/http_msg_body.cc
src/service_inspectors/http_inspect/http_msg_body.h
src/service_inspectors/http_inspect/http_msg_head_shared.cc
src/service_inspectors/http_inspect/http_msg_head_shared.h
src/service_inspectors/http_inspect/http_msg_head_shared_util.cc
src/service_inspectors/http_inspect/http_msg_header.cc
src/service_inspectors/http_inspect/http_msg_request.cc
src/service_inspectors/http_inspect/http_msg_section.cc
src/service_inspectors/http_inspect/http_msg_section.h
src/service_inspectors/http_inspect/http_msg_start.cc
src/service_inspectors/http_inspect/http_msg_status.cc
src/service_inspectors/http_inspect/http_normalizers.cc
src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc
src/service_inspectors/http_inspect/http_uri.cc
src/service_inspectors/http_inspect/http_uri.h
src/service_inspectors/http_inspect/http_uri_norm.cc
src/service_inspectors/http_inspect/http_uri_norm.h
src/service_inspectors/http_inspect/ips_http.cc
src/service_inspectors/http_inspect/test/http_uri_norm_test.cc

index 14f60a161f25ec74880ced8d4f40fbe84b626a8f..2e7ec084d294899cb6f5ccdd9f2cf57fb840d039 100644 (file)
@@ -68,10 +68,11 @@ const char *uri = nullptr;
 const char *useragent = nullptr;
 const char *via = nullptr;
 
-void Field::set(int32_t length_, const uint8_t* start_)
+void Field::set(int32_t length, const uint8_t* start, bool own_the_buffer_)
 {
-    start = start_;
-    length = length_;
+    strt = start;
+    len = length;
+    own_the_buffer = own_the_buffer_;
 }
 
 Field global_field;
@@ -158,8 +159,8 @@ const uint8_t* HttpEvent::get_content_type(int32_t &length)
     global_field.set(0, nullptr);
     if(content_type)
         global_field.set(strlen(content_type), (const uint8_t*)content_type);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_cookie(int32_t &length)
@@ -167,8 +168,8 @@ const uint8_t* HttpEvent::get_cookie(int32_t &length)
     global_field.set(0, nullptr);
     if(cookie)
         global_field.set(strlen(cookie), (const uint8_t*)cookie);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_host(int32_t &length)
@@ -176,8 +177,8 @@ const uint8_t* HttpEvent::get_host(int32_t &length)
     global_field.set(0, nullptr);
     if(host)
         global_field.set(strlen(host), (const uint8_t*)host);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_location(int32_t &length)
@@ -185,8 +186,8 @@ const uint8_t* HttpEvent::get_location(int32_t &length)
     global_field.set(0, nullptr);
     if(location)
         global_field.set(strlen(location), (const uint8_t*)location);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_referer(int32_t &length)
@@ -194,8 +195,8 @@ const uint8_t* HttpEvent::get_referer(int32_t &length)
     global_field.set(0, nullptr);
     if(referer)
         global_field.set(strlen(referer), (const uint8_t*)referer);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 int32_t HttpEvent::get_response_code()
@@ -208,8 +209,8 @@ const uint8_t* HttpEvent::get_server(int32_t &length)
     global_field.set(0, nullptr);
     if(server)
         global_field.set(strlen(server), (const uint8_t*)server);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_uri(int32_t &length)
@@ -217,8 +218,8 @@ const uint8_t* HttpEvent::get_uri(int32_t &length)
     global_field.set(0, nullptr);
     if(uri)
         global_field.set(strlen(uri), (const uint8_t*)uri);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_user_agent(int32_t &length)
@@ -226,8 +227,8 @@ const uint8_t* HttpEvent::get_user_agent(int32_t &length)
     global_field.set(0, nullptr);
     if(useragent)
         global_field.set(strlen(useragent), (const uint8_t*)useragent);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_via(int32_t &length)
@@ -235,8 +236,8 @@ const uint8_t* HttpEvent::get_via(int32_t &length)
     global_field.set(0, nullptr);
     if(via)
         global_field.set(strlen(via), (const uint8_t*)via);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 const uint8_t* HttpEvent::get_x_working_with(int32_t &length)
@@ -244,8 +245,8 @@ const uint8_t* HttpEvent::get_x_working_with(int32_t &length)
     global_field.set(0, nullptr);
     if(x_working_with)
         global_field.set(strlen(x_working_with), (const uint8_t*)x_working_with);
-    length = global_field.length;
-    return global_field.start;
+    length = global_field.length();
+    return global_field.start();
 }
 
 Flow::Flow() {}
index d24175b758787ef72e982614c48a6e063bf8e259..0cff64975a054a42d13cb3be82831b4c0d652d72 100644 (file)
 
 const uint8_t* HttpEvent::get_header(unsigned id, uint64_t sub_id, int32_t& length)
 {
-    Field field;
-    field = http_msg_header->get_classic_buffer(id, sub_id, 0);
-    if(field.length > 0)
+    const Field& field = http_msg_header->get_classic_buffer(id, sub_id, 0);
+    if(field.length() > 0)
     {
-        length = field.length;
-        return field.start;
+        length = field.length();
+        return field.start();
     }
     else
     {
index 2fe512559ab419c6441f595c40dcb4ff6263785b..f6ccfb8e749d028054a7aa341dde3a55510307a0 100644 (file)
@@ -73,10 +73,14 @@ former case the original message is constant and there is no reason for a Field
 the latter case, once the value has been derived from the original message there is no reason to
 derive it again.
 
-Once Field is set to a non-null value it should never change. The set functions will assert if this
-rule is disregarded. Because the set functions are much newer than the class there are still large
-amounts of code that have not yet been converted to use them. Meanwhile adhere to the rule even
-when not using the set functions.
+Once Field is set to a non-null value it should never change. The set() functions will assert if
+this rule is disregarded.
+
+A Field may own the buffer containing the message or it may point to a buffer that belongs to
+someone else. When a Field owning a buffer is deleted the buffer is deleted as well. Ownership is
+determined with the Field is initially set. In general any dynamically allocated buffer should be
+owned by a Field. If you follow this rule you won't need to keep track of allocated buffers or have
+delete[]s all over the place.
 
 HI implements flow depth using the request_depth and response_depth parameters. HI seeks to provide
 a consistent experience to detection by making flow depth independent of factors that a sender
index d9c7c6b8ddc91fc351ad7c8f740cda88ba724854..e3dfcf642f28422b020c99bffdcd4f61d07a1380 100644 (file)
 using namespace HttpEnums;
 
 const Field Field::FIELD_NULL { STAT_NO_SOURCE };
-void Field::set(int32_t length_, const uint8_t* start_)
+
+void Field::set(int32_t length, const uint8_t* start, bool own_the_buffer_)
 {
-    assert(length == STAT_NOT_COMPUTE);
-    assert(start == nullptr);
-    assert(start_ != nullptr);
-    assert(length_ >= 0);
-    assert(length_ <= MAX_OCTETS);
-    start = start_;
-    length = length_;
+    assert(len == STAT_NOT_COMPUTE);
+    assert(strt == nullptr);
+    assert(start != nullptr);
+    assert(length >= 0);
+    assert(length <= MAX_OCTETS);
+    strt = start;
+    len = length;
+    own_the_buffer = own_the_buffer_;
 }
 
 void Field::set(StatusCode stat_code)
 {
-    assert(length == STAT_NOT_COMPUTE);
-    assert(start == nullptr);
+    assert(len == STAT_NOT_COMPUTE);
+    assert(strt == nullptr);
     assert(stat_code <= 0);
-    start = nullptr;
-    length = stat_code;
+    len = stat_code;
 }
 
 void Field::set(const Field& f)
 {
-    assert(length == STAT_NOT_COMPUTE);
-    assert(start == nullptr);
-    start = f.start;
-    length = f.length;
+    assert(len == STAT_NOT_COMPUTE);
+    assert(strt == nullptr);
+    strt = f.strt;
+    len = f.len;
+    // Both Fields cannot be responsible for deleting the buffer so do not copy own_the_buffer
 }
 
 #ifdef REG_TEST
 void Field::print(FILE* output, const char* name) const
 {
-    if ((length == STAT_NOT_PRESENT) || (length == STAT_NOT_COMPUTE) || (length == STAT_NO_SOURCE))
+    if ((len == STAT_NOT_PRESENT) || (len == STAT_NOT_COMPUTE) || (len == STAT_NO_SOURCE))
     {
         return;
     }
-    const int out_count = fprintf(output, "%s, length = %d, ", name, length);
-    if (length <= 0)
+    const int out_count = fprintf(output, "%s, length = %d, ", name, len);
+    if (len <= 0)
     {
         fprintf(output, "\n");
         return;
     }
     // Limit the amount of data printed
-    const int32_t print_length = (length <= HttpTestManager::get_print_amount()) ? length :
+    const int32_t print_length = (len <= HttpTestManager::get_print_amount()) ? len :
         HttpTestManager::get_print_amount();
     for (int32_t k=0; k < print_length; k++)
     {
-        if ((start[k] >= 0x20) && (start[k] <= 0x7E))
-            fprintf(output, "%c", (char)start[k]);
-        else if (start[k] == 0xD)
+        if ((strt[k] >= 0x20) && (strt[k] <= 0x7E))
+            fprintf(output, "%c", (char)strt[k]);
+        else if (strt[k] == 0xD)
             fprintf(output, "~");
-        else if (start[k] == 0xA)
+        else if (strt[k] == 0xA)
             fprintf(output, "^");
         else if (HttpTestManager::get_print_hex())
-            fprintf(output, "[%.2x]", (uint8_t)start[k]);
+            fprintf(output, "[%.2x]", (uint8_t)strt[k]);
         else
             fprintf(output, "*");
         if ((k%120 == (119 - out_count)) && (k+1 < print_length))
index 3ab1736fbc709bdfeaede8c0752ff329cbb2249c..26e7691da98407629f95f67f18d1d40bb2b65f09 100644 (file)
 class Field
 {
 public:
-    int32_t length = HttpEnums::STAT_NOT_COMPUTE;
-    const uint8_t* start = nullptr;
-
     static const Field FIELD_NULL;
 
-    Field(int32_t length_, const uint8_t* start_) : length(length_), start(start_) { }
-    explicit Field(int32_t length_) : length(length_) { assert(length<=0); }
+    Field(int32_t length, const uint8_t* start, bool own_the_buffer_ = false) : len(length),
+        own_the_buffer(own_the_buffer_), strt(start) { }
+    explicit Field(int32_t length) : len(length) { assert(length<=0); }
     Field() = default;
-    void set(int32_t length_, const uint8_t* start_);
+    ~Field() { if (own_the_buffer) delete[] strt; }
+    int32_t length() const { return len; }
+    const uint8_t* start() const { return strt; }
+    void set(int32_t length, const uint8_t* start, bool own_the_buffer_ = false);
     void set(const Field& f);
     void set(HttpEnums::StatusCode stat_code);
     void set(int32_t length) { set(static_cast<HttpEnums::StatusCode>(length)); }
-    // Only call this method if the field owns the dynamically allocated buffer you are deleting.
-    // This method is a convenience but you still must know where the buffer came from. Many fields
-    // refer to static buffers or a subfield of someone else's buffer.
-
-    // FIXIT-M the following test should undoubtedly be > 0. But this cannot be changed until a
-    // survey is done to ensure that no old code creates zero-length buffers. In practice this will
-    // happen naturally when start and length become private.
-    void delete_buffer() { if (length >= 0) delete[] start; }
 
 #ifdef REG_TEST
     void print(FILE* output, const char* name) const;
 #endif
+
+private:
+    Field& operator=(const Field&) = delete;
+
+    int32_t len = HttpEnums::STAT_NOT_COMPUTE;
+    bool own_the_buffer = false;
+    const uint8_t* strt = nullptr;
 };
 
 #endif
index 2ea6c3657a21351ed4ae1be0552f0ba472fd7005..fdbfc5785dbacae2c96094aea5cc00f40706e1f5 100644 (file)
@@ -57,11 +57,7 @@ HttpFlowData::~HttpFlowData()
 #endif
     for (int k=0; k <= 1; k++)
     {
-        if ((section_type[k] != SEC_BODY_CHUNK) &&
-            (section_type[k] != SEC_BODY_CL) &&
-            (section_type[k] != SEC_BODY_OLD))
-            // Body sections are reassembled in a static buffer
-            delete[] section_buffer[k];
+        delete[] section_buffer[k];
         HttpTransaction::delete_transaction(transaction[k]);
         delete cutter[k];
         if (compress_stream[k] != nullptr)
index ff858fddce1ff5ff74516e0423650c8dde91f88a..2c858f376a64c7b78944730f9bbb0a92e43094aa 100644 (file)
@@ -33,6 +33,7 @@
 
 class HttpTransaction;
 class HttpJsNorm;
+class HttpMsgSection;
 
 class HttpFlowData : public FlowData
 {
@@ -111,6 +112,7 @@ private:
     MimeSession* mime_state[2] = { nullptr, nullptr };
     UtfDecodeSession* utf_state = nullptr; // SRC_SERVER only
     uint64_t expected_trans_num[2] = { 1, 1 };
+    HttpMsgSection* latest_section = nullptr;
 
     // number of user data octets seen so far (regular body or chunks)
     int64_t body_octets[2] = { HttpEnums::STAT_NOT_PRESENT, HttpEnums::STAT_NOT_PRESENT };
index 7266706c8c844db43ed424f846334d7f072aa5db..ff5925edc022bead92183efda523e11ea599d0cc 100644 (file)
@@ -63,7 +63,7 @@ void HeaderNormalizer::normalize(const HeaderId head_id, const int count,
     HttpInfractions& infractions, HttpEventGen& events, const HeaderId header_name_id[],
     const Field header_value[], const int32_t num_headers, Field& result_field) const
 {
-    if (result_field.length != STAT_NOT_COMPUTE)
+    if (result_field.length() != STAT_NOT_COMPUTE)
     {
         return;
     }
@@ -84,7 +84,7 @@ void HeaderNormalizer::normalize(const HeaderId head_id, const int count,
         {
             if (++num_matches == 1)
                 curr_match = k;   // remembering location of the first matching header
-            buffer_length += header_value[k].length;
+            buffer_length += header_value[k].length();
             if (!concatenate_repeats || (num_matches >= count))
                 break;
         }
@@ -114,8 +114,8 @@ void HeaderNormalizer::normalize(const HeaderId head_id, const int count,
             data_length++;
             while (header_name_id[++curr_match] != head_id);
         }
-        int32_t growth = derive_header_content(header_value[curr_match].start,
-            header_value[curr_match].length, working);
+        int32_t growth = derive_header_content(header_value[curr_match].start(),
+            header_value[curr_match].length(), working);
         working += growth;
         data_length += growth;
     }
@@ -132,7 +132,7 @@ void HeaderNormalizer::normalize(const HeaderId head_id, const int count,
         }
     }
     delete[] temp_space;
-    result_field.set(data_length, norm_value);
+    result_field.set(data_length, norm_value, true);
     return;
 }
 
index ebccff03617d7ea67bf955736ccc416717babf9c..18d83ab59ba074abe386e6c5c6a80619cd1b6b9e 100644 (file)
@@ -55,71 +55,86 @@ HttpInspect::HttpInspect(const HttpParaList* params_) : params(params_)
 #endif
 }
 
-THREAD_LOCAL uint8_t HttpInspect::body_buffer[MAX_OCTETS];
+InspectSection HttpInspect::get_latest_is(const Packet* p)
+{
+    const HttpFlowData* const session_data =
+        (HttpFlowData*)p->flow->get_flow_data(HttpFlowData::http_flow_id);
+
+    if ((session_data == nullptr) || (session_data->latest_section == nullptr))
+        return HttpEnums::IS_NONE;
 
-THREAD_LOCAL HttpMsgSection* HttpInspect::latest_section = nullptr;
+    return session_data->latest_section->get_inspection_section();
+}
 
-HttpEnums::InspectSection HttpInspect::get_latest_is()
+SourceId HttpInspect::get_latest_src(const Packet* p)
 {
-    return (latest_section != nullptr) ?
-        latest_section->get_inspection_section() : HttpEnums::IS_NONE;
+    const HttpFlowData* const session_data =
+        (HttpFlowData*)p->flow->get_flow_data(HttpFlowData::http_flow_id);
+
+    if ((session_data == nullptr) || (session_data->latest_section == nullptr))
+        return HttpEnums::SRC__NOT_COMPUTE;
+
+    return session_data->latest_section->get_source_id();
 }
 
-bool HttpInspect::get_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuffer& b)
+bool HttpInspect::get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
 {
     switch (ibt)
     {
     case InspectionBuffer::IBT_KEY:
-        return http_get_buf(HTTP_BUFFER_URI, 0, 0, nullptr, b);
+        return http_get_buf(HTTP_BUFFER_URI, 0, 0, p, b);
     case InspectionBuffer::IBT_HEADER:
-        if (get_latest_is() == IS_TRAILER)
-            return http_get_buf(HTTP_BUFFER_TRAILER, 0, 0, nullptr, b);
+        if (get_latest_is(p) == IS_TRAILER)
+            return http_get_buf(HTTP_BUFFER_TRAILER, 0, 0, p, b);
         else
-            return http_get_buf(HTTP_BUFFER_HEADER, 0, 0, nullptr, b);
+            return http_get_buf(HTTP_BUFFER_HEADER, 0, 0, p, b);
     case InspectionBuffer::IBT_BODY:
-        return http_get_buf(HTTP_BUFFER_CLIENT_BODY, 0, 0, nullptr, b);
+        return http_get_buf(HTTP_BUFFER_CLIENT_BODY, 0, 0, p, b);
     default:
         return false;
     }
 }
 
-bool HttpInspect::http_get_buf(unsigned id, uint64_t sub_id, uint64_t form, Packet*,
+bool HttpInspect::http_get_buf(unsigned id, uint64_t sub_id, uint64_t form, Packet* p,
     InspectionBuffer& b)
 {
-    if (latest_section == nullptr)
+    const HttpFlowData* const session_data =
+        (HttpFlowData*)p->flow->get_flow_data(HttpFlowData::http_flow_id);
+
+    if ((session_data == nullptr) || (session_data->latest_section == nullptr))
         return false;
 
-    const Field& buffer = latest_section->get_classic_buffer(id, sub_id, form);
+    const Field& buffer = session_data->latest_section->get_classic_buffer(id, sub_id, form);
 
-    if (buffer.length <= 0)
+    if (buffer.length() <= 0)
         return false;
 
-    b.data = buffer.start;
-    b.len = buffer.length;
+    b.data = buffer.start();
+    b.len = buffer.length();
     return true;
 }
 
-bool HttpInspect::get_fp_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuffer& b)
+bool HttpInspect::get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b)
 {
     // Fast pattern buffers only supplied at specific times
     switch (ibt)
     {
     case InspectionBuffer::IBT_KEY:
-        if ((get_latest_is() != IS_DETECTION) || (get_latest_src() != SRC_CLIENT))
+        if ((get_latest_is(p) != IS_DETECTION) || (get_latest_src(p) != SRC_CLIENT))
             return false;
         break;
     case InspectionBuffer::IBT_HEADER:
-        if ((get_latest_is() != IS_DETECTION) && (get_latest_is() != IS_TRAILER))
+        if ((get_latest_is(p) != IS_DETECTION) && (get_latest_is(p) != IS_TRAILER))
             return false;
         break;
     case InspectionBuffer::IBT_BODY:
-        if ((get_latest_is() != IS_DETECTION) && (get_latest_is() != IS_BODY))
+        if ((get_latest_is(p) != IS_DETECTION) && (get_latest_is(p) != IS_BODY))
             return false;
         break;
     default:
         return false;
     }
-    return get_buf(ibt, nullptr, b);
+    return get_buf(ibt, p, b);
 }
 
 const Field& HttpInspect::process(const uint8_t* data, const uint16_t dsize, Flow* const flow,
@@ -130,6 +145,7 @@ const Field& HttpInspect::process(const uint8_t* data, const uint16_t dsize, Flo
 
     HttpModule::increment_peg_counts(PEG_INSPECT);
 
+    HttpMsgSection*& latest_section = session_data->latest_section;
     switch (session_data->section_type[source_id])
     {
     case SEC_REQUEST:
@@ -192,13 +208,13 @@ const Field& HttpInspect::process(const uint8_t* data, const uint16_t dsize, Flo
 
 void HttpInspect::clear(Packet* p)
 {
-    latest_section = nullptr;
-
     HttpFlowData* session_data =
         (HttpFlowData*)p->flow->get_flow_data(HttpFlowData::http_flow_id);
 
     if (session_data == nullptr)
         return;
+    session_data->latest_section = nullptr;
+
     assert((p->is_from_client()) || (p->is_from_server()));
     assert(!((p->is_from_client()) && (p->is_from_server())));
     SourceId source_id = (p->is_from_client()) ? SRC_CLIENT : SRC_SERVER;
@@ -211,7 +227,7 @@ void HttpInspect::clear(Packet* p)
 
 void HttpInspect::clear(HttpFlowData* session_data, SourceId source_id)
 {
-    latest_section = nullptr;
+    session_data->latest_section = nullptr;
 
     // If current transaction is complete then we are done with it and should reclaim the space
     if ((source_id == SRC_SERVER) && (session_data->type_expected[SRC_SERVER] == SEC_STATUS) &&
index 415cc19f839b2a52038b539c8f1e67285401038a..01cb18ed2591f7b78add449c5f3d66ccefe020ef 100644 (file)
@@ -37,14 +37,12 @@ class HttpApi;
 class HttpInspect : public Inspector
 {
 public:
-    static THREAD_LOCAL uint8_t body_buffer[HttpEnums::MAX_OCTETS];
-
     HttpInspect(const HttpParaList* params_);
     ~HttpInspect() { delete params; }
 
-    bool get_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuffer& b) override;
-    bool http_get_buf(unsigned id, uint64_t sub_id, uint64_t form, Packet*, InspectionBuffer& b);
-    bool get_fp_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuffer& b) override;
+    bool get_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b) override;
+    bool http_get_buf(unsigned id, uint64_t sub_id, uint64_t form, Packet* p, InspectionBuffer& b);
+    bool get_fp_buf(InspectionBuffer::Type ibt, Packet* p, InspectionBuffer& b) override;
     bool configure(SnortConfig*) override { return true; }
     void show(SnortConfig*) override { LogMessage("HttpInspect\n"); }
     void eval(Packet*) override { }
@@ -55,7 +53,7 @@ public:
     {
         return new HttpStreamSplitter(is_client_to_server, this);
     }
-    static HttpEnums::InspectSection get_latest_is();
+    static HttpEnums::InspectSection get_latest_is(const Packet* p);
 
 private:
     friend HttpApi;
@@ -64,10 +62,7 @@ private:
     const Field& process(const uint8_t* data, const uint16_t dsize, Flow* const flow,
         HttpEnums::SourceId source_id_, bool buf_owner) const;
     void clear(HttpFlowData* session_data, HttpEnums::SourceId source_id);
-    static HttpEnums::SourceId get_latest_src() { return (latest_section != nullptr) ?
-        latest_section->get_source_id() : HttpEnums::SRC__NOT_COMPUTE; }
-
-    static THREAD_LOCAL HttpMsgSection* latest_section;
+    static HttpEnums::SourceId get_latest_src(const Packet* p);
 
     const HttpParaList* const params;
 };
index ba51b1eebea61162af0299b6f4225e9c81869baa..f65525a5c775a7fa4f17005301bc0b34c6a583b8 100644 (file)
@@ -60,20 +60,20 @@ HttpJsNorm::~HttpJsNorm()
     delete htmltype_search_mpse;
 }
 
-void HttpJsNorm::normalize(const Field& input, Field& output, bool& js_norm_alloc,
-    HttpInfractions& infractions, HttpEventGen& events) const
+void HttpJsNorm::normalize(const Field& input, Field& output, HttpInfractions& infractions,
+    HttpEventGen& events) const
 {
     bool js_present = false;
     int index = 0;
-    const char* ptr = (const char*)input.start;
-    const char* const end = ptr + input.length;
+    const char* ptr = (const char*)input.start();
+    const char* const end = ptr + input.length();
 
     JSState js;
     js.allowed_spaces = max_javascript_whitespaces;
     js.allowed_levels = MAX_ALLOWED_OBFUSCATION;
     js.alerts = 0;
 
-    uint8_t* buffer = new uint8_t[input.length];
+    uint8_t* buffer = new uint8_t[input.length()];
 
     while (ptr < end)
     {
@@ -119,9 +119,9 @@ void HttpJsNorm::normalize(const Field& input, Field& output, bool& js_norm_allo
             // Save before the <script> begins
             if (js_start > ptr)
             {
-                if ((js_start - ptr) > (input.length - index))
+                if ((js_start - ptr) > (input.length() - index))
                     break;
-                memmove_s(buffer + index, input.length - index, ptr, js_start - ptr);
+                memmove_s(buffer + index, input.length() - index, ptr, js_start - ptr);
                 index += js_start - ptr;
             }
 
@@ -131,7 +131,7 @@ void HttpJsNorm::normalize(const Field& input, Field& output, bool& js_norm_allo
 
             // FIXIT-L need to fix this library so we don't have to cast away const here.
             JSNormalizeDecode((char*)js_start, (uint16_t)(end-js_start), (char*)buffer+index,
-                (uint16_t)(input.length - index), (char**)&ptr, &bytes_copied, &js,
+                (uint16_t)(input.length() - index), (char**)&ptr, &bytes_copied, &js,
                 uri_param.iis_unicode ? uri_param.unicode_map : nullptr);
             index += bytes_copied;
         }
@@ -141,9 +141,9 @@ void HttpJsNorm::normalize(const Field& input, Field& output, bool& js_norm_allo
 
     if (js_present)
     {
-        if ((ptr < end) && ((input.length - index) >= (end - ptr)))
+        if ((ptr < end) && ((input.length() - index) >= (end - ptr)))
         {
-            memmove_s(buffer + index, input.length - index, ptr, end - ptr); index += end - ptr;
+            memmove_s(buffer + index, input.length() - index, ptr, end - ptr); index += end - ptr;
         }
         if (js.alerts)
         {
@@ -163,8 +163,7 @@ void HttpJsNorm::normalize(const Field& input, Field& output, bool& js_norm_allo
                 events.create_event(EVENT_MIXED_ENCODINGS);
             }
         }
-        output.set(index, buffer);
-        js_norm_alloc = true;
+        output.set(index, buffer, true);
     }
     else
     {
index 41e523e60d79085dac543537443b6a4da53e5ecc..0b8ed08902450fd825b061702a2b8f82cecb0405 100644 (file)
@@ -38,8 +38,8 @@ class HttpJsNorm
 public:
     HttpJsNorm(int max_javascript_whitespaces_, const HttpParaList::UriParam& uri_param_);
     ~HttpJsNorm();
-    void normalize(const Field& input, Field& output, bool& js_norm_alloc,
-        HttpInfractions& infractions, HttpEventGen& events) const;
+    void normalize(const Field& input, Field& output, HttpInfractions& infractions,
+        HttpEventGen& events) const;
 private:
     enum JsSearchId { JS_JAVASCRIPT };
     enum HtmlSearchId { HTML_JS, HTML_EMA, HTML_VB };
index 872857a92dd3a94eb76718b8c8ab1ddc39c36430..d0353c9653f0498783dc231a1c58ff962b70d99b 100644 (file)
@@ -44,32 +44,20 @@ HttpMsgBody::HttpMsgBody(const uint8_t* buffer, const uint16_t buf_size,
     transaction->set_body(this);
 }
 
-HttpMsgBody::~HttpMsgBody()
-{
-    if (classic_client_body_alloc)
-        classic_client_body.delete_buffer();
-
-    if (decoded_body_alloc)
-        decoded_body.delete_buffer();
-
-    if (js_norm_body_alloc)
-        js_norm_body.delete_buffer();
-}
-
 void HttpMsgBody::analyze()
 {
-    do_utf_decoding(msg_text, decoded_body, decoded_body_alloc);
+    do_utf_decoding(msg_text, decoded_body);
 
     if (session_data->detect_depth_remaining[source_id] > 0)
     {
-        do_js_normalization(decoded_body, js_norm_body, js_norm_body_alloc);
+        do_js_normalization(decoded_body, js_norm_body);
         const int32_t detect_length =
-            (js_norm_body.length <= session_data->detect_depth_remaining[source_id]) ?
-            js_norm_body.length : session_data->detect_depth_remaining[source_id];
-        detect_data.set(detect_length, js_norm_body.start);
+            (js_norm_body.length() <= session_data->detect_depth_remaining[source_id]) ?
+            js_norm_body.length() : session_data->detect_depth_remaining[source_id];
+        detect_data.set(detect_length, js_norm_body.start());
         session_data->detect_depth_remaining[source_id] -= detect_length;
         // Always set file data. File processing will later set a new value in some cases.
-        set_file_data(const_cast<uint8_t*>(detect_data.start), (unsigned)detect_data.length);
+        set_file_data(const_cast<uint8_t*>(detect_data.start()), (unsigned)detect_data.length());
     }
 
     if (session_data->file_depth_remaining[source_id] > 0)
@@ -77,10 +65,10 @@ void HttpMsgBody::analyze()
         do_file_processing(decoded_body);
     }
 
-    body_octets += msg_text.length;
+    body_octets += msg_text.length();
 }
 
-void HttpMsgBody::do_utf_decoding(const Field& input, Field& output, bool& decoded_alloc)
+void HttpMsgBody::do_utf_decoding(const Field& input, Field& output)
 {
     if (!params->normalize_utf || source_id == SRC_CLIENT)
     {
@@ -92,9 +80,9 @@ void HttpMsgBody::do_utf_decoding(const Field& input, Field& output, bool& decod
     {
         int bytes_copied;
         bool decoded;
-        uint8_t* buffer = new uint8_t[input.length];
-        decoded = session_data->utf_state->decode_utf((const char*)input.start, input.length,
-                            (char*)buffer, input.length, &bytes_copied);
+        uint8_t* buffer = new uint8_t[input.length()];
+        decoded = session_data->utf_state->decode_utf((const char*)input.start(), input.length(),
+                            (char*)buffer, input.length(), &bytes_copied);
         if (!decoded)
         {
             delete[] buffer;
@@ -104,8 +92,7 @@ void HttpMsgBody::do_utf_decoding(const Field& input, Field& output, bool& decod
         }
         else if (bytes_copied > 0)
         {
-            output.set(bytes_copied, buffer);
-            decoded_alloc = true;
+            output.set(bytes_copied, buffer, true);
         }
         else
         {
@@ -118,7 +105,7 @@ void HttpMsgBody::do_utf_decoding(const Field& input, Field& output, bool& decod
         output.set(input);
 }
 
-void HttpMsgBody::do_js_normalization(const Field& input, Field& output, bool& js_norm_alloc)
+void HttpMsgBody::do_js_normalization(const Field& input, Field& output)
 {
     if (!params->js_norm_param.normalize_javascript || source_id == SRC_CLIENT)
     {
@@ -126,7 +113,7 @@ void HttpMsgBody::do_js_normalization(const Field& input, Field& output, bool& j
         return;
     }
 
-    params->js_norm_param.js_norm->normalize(input, output, js_norm_alloc, infractions, events);
+    params->js_norm_param.js_norm->normalize(input, output, infractions, events);
 }
 
 void HttpMsgBody::do_file_processing(Field& file_data)
@@ -142,13 +129,13 @@ void HttpMsgBody::do_file_processing(Field& file_data)
     else file_position = SNORT_FILE_MIDDLE;
 
     // Chunked body with nothing but the zero length chunk?
-    if (front && (file_data.length == 0))
+    if (front && (file_data.length() == 0))
     {
         return;
     }
 
-    const int32_t fp_length = (file_data.length <= session_data->file_depth_remaining[source_id]) ?
-        file_data.length : session_data->file_depth_remaining[source_id];
+    const int32_t fp_length = (file_data.length() <= session_data->file_depth_remaining[source_id])
+        ? file_data.length() : session_data->file_depth_remaining[source_id];
 
     if (!session_data->mime_state[source_id])
     {
@@ -164,7 +151,7 @@ void HttpMsgBody::do_file_processing(Field& file_data)
             file_index = request->get_http_uri()->get_file_proc_hash();
         }
 
-        if (file_flows->file_process(file_data.start, fp_length,
+        if (file_flows->file_process(file_data.start(), fp_length,
             file_position, !download, file_index))
         {
             session_data->file_depth_remaining[source_id] -= fp_length;
@@ -175,9 +162,9 @@ void HttpMsgBody::do_file_processing(Field& file_data)
                 if (request != nullptr)
                 {
                     const Field& tranaction_uri = request->get_uri_norm_classic();
-                    if (tranaction_uri.length > 0)
+                    if (tranaction_uri.length() > 0)
                     {
-                        file_flows->set_file_name(tranaction_uri.start, tranaction_uri.length);
+                        file_flows->set_file_name(tranaction_uri.start(), tranaction_uri.length());
                     }
                 }
             }
@@ -190,7 +177,7 @@ void HttpMsgBody::do_file_processing(Field& file_data)
     }
     else
     {
-        session_data->mime_state[source_id]->process_mime_data(flow, file_data.start,
+        session_data->mime_state[source_id]->process_mime_data(flow, file_data.start(),
             fp_length, true, SNORT_FILE_POSITION_UNKNOWN);
 
         session_data->file_depth_remaining[source_id] -= fp_length;
@@ -204,8 +191,7 @@ void HttpMsgBody::do_file_processing(Field& file_data)
 
 const Field& HttpMsgBody::get_classic_client_body()
 {
-    return classic_normalize(detect_data, classic_client_body, classic_client_body_alloc,
-        params->uri_param);
+    return classic_normalize(detect_data, classic_client_body, params->uri_param);
 }
 
 #ifdef REG_TEST
index 9877530d511cbb52755dc8afe3857e4c9205df61..caf2112c05417d3779192e1c97eea64702eedda4 100644 (file)
@@ -30,7 +30,7 @@
 class HttpMsgBody : public HttpMsgSection
 {
 public:
-    virtual ~HttpMsgBody();
+    virtual ~HttpMsgBody() = default;
     void analyze() override;
     const Field& get_detect_buf() const override { return detect_data; }
     HttpEnums::InspectSection get_inspection_section() const override
@@ -50,17 +50,14 @@ protected:
 
 private:
     void do_file_processing(Field& file_data);
-    void do_utf_decoding(const Field& input, Field& output, bool& decoded_alloc);
-    void do_js_normalization(const Field& input, Field& output, bool& js_norm_alloc);
+    void do_utf_decoding(const Field& input, Field& output);
+    void do_js_normalization(const Field& input, Field& output);
 
     Field detect_data;
     const bool detection_section;
     Field classic_client_body;   // URI normalization applied
-    bool classic_client_body_alloc = false;
     Field decoded_body;
-    bool decoded_body_alloc = false;
     Field js_norm_body;
-    bool js_norm_body_alloc = false;
 };
 
 #endif
index 14a866e5806c8fb71dea0b89b85171159a8d3ac8..89287a5f5ce40fe83c836ddc7e399e8ead575bb8 100644 (file)
@@ -39,15 +39,8 @@ HttpMsgHeadShared::~HttpMsgHeadShared()
     {
         NormalizedHeader* temp_ptr = list_ptr;
         list_ptr = list_ptr->next;
-        temp_ptr->norm.delete_buffer();
         delete temp_ptr;
     }
-    if (classic_raw_header_alloc)
-        classic_raw_header.delete_buffer();
-    if (classic_norm_header_alloc)
-        classic_norm_header.delete_buffer();
-    if (classic_norm_cookie_alloc)
-        classic_norm_cookie.delete_buffer();
 }
 
 // All the header processing that is done for every message (i.e. not just-in-time) is done here.
@@ -96,24 +89,25 @@ void HttpMsgHeadShared::parse_header_block()
     // session_data->num_head_lines is computed without consideration of wrapping and may overstate
     // actual number of headers. Rely on num_headers which is calculated correctly.
     header_line = new Field[session_data->num_head_lines[source_id]];
-    while (bytes_used < msg_text.length)
+    while (bytes_used < msg_text.length())
     {
         assert(num_headers < session_data->num_head_lines[source_id]);
-        header_line[num_headers].start = msg_text.start + bytes_used;
-        header_line[num_headers].length = find_header_end(header_line[num_headers].start,
-            msg_text.length - bytes_used, num_seps);
-        if (header_line[num_headers].length > MAX_HEADER_LENGTH)
+        header_line[num_headers].set(
+            find_header_end(msg_text.start() + bytes_used, msg_text.length() - bytes_used,
+                num_seps),
+            msg_text.start() + bytes_used);
+        if (header_line[num_headers].length() > MAX_HEADER_LENGTH)
         {
             infractions += INF_TOO_LONG_HEADER;
             events.create_event(EVENT_LONG_HDR);
         }
-        bytes_used += header_line[num_headers++].length + num_seps;
+        bytes_used += header_line[num_headers++].length() + num_seps;
         if (num_headers >= MAX_HEADERS)
         {
             break;
         }
     }
-    if (bytes_used < msg_text.length)
+    if (bytes_used < msg_text.length())
     {
         // FIXIT-M eventually need to separate max header alert from internal maximum
         infractions += INF_TOO_MANY_HEADERS;
@@ -166,17 +160,16 @@ void HttpMsgHeadShared::parse_header_lines()
     int colon;
     for (int k=0; k < num_headers; k++)
     {
-        for (colon=0; colon < header_line[k].length; colon++)
+        for (colon=0; colon < header_line[k].length(); colon++)
         {
-            if (header_line[k].start[colon] == ':')
+            if (header_line[k].start()[colon] == ':')
                 break;
         }
-        if (colon < header_line[k].length)
+        if (colon < header_line[k].length())
         {
-            header_name[k].start = header_line[k].start;
-            header_name[k].length = colon;
-            header_value[k].start = header_line[k].start + colon + 1;
-            header_value[k].length = header_line[k].length - colon - 1;
+            header_name[k].set(colon, header_line[k].start());
+            header_value[k].set(header_line[k].length() - colon - 1,
+                                header_line[k].start() + colon + 1);
         }
         else
         {
@@ -190,8 +183,8 @@ void HttpMsgHeadShared::parse_header_lines()
 
 void HttpMsgHeadShared::derive_header_name_id(int index)
 {
-    const int32_t& length = header_name[index].length;
-    const uint8_t*& buffer = header_name[index].start;
+    const int32_t length = header_name[index].length();
+    const uint8_t* buffer = header_name[index].start();
 
     if (length <= 0)
     {
@@ -237,7 +230,7 @@ int HttpMsgHeadShared::get_header_count(HeaderId header_id) const
 
 const Field& HttpMsgHeadShared::get_classic_raw_header()
 {
-    if (classic_raw_header.length != STAT_NOT_COMPUTE)
+    if (classic_raw_header.length() != STAT_NOT_COMPUTE)
         return classic_raw_header;
     const HeaderId cookie_head = (source_id == SRC_CLIENT) ? HEAD_COOKIE : HEAD_SET_COOKIE;
     if (!headers_present[cookie_head])
@@ -256,8 +249,8 @@ const Field& HttpMsgHeadShared::get_classic_raw_header()
         // All header line Fields point into the buffer holding the entire message section.
         // Calculation must account for separators between header lines, but there are none
         // following the final header line.
-        const int32_t head_len = (k == num_headers-1) ? header_line[k].length :
-            header_line[k+1].start - header_line[k].start;
+        const int32_t head_len = (k == num_headers-1) ? header_line[k].length() :
+            header_line[k+1].start() - header_line[k].start();
         length += head_len;
     }
 
@@ -268,22 +261,20 @@ const Field& HttpMsgHeadShared::get_classic_raw_header()
     {
         if (header_name_id[k] == cookie_head)
             continue;
-        const int32_t head_len = (k == num_headers-1) ? header_line[k].length :
-            header_line[k+1].start - header_line[k].start;
-        memcpy(buffer + current, header_line[k].start, head_len);
+        const int32_t head_len = (k == num_headers-1) ? header_line[k].length() :
+            header_line[k+1].start() - header_line[k].start();
+        memcpy(buffer + current, header_line[k].start(), head_len);
         current += head_len;
     }
     assert(current == length);
 
-    classic_raw_header.set(length, buffer);
-    classic_raw_header_alloc = true;
+    classic_raw_header.set(length, buffer, true);
     return classic_raw_header;
 }
 
 const Field& HttpMsgHeadShared::get_classic_norm_header()
 {
-    return classic_normalize(get_classic_raw_header(), classic_norm_header,
-        classic_norm_header_alloc, params->uri_param);
+    return classic_normalize(get_classic_raw_header(), classic_norm_header, params->uri_param);
 }
 
 const Field& HttpMsgHeadShared::get_classic_raw_cookie()
@@ -294,8 +285,7 @@ const Field& HttpMsgHeadShared::get_classic_raw_cookie()
 
 const Field& HttpMsgHeadShared::get_classic_norm_cookie()
 {
-    return classic_normalize(get_classic_raw_cookie(), classic_norm_cookie,
-        classic_norm_cookie_alloc, params->uri_param);
+    return classic_normalize(get_classic_raw_cookie(), classic_norm_cookie, params->uri_param);
 }
 
 const Field& HttpMsgHeadShared::get_header_value_raw(HeaderId header_id) const
@@ -337,7 +327,7 @@ void HttpMsgHeadShared::print_headers(FILE* output)
     }
     for (int k=1; k <= HEAD__MAX_VALUE-1; k++)
     {
-        if (get_header_value_norm((HeaderId)k).length != STAT_NO_SOURCE)
+        if (get_header_value_norm((HeaderId)k).length() != STAT_NO_SOURCE)
         {
             snprintf(title_buf, sizeof(title_buf), "Normalized header %d", k);
             get_header_value_norm((HeaderId)k).print(output, title_buf);
index 7300aadffb290a6fa9b6df31d8c55d56446e237d..6153dee6e3c7376b6693f3b8644a4cfb30167268 100644 (file)
@@ -100,11 +100,8 @@ private:
     Field* header_value = nullptr;
 
     Field classic_raw_header;    // raw headers with cookies spliced out
-    bool classic_raw_header_alloc = false;
     Field classic_norm_header;   // URI normalization applied
-    bool classic_norm_header_alloc = false;
     Field classic_norm_cookie;   // URI normalization applied to concatenated cookie values
-    bool classic_norm_cookie_alloc = false;
 
     struct NormalizedHeader
     {
index 164771a0fe4b21cdd1979a90c23b0d4151befa2a..f48f83d162228a2e41676f7e447e25b6eaca1b29 100644 (file)
 int32_t HttpMsgHeadShared::get_next_code(const Field& field, int32_t& offset,
     const StrCode table[])
 {
-    assert(field.length > 0);
-    const uint8_t* start = field.start + offset;
+    assert(field.length() > 0);
+    const uint8_t* start = field.start() + offset;
     int32_t length;
-    for (length = 0; (offset+length < field.length) && (*(start+length) != ','); length++);
+    for (length = 0; (offset+length < field.length()) && (*(start+length) != ','); length++);
     offset += length + 1;
     return str_to_code(start, length, table);
 }
@@ -34,14 +34,14 @@ int32_t HttpMsgHeadShared::get_next_code(const Field& field, int32_t& offset,
 // Case insensitive search for the substring "boundary="
 bool HttpMsgHeadShared::boundary_present(const Field& field)
 {
-    assert(field.length > 0);
+    assert(field.length() > 0);
 
     const char* const BOUNDARY = "boundary=";
     const int BOUNDARY_LEN = 9;
 
-    for (int k = 0; k + BOUNDARY_LEN <= field.length; k++)
+    for (int k = 0; k + BOUNDARY_LEN <= field.length(); k++)
     {
-        if (strncasecmp(BOUNDARY, (const char*)(field.start + k), BOUNDARY_LEN) == 0)
+        if (strncasecmp(BOUNDARY, (const char*)(field.start() + k), BOUNDARY_LEN) == 0)
             return true;
     }
     return false;
index 3b795fc278264be3e5c2734193d82161f4143d86..5adeda03378ef6edf17816d06775d0d65ae3da67 100644 (file)
@@ -111,7 +111,7 @@ void HttpMsgHeader::update_flow()
     }
 
     // If there is a Transfer-Encoding header, see if the last of the encoded values is "chunked".
-    if (get_header_value_norm(HEAD_TRANSFER_ENCODING).length > 0)
+    if (get_header_value_norm(HEAD_TRANSFER_ENCODING).length() > 0)
     {
         if (chunked_before_end(get_header_value_norm(HEAD_TRANSFER_ENCODING)))
         {
@@ -136,7 +136,7 @@ void HttpMsgHeader::update_flow()
 
     // else because Transfer-Encoding header negates Content-Length header even if something was
     // wrong with Transfer-Encoding header.
-    else if (get_header_value_norm(HEAD_CONTENT_LENGTH).length > 0)
+    else if (get_header_value_norm(HEAD_CONTENT_LENGTH).length() > 0)
     {
         const int64_t content_length =
             norm_decimal_integer(get_header_value_norm(HEAD_CONTENT_LENGTH));
@@ -226,7 +226,7 @@ void HttpMsgHeader::setup_file_processing()
         if (source_id == SRC_CLIENT)
         {
             const Field& content_type = get_header_value_raw(HEAD_CONTENT_TYPE);
-            if (content_type.length > 0)
+            if (content_type.length() > 0)
             {
                 if (boundary_present(content_type))
                 {
@@ -238,7 +238,7 @@ void HttpMsgHeader::setup_file_processing()
                     // This interface is a leftover from when OHI pushed whole messages through
                     // this interface.
                     session_data->mime_state[source_id]->process_mime_data(flow,
-                        content_type.start, content_type.length, true,
+                        content_type.start(), content_type.length(), true,
                         SNORT_FILE_POSITION_UNKNOWN);
                     session_data->mime_state[source_id]->process_mime_data(flow,
                         (const uint8_t*)"\r\n", 2, true, SNORT_FILE_POSITION_UNKNOWN);
@@ -276,7 +276,7 @@ void HttpMsgHeader::setup_decompression()
 
     const Field& norm_content_encoding = get_header_value_norm(HEAD_CONTENT_ENCODING);
     int32_t cont_offset = 0;
-    while (norm_content_encoding.length > cont_offset)
+    while (norm_content_encoding.length() > cont_offset)
     {
         const Contentcoding content_code = (Contentcoding)get_next_code(norm_content_encoding,
             cont_offset, HttpMsgHeadShared::content_code_list);
@@ -313,7 +313,7 @@ void HttpMsgHeader::setup_decompression()
 
     const Field& norm_transfer_encoding = get_header_value_norm(HEAD_TRANSFER_ENCODING);
     int32_t trans_offset = 0;
-    while (norm_transfer_encoding.length > trans_offset)
+    while (norm_transfer_encoding.length() > trans_offset)
     {
         const Transcoding transfer_code = (Transcoding)get_next_code(norm_transfer_encoding,
             trans_offset, HttpMsgHeadShared::trans_code_list);
@@ -374,15 +374,16 @@ void HttpMsgHeader::setup_utf_decoding()
         return;
 
     const Field& norm_content_type = get_header_value_norm(HEAD_CONTENT_TYPE);
-    if (norm_content_type.length <= 0)
+    if (norm_content_type.length() <= 0)
         return;
 
     get_last_token(norm_content_type, last_token, ';');
 
     // No semicolon in the Content-Type header
-    if ( last_token.length == norm_content_type.length )
+    if ( last_token.length() == norm_content_type.length() )
     {
-        if( SnortStrnStr((const char*)norm_content_type.start, norm_content_type.length, "text") )
+        if (SnortStrnStr((const char*)norm_content_type.start(), norm_content_type.length(),
+            "text"))
         {
             charset_code = CHARSET_UNKNOWN;
         }
@@ -391,12 +392,13 @@ void HttpMsgHeader::setup_utf_decoding()
     }
     else
     {
-
-        charset_code = (CharsetCode)str_to_code(last_token.start, last_token.length, HttpMsgHeadShared::charset_code_list);
+        charset_code = (CharsetCode)str_to_code(last_token.start(), last_token.length(),
+            HttpMsgHeadShared::charset_code_list);
 
         if( charset_code == CHARSET_OTHER )
         {
-            charset_code = (CharsetCode)substr_to_code(last_token.start, last_token.length, HttpMsgHeadShared::charset_code_opt_list);
+            charset_code = (CharsetCode)substr_to_code(last_token.start(), last_token.length(),
+                HttpMsgHeadShared::charset_code_opt_list);
 
             if ( charset_code != CHARSET_UNKNOWN )
                 return;
index cd895e6c3eb958ef4eb163ddefb71c83ceb5c618..75b0b260402f60836b0d42124f1dc99b2582efff 100644 (file)
@@ -41,14 +41,14 @@ HttpMsgRequest::HttpMsgRequest(const uint8_t* buffer, const uint16_t buf_size,
 void HttpMsgRequest::parse_start_line()
 {
     // Check the version field
-    if ((start_line.length < 10) || !is_sp_tab[start_line.start[start_line.length-9]] ||
-         memcmp(start_line.start + start_line.length - 8, "HTTP/", 5))
+    if ((start_line.length() < 10) || !is_sp_tab[start_line.start()[start_line.length()-9]] ||
+         memcmp(start_line.start() + start_line.length() - 8, "HTTP/", 5))
     {
         if (!handle_zero_nine())
         {
             // Just a plain old bad request
             infractions += INF_BAD_REQ_LINE;
-            events.generate_misformatted_http(start_line.start, start_line.length);
+            events.generate_misformatted_http(start_line.start(), start_line.length());
         }
         return;
     }
@@ -59,20 +59,19 @@ void HttpMsgRequest::parse_start_line()
     // octets 2-81. The following algorithm uses those assumptions.
 
     int32_t first_space; // first whitespace in request line
-    for (first_space = 1; !is_sp_tab[start_line.start[first_space]]; first_space++);
+    for (first_space = 1; !is_sp_tab[start_line.start()[first_space]]; first_space++);
 
     int32_t first_end; // last whitespace in first clump of whitespace
-    for (first_end = first_space+1; is_sp_tab[start_line.start[first_end]]; first_end++);
+    for (first_end = first_space+1; is_sp_tab[start_line.start()[first_end]]; first_end++);
     first_end--;
 
     int32_t last_begin; // first whitespace in clump of whitespace before version
-    for (last_begin = start_line.length - 10; is_sp_tab[start_line.start[last_begin]];
+    for (last_begin = start_line.length() - 10; is_sp_tab[start_line.start()[last_begin]];
         last_begin--);
     last_begin++;
 
-    method.start = start_line.start;
-    method.length = first_space;
-    method_id = (MethodId)str_to_code(method.start, method.length, method_list);
+    method.set(first_space, start_line.start());
+    method_id = (MethodId)str_to_code(method.start(), method.length(), method_list);
 
     switch (method_id)
     {
@@ -87,13 +86,12 @@ void HttpMsgRequest::parse_start_line()
     default: HttpModule::increment_peg_counts(PEG_OTHER_METHOD); break;
     }
 
-    version.start = start_line.start + (start_line.length - 8);
-    version.length = 8;
+    version.set(8, start_line.start() + (start_line.length() - 8));
     derive_version_id();
 
     if (first_end < last_begin)
     {
-        uri = new HttpUri(start_line.start + first_end + 1, last_begin - first_end - 1,
+        uri = new HttpUri(start_line.start() + first_end + 1, last_begin - first_end - 1,
             method_id, params->uri_param, infractions, events);
     }
     else
@@ -106,26 +104,27 @@ void HttpMsgRequest::parse_start_line()
 bool HttpMsgRequest::handle_zero_nine()
 {
     // 0.9 request line is supposed to be "GET <URI>\r\n"
-    if ((start_line.length >= 3) &&
-        !memcmp(start_line.start, "GET", 3) &&
-        ((start_line.length == 3) || is_sp_tab[start_line.start[3]]))
+    if ((start_line.length() >= 3) &&
+        !memcmp(start_line.start(), "GET", 3) &&
+        ((start_line.length() == 3) || is_sp_tab[start_line.start()[3]]))
     {
         infractions += INF_ZERO_NINE_REQ;
         events.create_event(EVENT_SIMPLE_REQUEST);
-        method.set(3, start_line.start);
+        method.set(3, start_line.start());
         method_id = METH_GET;
         version_id = VERS_0_9;
 
         // Eliminate the clump of whitespace following GET and possible clump of whitespace at the
         // end and whatever is left is assumed to be the URI
         int32_t uri_begin;
-        for (uri_begin = 4; (uri_begin < start_line.length) &&
-            is_sp_tab[start_line.start[uri_begin]]; uri_begin++);
-        if (uri_begin < start_line.length)
+        for (uri_begin = 4; (uri_begin < start_line.length()) &&
+            is_sp_tab[start_line.start()[uri_begin]]; uri_begin++);
+        if (uri_begin < start_line.length())
         {
             int32_t uri_end;
-            for (uri_end = start_line.length - 1; is_sp_tab[start_line.start[uri_end]]; uri_end--);
-            uri = new HttpUri(start_line.start + uri_begin, uri_end - uri_begin + 1, method_id,
+            for (uri_end = start_line.length() - 1; is_sp_tab[start_line.start()[uri_end]];
+                uri_end--);
+            uri = new HttpUri(start_line.start() + uri_begin, uri_end - uri_begin + 1, method_id,
                 params->uri_param, infractions, events);
         }
         else
@@ -163,8 +162,8 @@ void HttpMsgRequest::gen_events()
 
     const bool zero_nine = infractions & INF_ZERO_NINE_REQ;
 
-    if ((start_line.start[method.length] == '\t') ||
-        (!zero_nine && (start_line.start[start_line.length - 9] == '\t')))
+    if ((start_line.start()[method.length()] == '\t') ||
+        (!zero_nine && (start_line.start()[start_line.length() - 9] == '\t')))
     {
         infractions += INF_REQUEST_TAB;
         events.create_event(EVENT_APACHE_WS);
@@ -172,16 +171,16 @@ void HttpMsgRequest::gen_events()
 
     // Look for white space issues in and around the URI.
     // Supposed to be <method><space><URI><space><version> or 0.9 format GET<space><URI>
-    const int32_t version_start = !zero_nine ? start_line.length - 9 : start_line.length;
-    for (int32_t k = method.length + 1; k < version_start; k++)
+    const int32_t version_start = !zero_nine ? start_line.length() - 9 : start_line.length();
+    for (int32_t k = method.length() + 1; k < version_start; k++)
     {
-        if (is_sp_tab[start_line.start[k]])
+        if (is_sp_tab[start_line.start()[k]])
         {
-            if (uri && (uri->get_uri().start <= start_line.start + k) &&
-                       (start_line.start + k < uri->get_uri().start + uri->get_uri().length))
+            if (uri && (uri->get_uri().start() <= start_line.start() + k) &&
+                       (start_line.start() + k < uri->get_uri().start() + uri->get_uri().length()))
             {
                 // white space inside the URI is not allowed
-                if (start_line.start[k] == ' ')
+                if (start_line.start()[k] == ' ')
                 {
                     infractions += INF_URI_SPACE;
                     events.create_event(EVENT_UNESCAPED_SPACE_URI);
@@ -192,7 +191,7 @@ void HttpMsgRequest::gen_events()
                 // extra white space before or after the URI
                 infractions += INF_REQUEST_WS;
                 events.create_event(EVENT_IMPROPER_WS);
-                if (start_line.start[k] == '\t')
+                if (start_line.start()[k] == '\t')
                 {
                     // which is also a tab
                     infractions += INF_REQUEST_TAB;
index 4610ba750acbcc434f0abb4dad3fa41a2443e7f6..5ab442d1cbc726acb37c63b721e07d27945e6a39 100644 (file)
@@ -37,7 +37,7 @@ using namespace HttpEnums;
 HttpMsgSection::HttpMsgSection(const uint8_t* buffer, const uint16_t buf_size,
        HttpFlowData* session_data_, SourceId source_id_, bool buf_owner, Flow* flow_,
        const HttpParaList* params_) :
-    msg_text(buf_size, buffer),
+    msg_text(buf_size, buffer, buf_owner),
     session_data(session_data_),
     source_id(source_id_),
     flow(flow_),
@@ -49,8 +49,7 @@ HttpMsgSection::HttpMsgSection(const uint8_t* buffer, const uint16_t buf_size,
     events(session_data->events[source_id]),
     version_id(session_data->version_id[source_id]),
     method_id((source_id == SRC_CLIENT) ? session_data->method_id : METH__NOT_PRESENT),
-    status_code_num((source_id == SRC_SERVER) ? session_data->status_code_num : STAT_NOT_PRESENT),
-    delete_msg_on_destruct(buf_owner)
+    status_code_num((source_id == SRC_SERVER) ? session_data->status_code_num : STAT_NOT_PRESENT)
 {
     assert((source_id == SRC_CLIENT) || (source_id == SRC_SERVER));
 }
@@ -82,20 +81,18 @@ void HttpMsgSection::update_depth() const
     }
 }
 
-const Field& HttpMsgSection::classic_normalize(const Field& raw, Field& norm, bool& norm_alloc,
+const Field& HttpMsgSection::classic_normalize(const Field& raw, Field& norm,
     const HttpParaList::UriParam& uri_param)
 {
-    if (norm.length != STAT_NOT_COMPUTE)
+    if (norm.length() != STAT_NOT_COMPUTE)
         return norm;
 
-    if ((raw.length <= 0) || !UriNormalizer::classic_need_norm(raw, true, uri_param))
+    if ((raw.length() <= 0) || !UriNormalizer::classic_need_norm(raw, true, uri_param))
     {
         norm.set(raw);
         return norm;
     }
-    uint8_t* buffer = new uint8_t[raw.length + UriNormalizer::URI_NORM_EXPANSION];
-    UriNormalizer::classic_normalize(raw, norm, buffer, uri_param);
-    norm_alloc = true;
+    UriNormalizer::classic_normalize(raw, norm, uri_param);
     return norm;
 }
 
index 510c4400e50f49ba2298785006b48f3a4f9476e6..4eb17059aee3614d5c34ea226561b18012d52b98 100644 (file)
@@ -35,7 +35,7 @@
 class HttpMsgSection
 {
 public:
-    virtual ~HttpMsgSection() { if (delete_msg_on_destruct) delete[] msg_text.start; }
+    virtual ~HttpMsgSection() = default;
     virtual HttpEnums::InspectSection get_inspection_section() const
         { return HttpEnums::IS_NONE; }
     HttpEnums::SourceId get_source_id() { return source_id; }
@@ -86,16 +86,13 @@ protected:
 
     // Convenience methods shared by multiple subclasses
     void update_depth() const;
-    static const Field& classic_normalize(const Field& raw, Field& norm, bool& norm_alloc,
+    static const Field& classic_normalize(const Field& raw, Field& norm,
         const HttpParaList::UriParam& uri_param);
 #ifdef REG_TEST
     void print_section_title(FILE* output, const char* title) const;
     void print_section_wrapup(FILE* output) const;
     void print_peg_counts(FILE* output) const;
 #endif
-
-private:
-    const bool delete_msg_on_destruct;
 };
 
 #endif
index 1bec865e8117873ae70d66235d5ae7a29ecead06..2742cb5aa620ae7638b043472c960221a19dffbb 100644 (file)
@@ -28,33 +28,32 @@ using namespace HttpEnums;
 
 void HttpMsgStart::analyze()
 {
-    start_line.start = msg_text.start;
-    start_line.length = msg_text.length;
+    start_line.set(msg_text);
     parse_start_line();
     gen_events();
 }
 
 void HttpMsgStart::derive_version_id()
 {
-    if (version.start[6] != '.')
+    if (version.start()[6] != '.')
     {
         version_id = VERS__PROBLEMATIC;
         infractions += INF_BAD_VERSION;
         events.create_event(EVENT_BAD_VERS);
     }
-    else if ((version.start[5] == '1') && (version.start[7] == '1'))
+    else if ((version.start()[5] == '1') && (version.start()[7] == '1'))
     {
         version_id = VERS_1_1;
     }
-    else if ((version.start[5] == '1') && (version.start[7] == '0'))
+    else if ((version.start()[5] == '1') && (version.start()[7] == '0'))
     {
         version_id = VERS_1_0;
     }
-    else if ((version.start[5] == '2') && (version.start[7] == '0'))
+    else if ((version.start()[5] == '2') && (version.start()[7] == '0'))
     {
         version_id = VERS_2_0;
     }
-    else if ((version.start[5] == '0') && (version.start[7] == '9'))
+    else if ((version.start()[5] == '0') && (version.start()[7] == '9'))
     {
         // Real 0.9 traffic would never be labeled HTTP/0.9 because 0.9 is older than the version
         // system. Aside from the possibility that someone might do this to make trouble,
@@ -63,8 +62,8 @@ void HttpMsgStart::derive_version_id()
         // labeled 0.9.
         version_id = VERS_0_9;
     }
-    else if ((version.start[5] >= '0') && (version.start[5] <= '9') &&
-        (version.start[7] >= '0') && (version.start[7] <= '9'))
+    else if ((version.start()[5] >= '0') && (version.start()[5] <= '9') &&
+        (version.start()[7] >= '0') && (version.start()[7] <= '9'))
     {
         version_id = VERS__OTHER;
         infractions += INF_UNKNOWN_VERSION;
index f5a36407e4f18d348d39ee337954207692bf5880..28cbe86f4e06aeeeb168a90867ed45ab1d0858e4 100644 (file)
@@ -42,7 +42,7 @@ void HttpMsgStatus::parse_start_line()
 {
     // Splitter guarantees line begins with "HTTP/"
 
-    if ((start_line.length < 12) || !is_sp_tab[start_line.start[8]])
+    if ((start_line.length() < 12) || !is_sp_tab[start_line.start()[8]])
     {
         infractions += INF_BAD_STAT_LINE;
         events.create_event(EVENT_MISFORMATTED_HTTP);
@@ -50,18 +50,18 @@ void HttpMsgStatus::parse_start_line()
     }
 
     int32_t first_end; // last whitespace in first clump of whitespace
-    for (first_end = 9; (first_end < start_line.length) && is_sp_tab[start_line.start[first_end]];
-        first_end++);
+    for (first_end = 9; (first_end < start_line.length())
+        && is_sp_tab[start_line.start()[first_end]]; first_end++);
     first_end--;
 
-    if (start_line.length < first_end + 4)
+    if (start_line.length() < first_end + 4)
     {
         infractions += INF_BAD_STAT_LINE;
         events.create_event(EVENT_MISFORMATTED_HTTP);
         return;
     }
 
-    if ((start_line.length > first_end + 4) && !is_sp_tab[start_line.start[first_end + 4]])
+    if ((start_line.length() > first_end + 4) && !is_sp_tab[start_line.start()[first_end + 4]])
     {
         // FIXIT-M This should not be fatal. HI supports something like "HTTP/1.1 200\\OK\r\n" as
         // seen in a status line test.
@@ -72,34 +72,31 @@ void HttpMsgStatus::parse_start_line()
 
     HttpModule::increment_peg_counts(PEG_RESPONSE);
 
-    version.start = start_line.start;
-    version.length = 8;
+    version.set(8, start_line.start());
     derive_version_id();
 
-    status_code.start = start_line.start + first_end + 1;
-    status_code.length = 3;
+    status_code.set(3, start_line.start() + first_end + 1);
     derive_status_code_num();
 
-    if (start_line.length > first_end + 5)
+    if (start_line.length() > first_end + 5)
     {
-        reason_phrase.start = start_line.start + first_end + 5;
-        reason_phrase.length = start_line.length - first_end - 5;
+        reason_phrase.set(start_line.length() - first_end - 5, start_line.start() + first_end + 5);
     }
 }
 
 void HttpMsgStatus::derive_status_code_num()
 {
-    if ((status_code.start[0] < '0') || (status_code.start[0] > '9') || (status_code.start[1] <
-        '0') || (status_code.start[1] > '9') ||
-        (status_code.start[2] < '0') || (status_code.start[2] > '9'))
+    if ((status_code.start()[0] < '0') || (status_code.start()[0] > '9') ||
+        (status_code.start()[1] < '0') || (status_code.start()[1] > '9') ||
+        (status_code.start()[2] < '0') || (status_code.start()[2] > '9'))
     {
         infractions += INF_BAD_STAT_CODE;
         events.create_event(EVENT_INVALID_STATCODE);
         status_code_num = STAT_PROBLEMATIC;
         return;
     }
-    status_code_num = (status_code.start[0] - '0') * 100 + (status_code.start[1] - '0') * 10 +
-        (status_code.start[2] - '0');
+    status_code_num = (status_code.start()[0] - '0') * 100 + (status_code.start()[1] - '0') * 10 +
+        (status_code.start()[2] - '0');
     if ((status_code_num < 100) || (status_code_num > 599))
     {
         infractions += INF_BAD_STAT_CODE;
@@ -112,33 +109,33 @@ void HttpMsgStatus::gen_events()
     if (infractions & INF_BAD_STAT_LINE)
         return;
 
-    if (status_code.start > start_line.start + 9)
+    if (status_code.start() > start_line.start() + 9)
     {
         infractions += INF_STATUS_WS;
         events.create_event(EVENT_IMPROPER_WS);
     }
 
-    for (int k = 8; k < status_code.start - start_line.start; k++)
+    for (int k = 8; k < status_code.start() - start_line.start(); k++)
     {
-        if (start_line.start[k] == '\t')
+        if (start_line.start()[k] == '\t')
         {
             infractions += INF_STATUS_TAB;
             events.create_event(EVENT_APACHE_WS);
         }
     }
 
-    if (status_code.start - start_line.start + 3 < start_line.length)
+    if (status_code.start() - start_line.start() + 3 < start_line.length())
     {
-        if (status_code.start[3] == '\t')
+        if (status_code.start()[3] == '\t')
         {
             infractions += INF_STATUS_TAB;
             events.create_event(EVENT_APACHE_WS);
         }
     }
 
-    for (int k=0; k < reason_phrase.length; k++)
+    for (int k=0; k < reason_phrase.length(); k++)
     {
-        if ((reason_phrase.start[k] <= 31) || (reason_phrase.start[k] >= 127))
+        if ((reason_phrase.start()[k] <= 31) || (reason_phrase.start()[k] >= 127))
         {
             // Illegal character in reason phrase
             infractions += INF_BAD_PHRASE;
index 4df2c8037ab19362b3644434ad0eef9867873159..1750e311224048d5c5bede61994badca15ef99c6 100644 (file)
@@ -72,13 +72,13 @@ int32_t norm_remove_quotes_lws(const uint8_t* in_buf, int32_t in_length, uint8_t
 // Convert a decimal field such as Content-Length to an integer.
 int64_t norm_decimal_integer(const Field& input)
 {
-    assert(input.length > 0);
+    assert(input.length() > 0);
     // Limited to 18 decimal digits, not including leading zeros, to fit comfortably into int64_t
     int64_t total = 0;
     int non_leading_zeros = 0;
-    for (int32_t k=0; k < input.length; k++)
+    for (int32_t k=0; k < input.length(); k++)
     {
-        int value = input.start[k] - '0';
+        int value = input.start()[k] - '0';
         if ((non_leading_zeros > 0) || (value != 0))
             non_leading_zeros++;
         if (non_leading_zeros > 18)
@@ -92,11 +92,11 @@ int64_t norm_decimal_integer(const Field& input)
 
 void get_last_token(const Field& input, Field& last_token, char ichar)
 {
-    assert(input.length > 0);
-    for (last_token.start = input.start + input.length - 1; (last_token.start >= input.start) &&
-        (*(last_token.start)!= ichar); (last_token.start)--);
-    (last_token.start)++;
-    last_token.length = input.length - (last_token.start - input.start);
+    assert(input.length() > 0);
+    const uint8_t* last_start = input.start() + input.length() - 1;
+    for (; (last_start >= input.start()) && (*last_start != ichar); last_start--);
+    last_start++;
+    last_token.set(input.length() - (last_start - input.start()), last_start);
     return;
 }
 
@@ -106,15 +106,15 @@ int32_t norm_last_token_code(const Field& input, const StrCode table[])
     Field last_token;
     get_last_token(input, last_token, ',');
 
-    return str_to_code(last_token.start, last_token.length, table);
+    return str_to_code(last_token.start(), last_token.length(), table);
 }
 
 // Given a comma-separated list of words, does "chunked" appear before the last word
 bool chunked_before_end(const Field& input)
 {
-    for (int k=0; k < (input.length - 7); k++)
+    for (int k=0; k < (input.length() - 7); k++)
     {
-        if (((k == 0) || (input.start[k-1] == ',')) && !memcmp(input.start+k, "chunked,", 8))
+        if (((k == 0) || (input.start()[k-1] == ',')) && !memcmp(input.start()+k, "chunked,", 8))
         {
             return true;
         }
index 4b14f0ae24ae1e30df24a2d379853c030fc19dd8..2b8a8782b2bdead778f82f23187bcc14ae760a75 100644 (file)
@@ -285,26 +285,18 @@ const StreamBuffer* HttpStreamSplitter::reassemble(Flow* flow, unsigned total, u
 
     HttpModule::increment_peg_counts(PEG_REASSEMBLE);
 
-    uint8_t*& buffer = session_data->section_buffer[source_id];
-
     const bool is_body = (session_data->section_type[source_id] == SEC_BODY_CHUNK) ||
                          (session_data->section_type[source_id] == SEC_BODY_CL) ||
                          (session_data->section_type[source_id] == SEC_BODY_OLD);
+    uint8_t*& buffer = session_data->section_buffer[source_id];
     if (buffer == nullptr)
     {
-        // The type of buffer used is based on section type. All body sections reuse a single
-        // static buffer. Other sections use a dynamic buffer that may be saved for a while.
-        // Changes here must be mirrored below where the buffer is passed to HttpInspect::process
-        // and in ~HttpFlowData where the buffer will be deleted if it has not been processed.
+        // Body sections need extra space to accommodate unzipping
         if (is_body)
-        {
-            buffer = HttpInspect::body_buffer;
-        }
+            buffer = new uint8_t[MAX_OCTETS];
         else
-        {
             buffer = new uint8_t[total];
-        }
-    }
+     }
 
     if (session_data->section_type[source_id] != SEC_BODY_CHUNK)
     {
@@ -323,7 +315,7 @@ const StreamBuffer* HttpStreamSplitter::reassemble(Flow* flow, unsigned total, u
     {
         const Field& send_to_detection = my_inspector->process(buffer,
             session_data->section_offset[source_id] - session_data->num_excess[source_id], flow,
-            source_id, !is_body);
+            source_id, true);
         // delete[] not necessary because HttpMsgSection is now responsible.
         buffer = nullptr;
 
@@ -334,14 +326,16 @@ const StreamBuffer* HttpStreamSplitter::reassemble(Flow* flow, unsigned total, u
         // framework and forwarded to detection even if it is empty. Other body sections and the
         // trailer section are only forwarded if nonempty. The start line section and header
         // sections other than the detection section are never forwarded.
-        if (((send_to_detection.length > 0) && (HttpInspect::get_latest_is() != IS_NONE)) ||
-            ((send_to_detection.length == 0) && (HttpInspect::get_latest_is() == IS_DETECTION)))
+        if (((send_to_detection.length() > 0) &&
+                (session_data->latest_section->get_inspection_section() != IS_NONE)) ||
+            ((send_to_detection.length() == 0) &&
+                (session_data->latest_section->get_inspection_section() == IS_DETECTION)))
         {
             // FIXIT-M kludge until we work out issues with returning an empty buffer
-            if (send_to_detection.length > 0)
+            if (send_to_detection.length() > 0)
             {
-                http_buf.data = send_to_detection.start;
-                http_buf.length = send_to_detection.length;
+                http_buf.data = send_to_detection.start();
+                http_buf.length = send_to_detection.length();
             }
             else
             {
index 94a7878fe9b6aa621f7b10065de30b96b6b144df..48a939f04b6db66b0c72eff89bbc7000ab2062a2 100644 (file)
 
 using namespace HttpEnums;
 
-HttpUri::~HttpUri()
-{
-    if (classic_norm_allocated)
-        delete[] classic_norm.start;
-}
-
 void HttpUri::parse_uri()
 {
     // Four basic types of HTTP URI
     // "*" means request does not apply to any specific resource
-    if ((uri.length == 1) && (uri.start[0] == '*'))
+    if ((uri.length() == 1) && (uri.start()[0] == '*'))
     {
         uri_type = URI_ASTERISK;
-        scheme.length = STAT_NOT_PRESENT;
-        authority.length = STAT_NOT_PRESENT;
-        abs_path.length = STAT_NOT_PRESENT;
+        scheme.set(STAT_NOT_PRESENT);
+        authority.set(STAT_NOT_PRESENT);
+        abs_path.set(STAT_NOT_PRESENT);
     }
     // CONNECT method uses an authority
     else if (method_id == METH_CONNECT)
     {
         uri_type = URI_AUTHORITY;
-        scheme.length = STAT_NOT_PRESENT;
-        authority.length = uri.length;
-        authority.start = uri.start;
-        abs_path.length = STAT_NOT_PRESENT;
+        scheme.set(STAT_NOT_PRESENT);
+        authority.set(uri);
+        abs_path.set(STAT_NOT_PRESENT);
     }
     // Absolute path is a path but no scheme or authority
-    else if (uri.start[0] == '/')
+    else if (uri.start()[0] == '/')
     {
         uri_type = URI_ABSPATH;
-        scheme.length = STAT_NOT_PRESENT;
-        authority.length = STAT_NOT_PRESENT;
-        abs_path.length = uri.length;
-        abs_path.start = uri.start;
+        scheme.set(STAT_NOT_PRESENT);
+        authority.set(STAT_NOT_PRESENT);
+        abs_path.set(uri);
     }
     // Absolute URI includes scheme, authority, and path
     else
@@ -71,88 +63,87 @@ void HttpUri::parse_uri()
         // Find the "://" and then the "/"
         int j;
         int k;
-        for (j = 0; (j < uri.length) && (uri.start[j] != ':'); j++);
-        for (k = j+3; (k < uri.length) && (uri.start[k] != '/'); k++);
-        if ((k < uri.length) && (uri.start[j+1] == '/') && (uri.start[j+2] == '/'))
+        for (j = 0; (j < uri.length()) && (uri.start()[j] != ':'); j++);
+        for (k = j+3; (k < uri.length()) && (uri.start()[k] != '/'); k++);
+        if ((k < uri.length()) && (uri.start()[j+1] == '/') && (uri.start()[j+2] == '/'))
         {
             uri_type = URI_ABSOLUTE;
-            scheme.length = j;
-            scheme.start = uri.start;
-            authority.length = k - j - 3;
-            authority.start = uri.start + j + 3;
-            abs_path.length = uri.length - k;
-            abs_path.start = uri.start + k;
+            scheme.set(j, uri.start());
+            authority.set(k - j - 3, uri.start() + j + 3);
+            abs_path.set(uri.length() - k, uri.start() + k);
         }
         else
         {
             infractions += INF_BAD_URI;
             events.create_event(EVENT_URI_BAD_FORMAT);
             uri_type = URI__PROBLEMATIC;
-            scheme.length = STAT_PROBLEMATIC;
-            authority.length = STAT_PROBLEMATIC;
-            abs_path.length = STAT_PROBLEMATIC;
+            scheme.set(STAT_PROBLEMATIC);
+            authority.set(STAT_PROBLEMATIC);
+            abs_path.set(STAT_PROBLEMATIC);
         }
     }
 }
 
 void HttpUri::parse_authority()
 {
-    if (authority.length <= 0)
+    if (authority.length() <= 0)
     {
-        host.length = STAT_NO_SOURCE;
-        port.length = STAT_NO_SOURCE;
+        host.set(STAT_NO_SOURCE);
+        port.set(STAT_NO_SOURCE);
         return;
     }
-    host.start = authority.start;
-    for (host.length = 0; (host.length < authority.length) &&
-        (authority.start[host.length] != ':'); host.length++);
-    if (host.length < authority.length)
+    int32_t host_len;
+    for (host_len = 0; (host_len < authority.length()) && (authority.start()[host_len] != ':');
+        host_len++);
+    host.set(host_len, authority.start());
+    if (host.length() < authority.length())
     {
-        port.length = authority.length - host.length - 1;
-        port.start = authority.start + host.length + 1;
+        port.set(authority.length() - host.length() - 1, authority.start() + host.length() + 1);
     }
     else
-        port.length = STAT_NOT_PRESENT;
+        port.set(STAT_NOT_PRESENT);
 }
 
 void HttpUri::parse_abs_path()
 {
     // path?query#fragment
     // path is always present in absolute path, while query and fragment are optional
-    if (abs_path.length <= 0)
+    if (abs_path.length() <= 0)
     {
-        path.length = STAT_NO_SOURCE;
-        query.length = STAT_NO_SOURCE;
-        fragment.length = STAT_NO_SOURCE;
+        path.set(STAT_NO_SOURCE);
+        query.set(STAT_NO_SOURCE);
+        fragment.set(STAT_NO_SOURCE);
         return;
     }
-    path.start = abs_path.start;
-    for (path.length = 0; (path.length < abs_path.length) && (abs_path.start[path.length] != '?')
-        && (abs_path.start[path.length] != '#'); path.length++);
-    if (path.length == abs_path.length)
+    int32_t path_len;
+    for (path_len = 0; (path_len < abs_path.length()) && (abs_path.start()[path_len] != '?') &&
+        (abs_path.start()[path_len] != '#'); path_len++);
+    path.set(path_len, abs_path.start());
+    if (path.length() == abs_path.length())
     {
-        query.length = STAT_NOT_PRESENT;
-        fragment.length = STAT_NOT_PRESENT;
+        query.set(STAT_NOT_PRESENT);
+        fragment.set(STAT_NOT_PRESENT);
         return;
     }
-    if (abs_path.start[path.length] == '?')
+    if (abs_path.start()[path.length()] == '?')
     {
-        query.start = abs_path.start + path.length + 1;
-        for (query.length = 0; (query.length < abs_path.length - path.length - 1) &&
-            (query.start[query.length] != '#'); query.length++);
-        if (abs_path.length - path.length - 1 - query.length == 0)
+        int32_t query_len;
+        const uint8_t* const query_start = abs_path.start() + path.length() + 1;
+        for (query_len = 0; (query_len < abs_path.length() - path.length() - 1) &&
+            (query_start[query_len] != '#'); query_len++);
+        query.set(query_len, query_start);
+        if (abs_path.length() - path.length() - 1 - query.length() == 0)
         {
-            fragment.length = STAT_NOT_PRESENT;
+            fragment.set(STAT_NOT_PRESENT);
             return;
         }
-        fragment.start = query.start + query.length + 1;
-        fragment.length = abs_path.length - path.length - 1 - query.length - 1;
+        fragment.set(abs_path.length() - path.length() - 1 - query.length() - 1,
+                     query.start() + query.length() + 1);
     }
     else
     {
-        query.length = STAT_NOT_PRESENT;
-        fragment.start = abs_path.start + path.length + 1;
-        fragment.length = abs_path.length - path.length - 1;
+        query.set(STAT_NOT_PRESENT);
+        fragment.set(abs_path.length() - path.length() - 1, abs_path.start() + path.length() + 1);
     }
 }
 
@@ -163,11 +154,11 @@ void HttpUri::check_oversize_dir(Field uri_field)
     const uint8_t* cur;
     const uint8_t* end;
 
-    if ( uri_field.length <= 0 )
+    if ( uri_field.length() <= 0 )
         return;
 
-    cur = uri_field.start;
-    end = uri_field.start + uri_field.length;
+    cur = uri_field.start();
+    end = uri_field.start() + uri_field.length();
 
     while ( cur < end )
     {
@@ -200,26 +191,28 @@ void HttpUri::normalize()
     // Almost all HTTP requests are honest and rarely need expensive normalization processing. We
     // do a quick scan for red flags and only perform normalization if something comes up.
     // Otherwise we set the normalized fields to point at the raw values.
-    if ((host.length > 0) && UriNormalizer::need_norm(host, false, uri_param, infractions, events))
+    if ((host.length() > 0) &&
+            UriNormalizer::need_norm(host, false, uri_param, infractions, events))
         infractions += INF_URI_NEED_NORM_HOST;
-    if ((path.length > 0) && UriNormalizer::need_norm(path, true, uri_param, infractions, events))
+    if ((path.length() > 0) &&
+            UriNormalizer::need_norm(path, true, uri_param, infractions, events))
         infractions += INF_URI_NEED_NORM_PATH;
-    if ((query.length > 0) && UriNormalizer::need_norm(query, false, uri_param, infractions,
-            events))
+    if ((query.length() > 0) &&
+            UriNormalizer::need_norm(query, false, uri_param, infractions, events))
         infractions += INF_URI_NEED_NORM_QUERY;
-    if ((fragment.length > 0) && UriNormalizer::need_norm(fragment, false, uri_param, infractions,
-            events))
+    if ((fragment.length() > 0) &&
+            UriNormalizer::need_norm(fragment, false, uri_param, infractions, events))
         infractions += INF_URI_NEED_NORM_FRAGMENT;
 
     if (!((infractions & INF_URI_NEED_NORM_PATH)  || (infractions & INF_URI_NEED_NORM_HOST) ||
           (infractions & INF_URI_NEED_NORM_QUERY) || (infractions & INF_URI_NEED_NORM_FRAGMENT)))
     {
         // This URI is OK, normalization not required
-        host_norm = host;
-        path_norm = path;
-        query_norm = query;
-        fragment_norm = fragment;
-        classic_norm = uri;
+        host_norm.set(host);
+        path_norm.set(path);
+        query_norm.set(query);
+        fragment_norm.set(fragment);
+        classic_norm.set(uri);
         check_oversize_dir(path_norm);
         return;
     }
@@ -227,17 +220,17 @@ void HttpUri::normalize()
     HttpModule::increment_peg_counts(PEG_URI_NORM);
 
     // Create a new buffer containing the normalized URI by normalizing each individual piece.
-    const uint32_t total_length = uri.length + UriNormalizer::URI_NORM_EXPANSION;
+    const uint32_t total_length = uri.length() + UriNormalizer::URI_NORM_EXPANSION;
     uint8_t* const new_buf = new uint8_t[total_length];
     uint8_t* current = new_buf;
-    if (scheme.length >= 0)
+    if (scheme.length() >= 0)
     {
-        memcpy(current, scheme.start, scheme.length);
-        current += scheme.length;
+        memcpy(current, scheme.start(), scheme.length());
+        current += scheme.length();
         memcpy(current, "://", 3);
         current += 3;
     }
-    if (host.length > 0)
+    if (host.length() > 0)
     {
         if (infractions & INF_URI_NEED_NORM_HOST)
             UriNormalizer::normalize(host, host_norm, false, current, uri_param, infractions,
@@ -248,31 +241,31 @@ void HttpUri::normalize()
             // We need a copy of the raw host to provide that part of the normalized URI buffer we
             // are assembling. But the normalized component will refer to the original raw buffer
             // on the chance that the data retention policy in use might keep it longer.
-            memcpy(current, host.start, host.length);
-            host_norm = host;
+            memcpy(current, host.start(), host.length());
+            host_norm.set(host);
         }
-        current += host_norm.length;
+        current += host_norm.length();
     }
-    if (port.length >= 0)
+    if (port.length() >= 0)
     {
         memcpy(current, ":", 1);
         current += 1;
-        memcpy(current, port.start, port.length);
-        current += port.length;
+        memcpy(current, port.start(), port.length());
+        current += port.length();
     }
-    if (path.length > 0)
+    if (path.length() > 0)
     {
         if (infractions & INF_URI_NEED_NORM_PATH)
             UriNormalizer::normalize(path, path_norm, true, current, uri_param, infractions,
                 events);
         else
         {
-            memcpy(current, path.start, path.length);
-            path_norm = path;
+            memcpy(current, path.start(), path.length());
+            path_norm.set(path);
         }
-        current += path_norm.length;
+        current += path_norm.length();
     }
-    if (query.length >= 0)
+    if (query.length() >= 0)
     {
         memcpy(current, "?", 1);
         current += 1;
@@ -281,12 +274,12 @@ void HttpUri::normalize()
                 events);
         else
         {
-            memcpy(current, query.start, query.length);
-            query_norm = query;
+            memcpy(current, query.start(), query.length());
+            query_norm.set(query);
         }
-        current += query_norm.length;
+        current += query_norm.length();
     }
-    if (fragment.length >= 0)
+    if (fragment.length() >= 0)
     {
         memcpy(current, "#", 1);
         current += 1;
@@ -295,10 +288,10 @@ void HttpUri::normalize()
                 infractions, events);
         else
         {
-            memcpy(current, fragment.start, fragment.length);
-            fragment_norm = fragment;
+            memcpy(current, fragment.start(), fragment.length());
+            fragment_norm.set(fragment);
         }
-        current += fragment_norm.length;
+        current += fragment_norm.length();
     }
     assert(current - new_buf <= total_length);
 
@@ -317,8 +310,7 @@ void HttpUri::normalize()
 
     check_oversize_dir(path_norm);
 
-    classic_norm.set(current - new_buf, new_buf);
-    classic_norm_allocated = true;
+    classic_norm.set(current - new_buf, new_buf, true);
 }
 
 size_t HttpUri::get_file_proc_hash()
@@ -326,9 +318,9 @@ size_t HttpUri::get_file_proc_hash()
     if (abs_path_hash)
         return abs_path_hash;
 
-    if (abs_path.length > 0 )
+    if (abs_path.length() > 0 )
     {
-        abs_path_hash = str_to_hash(abs_path.start, abs_path.length);
+        abs_path_hash = str_to_hash(abs_path.start(), abs_path.length());
     }
 
     return abs_path_hash;
index d1beb86ab13dce5ae271e57b4ac4a971641a1e13..ff540c9a0aeffc630e16177589f8904284b02a1d 100644 (file)
@@ -40,7 +40,6 @@ public:
         uri(length, start), method_id(method_id_), uri_param(uri_param_),
         infractions(infractions_), events(events_)
         { normalize(); }
-    ~HttpUri();
     const Field& get_uri() const { return uri; }
     HttpEnums::UriType get_uri_type() { return uri_type; }
     const Field& get_scheme() { return scheme; }
@@ -81,7 +80,6 @@ private:
     Field query_norm;
     Field fragment_norm;
     Field classic_norm;
-    bool classic_norm_allocated = false;
     size_t abs_path_hash = 0;
 
     void normalize();
index 25d1bf502d49a9824e9d0b569f11d18b58ac9034..93f05b0eb9e31861107403fe9869d4fa6701bdff 100644 (file)
@@ -70,12 +70,10 @@ bool UriNormalizer::need_norm(const Field& uri_component, bool do_path,
 bool UriNormalizer::need_norm_no_path(const Field& uri_component,
     const HttpParaList::UriParam& uri_param)
 {
-    const int32_t& length = uri_component.length;
-    const uint8_t* const & buf = uri_component.start;
-    for (int32_t k = 0; k < length; k++)
+    for (int32_t k = 0; k < uri_component.length(); k++)
     {
-        if ((uri_param.uri_char[buf[k]] == CHAR_PERCENT) ||
-            (uri_param.uri_char[buf[k]] == CHAR_SUBSTIT))
+        if ((uri_param.uri_char[uri_component.start()[k]] == CHAR_PERCENT) ||
+            (uri_param.uri_char[uri_component.start()[k]] == CHAR_SUBSTIT))
             return true;
     }
     return false;
@@ -84,8 +82,8 @@ bool UriNormalizer::need_norm_no_path(const Field& uri_component,
 bool UriNormalizer::need_norm_path(const Field& uri_component,
     const HttpParaList::UriParam& uri_param)
 {
-    const int32_t& length = uri_component.length;
-    const uint8_t* const & buf = uri_component.start;
+    const int32_t length = uri_component.length();
+    const uint8_t* const buf = uri_component.start();
     for (int32_t k = 0; k < length; k++)
     {
         switch (uri_param.uri_char[buf[k]])
@@ -122,7 +120,7 @@ int32_t UriNormalizer::norm_char_clean(const Field& input, uint8_t* out_buf,
 {
     bool utf8_needed = false;
     bool double_decoding_needed = false;
-    std::vector<bool> percent_encoded(input.length, false);
+    std::vector<bool> percent_encoded(input.length(), false);
     int32_t length = norm_percent_processing(input, out_buf, uri_param, utf8_needed,
         percent_encoded, double_decoding_needed, infractions, events);
     if (uri_param.utf8 && utf8_needed)
@@ -144,19 +142,19 @@ int32_t UriNormalizer::norm_percent_processing(const Field& input, uint8_t* out_
     HttpInfractions& infractions, HttpEventGen& events)
 {
     int32_t length = 0;
-    for (int32_t k = 0; k < input.length; k++)
+    for (int32_t k = 0; k < input.length(); k++)
     {
-        switch (uri_param.uri_char[input.start[k]])
+        switch (uri_param.uri_char[input.start()[k]])
         {
         case CHAR_EIGHTBIT:
             if (uri_param.utf8_bare_byte &&
-               (((input.start[k] & 0xE0) == 0xC0) || ((input.start[k] & 0xF0) == 0xE0)))
+               (((input.start()[k] & 0xE0) == 0xC0) || ((input.start()[k] & 0xF0) == 0xE0)))
                 utf8_needed = true;
             // Fall through
         case CHAR_NORMAL:
         case CHAR_PATH:
         case CHAR_SUBSTIT:
-            out_buf[length++] = input.start[k];
+            out_buf[length++] = input.start()[k];
             break;
         case CHAR_PERCENT:
             if (is_percent_encoding(input, k))
@@ -172,7 +170,7 @@ int32_t UriNormalizer::norm_percent_processing(const Field& input, uint8_t* out_
                 out_buf[length++] = hex_val;
                 k += 2;
             }
-            else if ((k+1 < input.length) && (input.start[k+1] == '%'))
+            else if ((k+1 < input.length()) && (input.start()[k+1] == '%'))
             {
                 // %% => %
                 double_decoding_needed = true;
@@ -221,15 +219,15 @@ int32_t UriNormalizer::norm_utf8_processing(const Field& input, uint8_t* out_buf
     bool& double_decoding_needed, HttpInfractions& infractions, HttpEventGen& events)
 {
     int32_t length = 0;
-    for (int32_t k=0; k < input.length; k++)
+    for (int32_t k=0; k < input.length(); k++)
     {
         if (percent_encoded[k] || uri_param.utf8_bare_byte)
         {
             // two-byte UTF-8: 110xxxxx 10xxxxxx
-            if (((input.start[k] & 0xE0) == 0xC0) &&
-                (k+1 < input.length) &&
+            if (((input.start()[k] & 0xE0) == 0xC0) &&
+                (k+1 < input.length()) &&
                 (percent_encoded[k+1] || uri_param.utf8_bare_byte) &&
-                ((input.start[k+1] & 0xC0) == 0x80))
+                ((input.start()[k+1] & 0xC0) == 0x80))
             {
                 infractions += INF_URI_PERCENT_UTF8_2B;
                 events.create_event(EVENT_UTF_8);
@@ -238,8 +236,8 @@ int32_t UriNormalizer::norm_utf8_processing(const Field& input, uint8_t* out_buf
                     infractions += INF_BARE_BYTE;
                     events.create_event(EVENT_BARE_BYTE);
                 }
-                const uint16_t utf8_val = ((input.start[k] & 0x1F) << 6) +
-                                           (input.start[k+1] & 0x3F);
+                const uint16_t utf8_val = ((input.start()[k] & 0x1F) << 6) +
+                                           (input.start()[k+1] & 0x3F);
                 const uint8_t val8 = reduce_to_eight_bits(utf8_val, uri_param, infractions,
                     events);
                 if (val8 == '%')
@@ -248,12 +246,12 @@ int32_t UriNormalizer::norm_utf8_processing(const Field& input, uint8_t* out_buf
                 k += 1;
             }
             // three-byte UTF-8: 1110xxxx 10xxxxxx 10xxxxxx
-            else if (((input.start[k] & 0xF0) == 0xE0) &&
-                (k+2 < input.length) &&
+            else if (((input.start()[k] & 0xF0) == 0xE0) &&
+                (k+2 < input.length()) &&
                 (percent_encoded[k+1] || uri_param.utf8_bare_byte) &&
-                ((input.start[k+1] & 0xC0) == 0x80) &&
+                ((input.start()[k+1] & 0xC0) == 0x80) &&
                 (percent_encoded[k+2] || uri_param.utf8_bare_byte) &&
-                ((input.start[k+2] & 0xC0) == 0x80))
+                ((input.start()[k+2] & 0xC0) == 0x80))
             {
                 infractions += INF_URI_PERCENT_UTF8_3B;
                 events.create_event(EVENT_UTF_8);
@@ -262,9 +260,9 @@ int32_t UriNormalizer::norm_utf8_processing(const Field& input, uint8_t* out_buf
                     infractions += INF_BARE_BYTE;
                     events.create_event(EVENT_BARE_BYTE);
                 }
-                const uint16_t utf8_val = ((input.start[k] & 0x0F) << 12) +
-                                          ((input.start[k+1] & 0x3F) << 6) +
-                                           (input.start[k+2] & 0x3F);
+                const uint16_t utf8_val = ((input.start()[k] & 0x0F) << 12) +
+                                          ((input.start()[k+1] & 0x3F) << 6) +
+                                           (input.start()[k+2] & 0x3F);
                 const uint8_t val8 = reduce_to_eight_bits(utf8_val, uri_param, infractions,
                     events);
                 if (val8 == '%')
@@ -273,10 +271,10 @@ int32_t UriNormalizer::norm_utf8_processing(const Field& input, uint8_t* out_buf
                 k += 2;
             }
             else
-                out_buf[length++] = input.start[k];
+                out_buf[length++] = input.start()[k];
         }
         else
-            out_buf[length++] = input.start[k];
+            out_buf[length++] = input.start()[k];
     }
     return length;
 }
@@ -287,10 +285,10 @@ int32_t UriNormalizer::norm_double_decode(const Field& input, uint8_t* out_buf,
 {
     // Double decoding is limited to %hh and %u encoding cases
     int32_t length = 0;
-    for (int32_t k = 0; k < input.length; k++)
+    for (int32_t k = 0; k < input.length(); k++)
     {
-        if (input.start[k] != '%')
-            out_buf[length++] = input.start[k];
+        if (input.start()[k] != '%')
+            out_buf[length++] = input.start()[k];
         else
         {
             if (is_percent_encoding(input, k))
@@ -342,9 +340,9 @@ void UriNormalizer::detect_bad_char(const Field& uri_component,
     if (uri_param.bad_characters.count() == 0)
         return;
 
-    for (int32_t k = 0; k < uri_component.length; k++)
+    for (int32_t k = 0; k < uri_component.length(); k++)
     {
-        if (uri_param.bad_characters[uri_component.start[k]])
+        if (uri_param.bad_characters[uri_component.start()[k]])
         {
             infractions += INF_URI_BAD_CHAR;
             events.create_event(EVENT_NON_RFC_CHAR);
@@ -450,7 +448,7 @@ int32_t UriNormalizer::norm_path_clean(uint8_t* buf, const int32_t in_length,
 }
 
 // Provide traditional URI-style normalization for buffers that usually are not URIs
-void UriNormalizer::classic_normalize(const Field& input, Field& result, uint8_t* buffer,
+void UriNormalizer::classic_normalize(const Field& input, Field& result,
     const HttpParaList::UriParam& uri_param)
 {
     // The requirements for generating events related to these normalizations are unclear. It
@@ -465,6 +463,8 @@ void UriNormalizer::classic_normalize(const Field& input, Field& result, uint8_t
     HttpInfractions unused;
     HttpDummyEventGen dummy_ev;
 
+    uint8_t* const buffer = new uint8_t[input.length() + URI_NORM_EXPANSION];
+
     // Normalize character escape sequences
     int32_t data_length = norm_char_clean(input, buffer, uri_param, unused, dummy_ev);
 
@@ -483,7 +483,7 @@ void UriNormalizer::classic_normalize(const Field& input, Field& result, uint8_t
         }
     }
 
-    result.set(data_length, buffer);
+    result.set(data_length, buffer, true);
 }
 
 bool UriNormalizer::classic_need_norm(const Field& uri_component, bool do_path,
index 0c43d882d9f389e6d72d825258e64cb735be9955..32aa275072ff8ca337b1f75b4a925e78c83825cb 100644 (file)
@@ -42,7 +42,7 @@ public:
         HttpEventGen& events);
     static bool classic_need_norm(const Field& uri_component, bool do_path,
         const HttpParaList::UriParam& uri_param);
-    static void classic_normalize(const Field& input, Field& result, uint8_t* buffer,
+    static void classic_normalize(const Field& input, Field& result,
         const HttpParaList::UriParam& uri_param);
     static void load_default_unicode_map(uint8_t map[65536]);
     static void load_unicode_map(uint8_t map[65536], const char* filename, int code_page);
@@ -92,33 +92,33 @@ private:
 
 bool UriNormalizer::is_percent_encoding(const Field& input, int32_t index)
 {
-    return (index+2 < input.length) &&
-           (HttpEnums::as_hex[input.start[index+1]] != -1) &&
-           (HttpEnums::as_hex[input.start[index+2]] != -1);
+    return (index+2 < input.length()) &&
+           (HttpEnums::as_hex[input.start()[index+1]] != -1) &&
+           (HttpEnums::as_hex[input.start()[index+2]] != -1);
 }
 
 uint8_t UriNormalizer::extract_percent_encoding(const Field& input, int32_t index)
 {
-    return HttpEnums::as_hex[input.start[index+1]] << 4 |
-           HttpEnums::as_hex[input.start[index+2]];
+    return HttpEnums::as_hex[input.start()[index+1]] << 4 |
+           HttpEnums::as_hex[input.start()[index+2]];
 }
 
 bool UriNormalizer::is_u_encoding(const Field& input, int32_t index)
 {
-    return (index+5 < input.length) &&
-           ((input.start[index+1] == 'u') || (input.start[index+1] == 'U')) &&
-           (HttpEnums::as_hex[input.start[index+2]] != -1) &&
-           (HttpEnums::as_hex[input.start[index+3]] != -1) &&
-           (HttpEnums::as_hex[input.start[index+4]] != -1) &&
-           (HttpEnums::as_hex[input.start[index+5]] != -1);
+    return (index+5 < input.length()) &&
+           ((input.start()[index+1] == 'u') || (input.start()[index+1] == 'U')) &&
+           (HttpEnums::as_hex[input.start()[index+2]] != -1) &&
+           (HttpEnums::as_hex[input.start()[index+3]] != -1) &&
+           (HttpEnums::as_hex[input.start()[index+4]] != -1) &&
+           (HttpEnums::as_hex[input.start()[index+5]] != -1);
 }
 
 uint16_t UriNormalizer::extract_u_encoding(const Field& input, int32_t index)
 {
-    return (HttpEnums::as_hex[input.start[index+2]] << 12) |
-           (HttpEnums::as_hex[input.start[index+3]] << 8)  |
-           (HttpEnums::as_hex[input.start[index+4]] << 4)  |
-            HttpEnums::as_hex[input.start[index+5]];
+    return (HttpEnums::as_hex[input.start()[index+2]] << 12) |
+           (HttpEnums::as_hex[input.start()[index+3]] << 8)  |
+           (HttpEnums::as_hex[input.start()[index+4]] << 4)  |
+            HttpEnums::as_hex[input.start()[index+5]];
 }
 
 #endif
index 93cf344cc2429d62b35af83b4e60ef99d65690a5..9f3a3be7998288645b1008aed85ca3d6397c0bf7 100644 (file)
@@ -205,18 +205,18 @@ int HttpIpsOption::eval(Cursor& c, Packet* p)
     if (!p->flow || !p->flow->gadget)
         return DETECTION_OPTION_NO_MATCH;
 
-    if (HttpInspect::get_latest_is() != inspect_section)
+    if (HttpInspect::get_latest_is(p) != inspect_section)
     {
         // It is OK to provide a body buffer during the detection section. If there actually is
         // a body buffer available then the detection section must also be the first body section.
-        if (! ((inspect_section == IS_BODY) && (HttpInspect::get_latest_is() == IS_DETECTION)) )
+        if (! ((inspect_section == IS_BODY) && (HttpInspect::get_latest_is(p) == IS_DETECTION)) )
             return DETECTION_OPTION_NO_MATCH;
     }
 
     InspectionBuffer hb;
 
     if (! ((HttpInspect*)(p->flow->gadget))->
-           http_get_buf((unsigned)buffer_index, sub_id, form, nullptr, hb))
+           http_get_buf((unsigned)buffer_index, sub_id, form, p, hb))
         return DETECTION_OPTION_NO_MATCH;
 
     c.set(key, hb.data, hb.len);
index 5026f3d3af73c526f6e2046d8ad04e9ac9e149e1..29f247b289e4d00fe06c31d2dc9706edcffff78e 100644 (file)
@@ -56,8 +56,8 @@ TEST(http_inspect_uri_norm, normalize)
     Field input(20, (const uint8_t*) "/uri//to/%6eormalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 17);
-    CHECK(memcmp(result.start, "/uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 17);
+    CHECK(memcmp(result.start(), "/uri/to/normalize", 17) == 0);
 }
 
 TEST_GROUP(http_double_decode_test)
@@ -82,8 +82,8 @@ TEST(http_double_decode_test, single)
     Field input(19, (const uint8_t*) "/uri/to%5Cnormalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 17);
-    CHECK(memcmp(result.start, "/uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 17);
+    CHECK(memcmp(result.start(), "/uri/to/normalize", 17) == 0);
 }
 
 TEST(http_double_decode_test, encoded_percent)
@@ -91,8 +91,8 @@ TEST(http_double_decode_test, encoded_percent)
     Field input(21, (const uint8_t*) "/uri/to%255Cnormalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 17);
-    CHECK(memcmp(result.start, "/uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 17);
+    CHECK(memcmp(result.start(), "/uri/to/normalize", 17) == 0);
 }
 
 TEST(http_double_decode_test, double_percent)
@@ -100,8 +100,8 @@ TEST(http_double_decode_test, double_percent)
     Field input(20, (const uint8_t*) "/uri/to%%5Cnormalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 17);
-    CHECK(memcmp(result.start, "/uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 17);
+    CHECK(memcmp(result.start(), "/uri/to/normalize", 17) == 0);
 }
 
 TEST(http_double_decode_test, encoded_all)
@@ -109,8 +109,8 @@ TEST(http_double_decode_test, encoded_all)
     Field input(25, (const uint8_t*) "/uri/to%25%35%43normalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 17);
-    CHECK(memcmp(result.start, "/uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 17);
+    CHECK(memcmp(result.start(), "/uri/to/normalize", 17) == 0);
 }
 
 TEST(http_double_decode_test, utf8_all)
@@ -118,8 +118,8 @@ TEST(http_double_decode_test, utf8_all)
     Field input(24, (const uint8_t*) "/uri/to\xE0\x80\xA5\xC0\xB5\xE0\x81\x83normalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 17);
-    CHECK(memcmp(result.start, "/uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 17);
+    CHECK(memcmp(result.start(), "/uri/to/normalize", 17) == 0);
 }
 
 TEST(http_double_decode_test, u_encode_percent)
@@ -127,8 +127,8 @@ TEST(http_double_decode_test, u_encode_percent)
     Field input(24, (const uint8_t*) "/%%uri/to%u005cnormalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 18);
-    CHECK(memcmp(result.start, "/%uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 18);
+    CHECK(memcmp(result.start(), "/%uri/to/normalize", 17) == 0);
 }
 
 TEST(http_double_decode_test, u_encode_all)
@@ -136,8 +136,8 @@ TEST(http_double_decode_test, u_encode_all)
     Field input(52, (const uint8_t*) "/uri/to%u0025%U0075%u0030%U0030%u0035%U0063normalize");
     Field result;
     UriNormalizer::normalize(input, result, true, buffer, uri_param, infractions, events);
-    CHECK(result.length == 17);
-    CHECK(memcmp(result.start, "/uri/to/normalize", 17) == 0);
+    CHECK(result.length() == 17);
+    CHECK(memcmp(result.start(), "/uri/to/normalize", 17) == 0);
 }
 
 int main(int argc, char** argv)