peass-ng/PEASS-ng · error · ArgumentException
a hexadecimal encoding must have an even number of character
Error message
a hexadecimal encoding must have an even number of characters
What it means
HexEncoder.DecodeStrict requires the decoded region to contain an even number of characters because hex encodes two characters per byte. A odd len throws ArgumentException('a hexadecimal encoding must have an even number of characters', 'len').
Source
Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/util/encoders/HexEncoder.cs:223
length++;
}
if (bufOff > 0)
{
outStream.Write(buf, 0, bufOff);
}
return length;
}
internal byte[] DecodeStrict(string str, int off, int len)
{
if (null == str)
throw new ArgumentNullException("str");
if (off < 0 || len < 0 || off > (str.Length - len))
throw new IndexOutOfRangeException("invalid offset and/or length specified");
if (0 != (len & 1))
throw new ArgumentException("a hexadecimal encoding must have an even number of characters", "len");
int resultLen = len >> 1;
byte[] result = new byte[resultLen];
int strPos = off;
for (int i = 0; i < resultLen; ++i)
{
byte b1 = decodingTable[str[strPos++]];
byte b2 = decodingTable[str[strPos++]];
if ((b1 | b2) >= 0x80)
throw new IOException("invalid characters encountered in Hex data");
result[i] = (byte)((b1 << 4) | b2);
}
return result;
}
}View on GitHub (pinned to 53fb989abc)
Solutions
- Check len % 2 == 0 (and the underlying string length parity) before decoding.
- Fix the slice computation so off/len land on 2-character byte boundaries.
- If the source is truncated, re-fetch or repair the data instead of decoding half a byte.
- Strip prefixes/suffixes (0x, whitespace) so the remaining character count is even.
Example fix
// before
DecodeStrict(s, 0, s.Length); // s.Length == 11 -> throws
// after
if (s.Length % 2 != 0) throw new FormatException("odd-length hex");
DecodeStrict(s, 0, s.Length); Defensive patterns
Strategy: validation
Validate before calling
if ((len & 1) != 0 || off + len > str.Length) throw new FormatException("hex slice must be even-length and in bounds"); Type guard
static bool IsEvenHexSlice(string s, int off, int len) => off >= 0 && len >= 0 && (len & 1) == 0 && off + len <= s.Length;
Try / catch
try { DecodeStrict(s, off, len); } catch (ArgumentException ex) when (ex.ParamName == "len") { padOrRejectInput(); } Prevention
- Check parity of hex strings at ingestion
- Fix slicing so offsets advance in steps of 2
- Reject or repair truncated hex at the source
When it happens
Trigger: Calling strict decode with an odd len value — e.g. slicing a hex string at the wrong boundary, or the source string itself has odd length (truncated hex).
Common situations: Truncated hex from cut-and-paste or log truncation; string slicing with off-by-one; a leading '0x' stripped only partially leaving odd count.
Related errors
- invalid characters encountered in Hex data
- str
- invalid offset and/or length specified
- malformed BMPString encoding encountered
- Invalid character in base32hex string.
AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02).
Data as JSON: /api/errors/4f635e940ec14594.
Report an issue: GitHub.