{"record":{"id":"00346db67c1b1c3d","repo":"EllanJiang/GameFramework","slug":"buffer-is-invalid-utility-marshal","errorCode":null,"errorMessage":"Buffer is invalid.","messagePattern":"Buffer is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Utility/Utility.Marshal.cs","lineNumber":221,"sourceCode":"\n            /// <summary>\n            /// 将数据从二进制流转换为对象。\n            /// </summary>\n            /// <typeparam name=\"T\">要转换的对象的类型。</typeparam>\n            /// <param name=\"structureSize\">要转换的对象的大小。</param>\n            /// <param name=\"buffer\">要转换的二进制流。</param>\n            /// <param name=\"startIndex\">读取要转换的二进制流的起始位置。</param>\n            /// <returns>存储转换结果的对象。</returns>\n            internal static T BytesToStructure<T>(int structureSize, byte[] buffer, int startIndex)\n            {\n                if (structureSize < 0)\n                {\n                    throw new GameFrameworkException(\"Structure size is invalid.\");\n                }\n\n                if (buffer == null)\n                {\n                    throw new GameFrameworkException(\"Buffer is invalid.\");\n                }\n\n                if (startIndex < 0)\n                {\n                    throw new GameFrameworkException(\"Start index is invalid.\");\n                }\n\n                if (startIndex + structureSize > buffer.Length)\n                {\n                    throw new GameFrameworkException(\"Buffer length is not enough.\");\n                }\n\n                EnsureCachedHGlobalSize(structureSize);\n                System.Runtime.InteropServices.Marshal.Copy(buffer, startIndex, s_CachedHGlobalPtr, structureSize);\n                return (T)System.Runtime.InteropServices.Marshal.PtrToStructure(s_CachedHGlobalPtr, typeof(T));\n            }\n        }\n    }","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Utility/Utility.Marshal.cs#L203-L239","documentation":"BytesToStructure requires a non-null byte[] buffer to read the struct bytes from. A null buffer would crash inside the unmanaged copy (Marshal.Copy), so the library throws GameFrameworkException early with this message. It is a defensive null check at the marshaling boundary.","triggerScenarios":"Calling Utility.Marshal.BytesToStructure<T>(structureSize, null, startIndex) — e.g. a read function returned null because a stream read failed or a cache lookup missed.","commonSituations":"Network/file read helpers that return null on failure instead of throwing; deserialization pipelines where an earlier decode step silently produced null; unit data loaded from a partially failed resource table.","solutions":["Ensure the byte[] passed to BytesToStructure is non-null; check the result of whatever produced it before calling.","Make the upstream read routine throw or return an empty array instead of null.","Add a null check with a clear log message at the deserialization entry point."],"exampleFix":"// before\nbyte[] data = ReadChunk(id); // may return null\nvar header = Utility.Marshal.BytesToStructure<Header>(size, data, 0);\n// after\nbyte[] data = ReadChunk(id);\nif (data == null) throw new IOException($\"Chunk {id} not found\");\nvar header = Utility.Marshal.BytesToStructure<Header>(size, data, 0);","handlingStrategy":"type-guard","validationCode":"if (buffer == null)\n    throw new ArgumentNullException(nameof(buffer));\nvar value = Utility.Marshal.BytesToStructure<T>(structureSize, buffer, startIndex);","typeGuard":"bool IsValidBuffer(byte[] buffer) => buffer != null;","tryCatchPattern":"try\n{\n    var v = Utility.Marshal.BytesToStructure<T>(size, buffer, offset);\n}\ncatch (GameFrameworkException ex) when (ex.Message == \"Buffer is invalid.\")\n{\n    // buffer was null: re-read the chunk or surface a read failure\n}","preventionTips":["Make read helpers throw on failure instead of returning null arrays.","Null-check every byte[] produced by network/file reads before parsing.","Enable nullable reference type annotations (#nullable enable) so null flows are flagged at compile time."],"tags":["null-check","marshaling","gameframework"],"backgroundTag":"null-argument","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"}