Merge pull request #2575 from Elcoid/iss2570

sam: fix inconsistencies in version negotiation of sam handshake
This commit is contained in:
orignal
2026-09-25 14:15:45 -04:00
committed by GitHub
2 changed files with 100 additions and 8 deletions
+41 -8
View File
@@ -95,6 +95,15 @@ namespace client
version *= 10;
version += (ch - '0');
}
else if (ch == '.')
{
// no-op: skip periods
}
else
{
// if version contains other characters, return error
return -1;
}
}
return version;
}
@@ -131,7 +140,10 @@ namespace client
if (!strcmp (m_Buffer, SAM_HANDSHAKE))
{
int minVer = 0, maxVer = 0;
// try to find MIN and MAX, 3.0 if not found
bool verErr = false;
// try to find MIN and MAX, MAX_SAM_VERSION if not found,
// since the highest possible version must be returned
// given the constraints
if (separator)
{
separator++;
@@ -143,14 +155,35 @@ namespace client
if (!minVerStr.empty ())
minVer = ExtractVersion (minVerStr);
}
// if parsing error or impossible version constraints
if (minVer == -1 || maxVer == -1 || (minVer && maxVer && minVer > maxVer))
verErr = true;
// version negotiation
if (maxVer && maxVer <= MAX_SAM_VERSION)
m_Version = maxVer;
else if (minVer && minVer >= MIN_SAM_VERSION && minVer <= MAX_SAM_VERSION)
m_Version = minVer;
else if (!maxVer && !minVer)
m_Version = MIN_SAM_VERSION;
else
else if (maxVer && minVer) // if both constraints provided
{
if (maxVer < MIN_SAM_VERSION || minVer > MAX_SAM_VERSION)
verErr = true;
else
m_Version = std::min(maxVer, MAX_SAM_VERSION);
}
else if (maxVer) // if only max provided
{
if (maxVer < MIN_SAM_VERSION)
verErr = true;
else
m_Version = std::min(maxVer, MAX_SAM_VERSION);
}
else if (minVer) // if only min provided
{
if (minVer > MAX_SAM_VERSION)
verErr = true;
else
m_Version = MAX_SAM_VERSION;
}
else // if neither min nor max is provided
m_Version = MAX_SAM_VERSION;
if (verErr)
{
LogPrint (eLogError, "SAM: Handshake version mismatch ", minVer, " ", maxVer);
SendMessageReply (SAM_HANDSHAKE_NOVERSION, true);
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# This script tests the version negotiation in the SAM handshake.
# Inputs and expected outputs
IN=()
EXP=()
IN+=("MIN=3.1 MAX=3.3")
EXP+=("OK VERSION=3.3")
IN+=("MAX=3.3")
EXP+=("OK VERSION=3.3")
IN+=("MAX=3.4")
EXP+=("OK VERSION=3.3")
IN+=("MIN=3.0")
EXP+=("OK VERSION=3.3")
IN+=("MIN=3.1")
EXP+=("OK VERSION=3.3")
IN+=("MIN=2.9")
EXP+=("OK VERSION=3.3")
IN+=("")
EXP+=("OK VERSION=3.3")
IN+=("MIN=3.3 MAX=3.1")
EXP+=("NOVERSION")
IN+=("MIN=3.5 MAX=2.7")
EXP+=("NOVERSION")
IN+=("MIN=2.7 MAX=3.5")
EXP+=("OK VERSION=3.3")
IN+=("MIN=afddab3vsfdsg1df MAX=dsaaffdb3ggfgfbgf1bssbf")
EXP+=("NOVERSION")
IN+=("MIN=31 MAX=31")
EXP+=("OK VERSION=3.1")
for i in $(seq 0 $((${#IN[@]} - 1))); do
printf "HELLO VERSION ${IN[$i]} - "
# Observed output
OBS=$(printf "HELLO VERSION ${IN[$i]}\n" | nc -q 0 127.0.0.1 7656)
if [ "$OBS" = "HELLO REPLY RESULT=${EXP[$i]}" ]; then
printf "OK\n"
else
printf "received $OBS\n"
fi
done