{"record":{"id":"e87d64fd89da7a25","repo":"EllanJiang/GameFramework","slug":"start-index-or-length-is-invalid-utility-encryption","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/Utility/Utility.Encryption.cs","lineNumber":122,"sourceCode":"                if (bytes == null)\n                {\n                    return;\n                }\n\n                if (code == null)\n                {\n                    throw new GameFrameworkException(\"Code is invalid.\");\n                }\n\n                int codeLength = code.Length;\n                if (codeLength <= 0)\n                {\n                    throw new GameFrameworkException(\"Code length is invalid.\");\n                }\n\n                if (startIndex < 0 || length < 0 || startIndex + length > bytes.Length)\n                {\n                    throw new GameFrameworkException(\"Start index or length is invalid.\");\n                }\n\n                int codeIndex = startIndex % codeLength;\n                for (int i = startIndex; i < length; i++)\n                {\n                    bytes[i] ^= code[codeIndex++];\n                    codeIndex %= codeLength;\n                }\n            }\n        }\n    }\n}\n","sourceCodeStart":104,"sourceCodeEnd":135,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Utility/Utility.Encryption.cs#L104-L135","documentation":"Utility.Encryption.GetSelfXorBytes throws GameFrameworkException(\"Start index or length is invalid.\") when startIndex < 0, length < 0, or startIndex + length exceeds bytes.Length — i.e. the requested range does not fit in the buffer. The library validates the slice bounds before performing the XOR loop to avoid corrupting memory or throwing IndexOutOfRangeException mid-operation.","triggerScenarios":"Calling GetSelfXorBytes with a range outside the buffer, e.g. GetSelfXorBytes(data10, 5, 10, key) (5+10 > 10), a negative offset/length from computed offsets, or passing a smaller buffer than the length captured earlier.","commonSituations":"Protocol parsing where offset/length were read from the data itself and are wrong or malicious; buffers reallocated to a smaller size after the length was computed; off-by-one errors when stripping headers.","solutions":["Clamp or recompute startIndex/length so 0 <= startIndex and startIndex + length <= bytes.Length.","Verify the offsets/lengths used — especially if they were parsed from the data — before calling.","Catch GameFrameworkException around the call when handling untrusted data, and reject the buffer instead."],"exampleFix":"// before\nUtility.Converter.GetSelfXorBytes(data, headerLen, payloadLen, key);\n// after\nint start = Math.Max(0, headerLen);\nint len = Math.Min(payloadLen, data.Length - start);\nif (len > 0) Utility.Converter.GetSelfXorBytes(data, start, len, key);","handlingStrategy":"validation","validationCode":"if (startIndex < 0 || length < 0 || startIndex + length > bytes.Length) throw new ArgumentOutOfRangeException(nameof(startIndex), \"Range must satisfy 0 <= startIndex and startIndex + length <= bytes.Length\");","typeGuard":"bool IsValidRange(byte[] bytes, int startIndex, int length) => bytes != null && startIndex >= 0 && length >= 0 && startIndex + length <= bytes.Length;","tryCatchPattern":"try { Utility.Converter.GetSelfXorBytes(data, offset, len, key); }\ncatch (GameFrameworkException ex) { Log.Warn(\"XOR range invalid: {0}\", ex.Message); /* treat payload as corrupt and reject */ }","preventionTips":["Clamp offset/length with Math.Max/Math.Min before calling when values come from parsed data.","Recompute lengths after any buffer reallocation.","Sanitize lengths read from untrusted payloads and reject the packet if out of bounds."],"tags":["argument-out-of-range","encryption","xor","bounds"],"backgroundTag":"value-out-of-range","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}