Masking: Distinguish between EOF and 8 byte integer

When processing the response to a COM_QUERY, the rows will be
terminated by an EOF packet. However, as the type byte of an
EOF packet is 0xFE and the identifying byte of an 8 byte length
encoded integer is also 0xFE it is not possible to distinguish
the two except by also looking at packet length.
This commit is contained in:
Johan Wikman 2017-01-18 14:11:25 +02:00
parent fde8b52aea
commit e4d6af37a9
3 changed files with 48 additions and 29 deletions

View File

@ -216,28 +216,26 @@ void warn_of_type_mismatch(const MaskingRules::Rule& rule)
void MaskingFilterSession::handle_row(GWBUF* pPacket)
{
ComResponse response(pPacket);
ComPacket response(pPacket);
switch (response.type())
if ((response.payload_len() == ComEOF::PAYLOAD_LEN) &&
(ComResponse(response).type() == ComPacket::EOF_PACKET))
{
case ComPacket::EOF_PACKET:
// EOF after last row.
ComEOF eof(response);
if (eof.status() & SERVER_MORE_RESULTS_EXIST)
{
ComEOF eof(response);
if (eof.status() & SERVER_MORE_RESULTS_EXIST)
{
m_res.reset_multi();
m_state = EXPECTING_RESPONSE;
}
else
{
m_state = EXPECTING_NOTHING;
}
m_res.reset_multi();
m_state = EXPECTING_RESPONSE;
}
break;
default:
else
{
m_state = EXPECTING_NOTHING;
}
}
else
{
if (m_res.some_rule_matches())
{
if (response.payload_len() >= ComPacket::MAX_PAYLOAD_LEN)
@ -267,7 +265,7 @@ void MaskingFilterSession::handle_large_payload()
}
}
void MaskingFilterSession::mask_values(ComResponse& response)
void MaskingFilterSession::mask_values(ComPacket& response)
{
switch (m_res.command())
{

View File

@ -59,7 +59,7 @@ private:
void handle_eof(GWBUF* pPacket);
void handle_large_payload();
void mask_values(ComResponse& response);
void mask_values(ComPacket& response);
private:
typedef std::tr1::shared_ptr<MaskingRules> SMaskingRules;

View File

@ -493,16 +493,6 @@ public:
MAX_PAYLOAD_LEN = 0xffffff
};
uint32_t payload_len() const
{
return m_payload_len;
}
uint8_t packet_no() const
{
return m_packet_no;
}
protected:
ComPacket(GWBUF* pPacket)
: m_pPacket(pPacket)
, m_pData(GWBUF_DATA(pPacket))
@ -521,6 +511,22 @@ protected:
m_pData += MYSQL_HEADER_LEN;
}
uint32_t payload_len() const
{
return m_payload_len;
}
uint32_t packet_len() const
{
return MYSQL_HEADER_LEN + m_payload_len;
}
uint8_t packet_no() const
{
return m_packet_no;
}
protected:
GWBUF* m_pPacket;
uint8_t* m_pData;
@ -542,13 +548,22 @@ public:
: ComPacket(pPacket)
, m_type(*m_pData)
{
ss_dassert(packet_len() >= MYSQL_HEADER_LEN + 1);
++m_pData;
}
ComResponse(const ComPacket& packet)
: ComPacket(packet)
, m_type(*m_pData)
{
ss_dassert(packet_len() >= MYSQL_HEADER_LEN + 1);
++m_pData;
}
ComResponse(const ComResponse& packet)
: ComPacket(packet)
, m_type(packet.m_type)
{
ss_dassert(packet_len() >= MYSQL_HEADER_LEN + 1);
++m_pData;
}
@ -579,6 +594,12 @@ protected:
class ComEOF : public ComResponse
{
public:
enum
{
PAYLOAD_LEN = 5,
PACKET_LEN = MYSQL_HEADER_LEN + PAYLOAD_LEN
};
ComEOF(GWBUF* pPacket)
: ComResponse(pPacket)
{