{"record":{"id":"bdbafc253ac4875f","repo":"egametang/ET","slug":"bufferlist-length-coutn-buffer-length-buffer","errorCode":null,"errorMessage":"bufferList length < coutn, buffer length: {buffer.Length} {offset} {count}","messagePattern":"bufferList length < coutn, buffer length: (.+?) (.+?) (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.core/Scripts/Core/Share/Network/Circularbuffer.cs","lineNumber":206,"sourceCode":"\t\t//    }\n//\n\t\t//    this.LastIndex += n;\n//\n\t\t//    if (this.LastIndex == this.ChunkSize)\n\t\t//    {\n\t\t//\t    this.AddLast();\n\t\t//\t    this.LastIndex = 0;\n\t\t//    }\n//\n\t\t//    return n;\n\t    //}\n\n\t    // 把CircularBuffer中数据写入buffer\n        public override int Read(byte[] buffer, int offset, int count)\n        {\n\t        if (buffer.Length < offset + count)\n\t        {\n\t\t        throw new Exception($\"bufferList length < coutn, buffer length: {buffer.Length} {offset} {count}\");\n\t        }\n\n\t        long length = this.Length;\n\t\t\tif (length < count)\n            {\n\t            count = (int)length;\n            }\n\n            int alreadyCopyCount = 0;\n            while (alreadyCopyCount < count)\n            {\n                int n = count - alreadyCopyCount;\n\t\t\t\tif (ChunkSize - this.FirstIndex > n)\n                {\n                    Array.Copy(this.First, this.FirstIndex, buffer, alreadyCopyCount + offset, n);\n                    this.FirstIndex += n;\n                    alreadyCopyCount += n;\n                }","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.core/Scripts/Core/Share/Network/Circularbuffer.cs#L188-L224","documentation":"CircularBuffer.Read(byte[], int offset, int count) throws when the destination array is too small to hold offset+count bytes. This is a caller contract check: the output buffer must be large enough for the region you requested.","triggerScenarios":"Passing a small cache buffer with a count larger than its usable length, e.g. reading InnerPacketSizeLength (4) into a 2-byte array, or a non-zero offset that pushes count past the array end.","commonSituations":"Reused cache buffer that was shrunk, wrong constant for the read size, or off-by-one in offset math.","solutions":["Ensure buffer.Length >= offset + count (size the cache to the largest possible read).","Prefer the stream overload when the destination size is uncertain.","Reset offset to 0 between reads on a reused cache."],"exampleFix":"// before\nbuffer.Read(this.cache, 0, InnerPacketSizeLength); // cache too small\n// after\nthis.cache = new byte[Math.Max(8, InnerPacketSizeLength)];\nbuffer.Read(this.cache, 0, InnerPacketSizeLength);","handlingStrategy":"validation","validationCode":"if (buffer == null || buffer.Length < offset + count)\n    throw new ArgumentException(\"destination buffer too small\");\nbufffer.Read(buffer, offset, count);","typeGuard":"static bool FitsBuffer(byte[] b, int offset, int count) => b != null && offset >= 0 && count >= 0 && b.Length >= offset + count;","tryCatchPattern":"null","preventionTips":["Size reusable cache buffers to the max read constant.","Keep offset at 0 for sequential reads on a shared cache.","Assert buffer invariants at the call site."],"tags":["network","buffer","argument","csharp"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}