From 5095e3c9e67d0ffd52c0d2cdfd0b343d3de5c77d Mon Sep 17 00:00:00 2001 From: Roman-Koshelev Date: Sun, 11 Apr 2021 14:15:25 +0300 Subject: [PATCH 1/4] Simplification message_reader::init() --- include/hffix.hpp | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/include/hffix.hpp b/include/hffix.hpp index 4668cfc..b1337f6 100644 --- a/include/hffix.hpp +++ b/include/hffix.hpp @@ -2258,10 +2258,8 @@ class message_reader { char const* b = buffer_ + 9; // look for the first '\x01' while(true) { - if (b >= buffer_end_) { - is_complete_ = false; - return; - } + if (b >= buffer_end_) return; + if (*b == '\x01') { prefix_end_ = b; break; @@ -2273,10 +2271,8 @@ class message_reader { ++b; } - if (b + 1 >= buffer_end_) { - is_complete_ = false; - return; - } + if (b + 1 >= buffer_end_) return; + if (b[1] != '9') { // next field must be tag 9 BodyLength invalid(); return; @@ -2286,10 +2282,8 @@ class message_reader { size_t bodylength(0); // the value of tag 9 BodyLength while(true) { - if (b >= buffer_end_) { - is_complete_ = false; - return; - } + if (b >= buffer_end_) return; + if (*b == '\x01') break; if (*b < '0' || *b > '9') { // this is the only time we need to check for numeric ascii. invalid(); @@ -2300,10 +2294,7 @@ class message_reader { } ++b; - if (b + 3 >= buffer_end_) { - is_complete_ = false; - return; - } + if (b + 3 >= buffer_end_) return; if (*b != '3' || b[1] != '5') { // next field must be tag 35 MsgType invalid(); @@ -2312,10 +2303,7 @@ class message_reader { char const* checksum = b + bodylength; - if (checksum + 7 > buffer_end_) { - is_complete_ = false; - return; - } + if (checksum + 7 > buffer_end_) return; if (*(checksum - 1) != '\x01') { // check for SOH before the checksum. // this guarantees that at least From 202995074bdda8033ead0c7971d431734054362c Mon Sep 17 00:00:00 2001 From: Roman-Koshelev Date: Sun, 11 Apr 2021 14:04:55 +0300 Subject: [PATCH 2/4] message_reader::init() Rewritten check BeginString Strengthen the check, and also remove the restriction on the length of the value --- include/hffix.hpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/include/hffix.hpp b/include/hffix.hpp index b1337f6..8a0afcc 100644 --- a/include/hffix.hpp +++ b/include/hffix.hpp @@ -2253,23 +2253,25 @@ class message_reader { friend class message_reader_const_iterator; void init() { + char const* b = buffer_; - // Skip the version prefix string "8=FIX.4.2" or "8=FIXT.1.1", et cetera. - char const* b = buffer_ + 9; // look for the first '\x01' + if (b >= buffer_end_) return; + if (*b++ != '8') { invalid(); return; } + if (b >= buffer_end_) return; + if (*b++ != '=') { invalid(); return; } - while(true) { - if (b >= buffer_end_) return; + const std::ptrdiff_t max_begin_string_len = details::len("FIXT.1.1"); + const std::ptrdiff_t max_find_len = std::min(max_begin_string_len + 1, buffer_end_ - b); - if (*b == '\x01') { - prefix_end_ = b; - break; - } - if (b - buffer_ > 11) { + // look for the first '\x01' + char const* end = b + max_find_len + 1; + b = std::find(b, end, '\x01'); + if (b == end) { + if (max_find_len == (max_begin_string_len + 1)) invalid(); - return; - } - ++b; + return; } + prefix_end_ = b; if (b + 1 >= buffer_end_) return; From fd363820a967f6ea4b9982560dca3c6f810509e7 Mon Sep 17 00:00:00 2001 From: Roman-Koshelev Date: Sun, 11 Apr 2021 14:24:09 +0300 Subject: [PATCH 3/4] message_reader::init() Rewritten check BodyLength We will strengthen the check, and also detect an invalid message for as few characters as possible --- include/hffix.hpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/include/hffix.hpp b/include/hffix.hpp index 8a0afcc..8710334 100644 --- a/include/hffix.hpp +++ b/include/hffix.hpp @@ -2271,31 +2271,27 @@ class message_reader { invalid(); return; } - prefix_end_ = b; + prefix_end_ = b++; - if (b + 1 >= buffer_end_) return; - - if (b[1] != '9') { // next field must be tag 9 BodyLength - invalid(); - return; - } - b += 3; // skip the " 9=" for tag 9 BodyLength + if (b >= buffer_end_) return; + // next field must be tag 9 BodyLength + if (*b++ != '9') { invalid(); return; } + if (b >= buffer_end_) return; + if (*b++ != '=') { invalid(); return; } size_t bodylength(0); // the value of tag 9 BodyLength while(true) { if (b >= buffer_end_) return; - - if (*b == '\x01') break; - if (*b < '0' || *b > '9') { // this is the only time we need to check for numeric ascii. - invalid(); - return; - } + char tmp = *b++; + + if (tmp == '\x01') break; + // this is the only time we need to check for numeric ascii. + if (tmp < '0' || tmp > '9') { invalid(); return; } bodylength *= 10; - bodylength += *b++ - '0'; // we know that 0 <= (*b - '0') <= 9, so rvalue will be positive. + bodylength += tmp - '0'; // we know that 0 <= (*b - '0') <= 9, so rvalue will be positive. } - ++b; if (b + 3 >= buffer_end_) return; if (*b != '3' || b[1] != '5') { // next field must be tag 35 MsgType From 13245d8d44382bfaf1ad431eb351dbdc7bd90efb Mon Sep 17 00:00:00 2001 From: Roman-Koshelev Date: Sun, 11 Apr 2021 14:29:23 +0300 Subject: [PATCH 4/4] message_reader::init() Rewritten check MsgType We will strengthen the check, and also detect an invalid message for as few characters as possible --- include/hffix.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/hffix.hpp b/include/hffix.hpp index 8710334..3630c1f 100644 --- a/include/hffix.hpp +++ b/include/hffix.hpp @@ -2292,12 +2292,12 @@ class message_reader { bodylength += tmp - '0'; // we know that 0 <= (*b - '0') <= 9, so rvalue will be positive. } - if (b + 3 >= buffer_end_) return; - - if (*b != '3' || b[1] != '5') { // next field must be tag 35 MsgType - invalid(); - return; - } + if (b >= buffer_end_) return; + if (*b != '3') { invalid(); return; } + if (b + 1 >= buffer_end_) return; + if (b[1] != '5') { invalid(); return; } + if (b + 2 >= buffer_end_) return; + if (b[2] != '=') { invalid(); return; } char const* checksum = b + bodylength;