{"record":{"id":"2ff7a6b13776eca2","repo":"SixLabors/ImageSharp","slug":"input-string-contained-non-hexadecimal-characters","errorCode":null,"errorMessage":"Input string contained non-hexadecimal characters","messagePattern":"Input string contained non-hexadecimal characters","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Common/Helpers/HexConverter.cs","lineNumber":89,"sourceCode":"            // byteHi hasn't been shifted to the high half yet, so the only way the bitwise or produces this pattern\n            // is if either byteHi or byteLo was not a hex character.\n            if ((byteLo | byteHi) == 0xFF)\n            {\n                break;\n            }\n\n            bytes[j++] = (byte)((byteHi << 4) | byteLo);\n            i += 2;\n        }\n\n        if (byteLo == 0xFF)\n        {\n            i++;\n        }\n\n        if ((byteLo | byteHi) == 0xFF)\n        {\n            throw new ArgumentException(\"Input string contained non-hexadecimal characters\", nameof(chars));\n        }\n\n        return j;\n    }\n}\n","sourceCodeStart":71,"sourceCodeEnd":95,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Common/Helpers/HexConverter.cs#L71-L95","documentation":"During the pairwise scan, HexStringToBytes computes byteLo/byteHi via FromHexChar, where invalid characters map to 0xFF; if either nibble is 0xFF the input contained a non-hexadecimal character and an ArgumentException is thrown for the 'chars' parameter.","triggerScenarios":"Hex strings containing 'g'-'z', whitespace, '0x' prefixes, or other non-[0-9a-fA-F] characters, e.g. HexStringToBytes(\"0xAB\".AsSpan(), dest).","commonSituations":"Copying hex values including a \"0x\" prefix; strings with embedded spaces or separators; uppercase/lowercase confusion is fine but punctuation is not; decoding data that was corrupted in transit.","solutions":["Strip non-hex characters (prefixes, spaces, separators) before calling.","Pre-validate with a regex/loop over [0-9a-fA-F] and reject bad input with a clearer message.","Catch ArgumentException around the call when input origin is untrusted."],"exampleFix":"// before\nHexConverter.HexStringToBytes(\"0xABCD\".AsSpan(), dest); // throws\n// after\nvar hex = raw.StartsWith(\"0x\") ? raw[2..] : raw;\nhex = hex.Replace(\" \", \"\");\nHexConverter.HexStringToBytes(hex.AsSpan(), dest);","handlingStrategy":"validation","validationCode":"static bool IsHexString(ReadOnlySpan<char> s)\n{\n    foreach (char c in s)\n        if (!char.IsAsciiHexDigit(c)) return false;\n    return true;\n}","typeGuard":"static bool IsHexSafe(ReadOnlySpan<char> s) =>\n    s.Length % 2 == 0 && !s.ContainsAnyInRange('g', 'z') && s.IndexOfAny(\" _-0x\") < 0;","tryCatchPattern":"try { written = HexConverter.HexStringToBytes(hex.AsSpan(), dest); }\ncatch (ArgumentException) { ReportInvalidHex(hex); }","preventionTips":["Strip '0x' prefixes, spaces, and separators before parsing.","Validate the charset with char.IsAsciiHexDigit in a loop.","Sanitize hex data at the boundary where it enters your system."],"tags":["hex","argument-exception","invalid-characters","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"59ce6af6fc29027cda277ef62d4d1694a8acce91","analyzedAt":"2026-09-13T18:34:59.331Z","contentChangedAt":"2026-09-13T18:34:59.331Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}