Repository navigation
Possible verbatim string confusion? #3032
Description
Activity
Found it, and the server was innocent.
The
txt=in that log is the test's own formatting, not the wire —ConfigTests.csbuilds the failure message
withsb.Append(setting.Key).Append('='). So the real observation is a parsed pair of("txt", "# CPU"),
which means the line the INFO parser saw wastxt:# CPU: the verbatim kind prefix survived into the payload.
That line then fails theStartsWith("# ")section test, gets split on the colon into a key/value pair, and
with no section header ever recognised every field lands undermiscellaneous. Hence "expected CPU, got
miscellaneous" with all the data present.The cause was in
RawResult.GetString(out verbatimPrefix):if (Payload.IsSingleSegment) { s = Format.GetString(Payload.First.Span); return Resp3Type == ResultType.VerbatimString ? GetVerbatimString(s, out verbatimPrefix) : s; } #if NET6_0_OR_GREATER // use system-provided sequence decoder return Encoding.UTF8.GetString(in _payload); // <-- never calls GetVerbatimString #else ... return Resp3Type == ResultType.VerbatimString ? GetVerbatimString(s, out verbatimPrefix) : s; #endif
The multi-segment path on .NET 6+ skipped the strip entirely. Single-segment replies were fine, and so was the
down-level branch — so it fired only when the INFO reply happened to straddle a buffer boundary, which is why
it looked flaky, machine-specific and server-shaped. It also leftverbatimPrefixempty on that path.Believed fixed in v3: RESPite's
RespReader.ReadStringlinearises viaBuffer(...)before inspecting the
kind prefix, so single- and multi-segment payloads take the same path and the segment-dependence is gone.
Confirmed locally with a throwaway[Theory, Resp(...)]over a verbatim INFO frame — the attribute generates
right-sized, oversized, every two-chunk split point (including insidetxt:) and chunk-per-byte, 43 variants,
all green; and it does fail if the strip is disabled, so it wasn't passing vacuously. Not keeping the test:
the defect lived inRawResult, which no longer exists, so it would guard a different code path than the one
that broke.Worth noting for next time: any single-segment test of verbatim handling would have passed throughout this.
The exhaustive splitting in theRespattribute is what makes this class of bug findable.Closing as fixed in v3.
I've seen the following repeatedly today only against CI servers, on the main branch (mentioning to rule out any V3/V2 stuff):
This is interesting because a RESP3 verbatim string would be:
={count}\r\n{kind}:{payload}\r\n, wherekindis always exactly 3 characters, for example=16\r\ntxt:blahblahblah\r\n.The server should not be issuing
txt=...it should betxt:...- so... either the server has started responding differently, or we're borking something on the inbound.Relevant CI is using
Redis version=8.6.1, in particular in the Windows Server 2022 build.CI starts this server in WSL with:
https://github.com/StackExchange/StackExchange.Redis/actions/runs/22959665638/workflow#L67-L75
I'm not sure there's anything to do on this right now other than keep an eye on it.