{"record":{"id":"e49aafa0a4d24762","repo":"EllanJiang/GameFramework","slug":"start-index-or-length-is-invalid","errorCode":null,"errorMessage":"Start index or length is invalid.","messagePattern":"Start index or length is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/DataProvider/DataProvider.cs","lineNumber":356,"sourceCode":"        /// <param name=\"startIndex\">内容二进制流的起始位置。</param>\n        /// <param name=\"length\">内容二进制流的长度。</param>\n        /// <param name=\"userData\">用户自定义数据。</param>\n        /// <returns>是否解析内容成功。</returns>\n        public bool ParseData(byte[] dataBytes, int startIndex, int length, object userData)\n        {\n            if (m_DataProviderHelper == null)\n            {\n                throw new GameFrameworkException(\"You must set data helper first.\");\n            }\n\n            if (dataBytes == null)\n            {\n                throw new GameFrameworkException(\"Data bytes is invalid.\");\n            }\n\n            if (startIndex < 0 || length < 0 || startIndex + length > dataBytes.Length)\n            {\n                throw new GameFrameworkException(\"Start index or length is invalid.\");\n            }\n\n            try\n            {\n                return m_DataProviderHelper.ParseData(m_Owner, dataBytes, startIndex, length, userData);\n            }\n            catch (Exception exception)\n            {\n                if (exception is GameFrameworkException)\n                {\n                    throw;\n                }\n\n                throw new GameFrameworkException(Utility.Text.Format(\"Can not parse data bytes with exception '{0}'.\", exception), exception);\n            }\n        }\n\n        /// <summary>","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/DataProvider/DataProvider.cs#L338-L374","documentation":"ParseData(byte[], int, int, object) throws GameFrameworkException('Start index or length is invalid.') when startIndex < 0, length < 0, or startIndex + length exceeds dataBytes.Length. The (startIndex, length) pair must describe a valid in-bounds slice of the buffer before it is handed to the data provider helper.","triggerScenarios":"Passing a negative startIndex or length; passing a length larger than dataBytes.Length - startIndex (e.g. using the full-file length with an offset into the buffer); slicing a bigger buffer with a miscomputed segment size; reading a declared record length from a corrupt/short payload.","commonSituations":"Parsing multiple records out of one buffer where per-record offsets/sizes are read from headers that are wrong or truncated; off-by-one errors in offset arithmetic; loading truncated files whose header claims more bytes than were actually read.","solutions":["Clamp/validate: ensure startIndex >= 0, length >= 0 and startIndex + length <= dataBytes.Length before calling ParseData (Math.Min against remaining bytes works well).","Fix the offset/length computation, e.g. pass dataBytes.Length - startIndex as length instead of the full buffer length.","For header-driven formats, verify the declared sizes against the actual buffer size and treat mismatches as corrupt data.","If the file is truncated, re-download/re-export the data file rather than forcing a parse."],"exampleFix":"// before\ntable.ParseData(buffer, offset, buffer.Length, userData); // may overrun\n// after\nint length = Math.Min(buffer.Length - offset, declaredLength);\nif (offset < 0 || length < 0 || offset + length > buffer.Length)\n{\n    throw new IOException(\"Invalid data slice.\");\n}\ntable.ParseData(buffer, offset, length, userData);","handlingStrategy":"validation","validationCode":"bool IsValidSlice(byte[] b, int start, int len) => start >= 0 && len >= 0 && start + len <= b.Length;","typeGuard":"bool InBounds(byte[] b, int start, int len) => b != null && (uint)start <= (uint)b.Length && len >= 0 && start + len <= b.Length;","tryCatchPattern":"try { provider.ParseData(bytes, start, len, userData); } catch (GameFrameworkException ex) when (ex.Message.Contains(\"Start index or length\")) { /* log offset math bug */ }","preventionTips":["Compute length as remaining bytes (dataBytes.Length - startIndex), not the full buffer length.","Validate all (offset, size) pairs read from headers against the buffer size.","Handle truncated files explicitly instead of forcing an out-of-range parse."],"tags":["argument-out-of-range","dataprovider","slice-bounds"],"backgroundTag":"argument-out-of-range","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}