{"record":{"id":"edf5ffda8a502659","repo":"JeffreySu/WeiXinMPSDK","slug":"finance-sdk-buffername-length","errorCode":null,"errorMessage":"Finance SDK 返回了无效的 {bufferName} 长度：{length}。","messagePattern":"Finance SDK 返回了无效的 (.+?) 长度：(.+?)。","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceNativeApi.cs","lineNumber":250,"sourceCode":"                return LinuxLibraryName;\n            }\n\n            throw new PlatformNotSupportedException(\n                \"企业微信官方未提供当前操作系统可用的 Finance 会话内容存档原生库。\" +\n                \"请在 Windows 或 Linux 上运行，并在 LibraryPath 中指定对应的官方库。\");\n        }\n\n        private static string ReadUtf8(IntPtr pointer, int length, string bufferName)\n        {\n            var bytes = ReadBytes(pointer, length, bufferName);\n            return bytes.Length == 0 ? string.Empty : Encoding.UTF8.GetString(bytes);\n        }\n\n        private static byte[] ReadBytes(IntPtr pointer, int length, string bufferName)\n        {\n            if (length < 0)\n            {\n                throw new InvalidOperationException($\"Finance SDK 返回了无效的 {bufferName} 长度：{length}。\");\n            }\n\n            if (length == 0)\n            {\n                return Array.Empty<byte>();\n            }\n\n            if (pointer == IntPtr.Zero)\n            {\n                throw new InvalidOperationException($\"Finance SDK 返回的 {bufferName} 指针为空，但长度为 {length}。\");\n            }\n\n            var bytes = new byte[length];\n            Marshal.Copy(pointer, bytes, 0, length);\n            return bytes;\n        }\n\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/JeffreySu/WeiXinMPSDK/blob/be573f6f94bdbf718dd5f6cdecb137fbc7ff651e/src/Senparc.Weixin.Work/Senparc.Weixin.Work/AdvancedAPIs/MsgAudit/MsgAuditFinanceNativeApi.cs#L232-L268","documentation":"ReadBytes guards every buffer returned by the WeChat Work (企业微信) Finance SDK. When the SDK reports a negative buffer length (for the outindexbuf or media data buffer), the wrapper cannot safely allocate a byte array, so it throws InvalidOperationException naming the offending buffer. A negative length means the native SDK violated its contract or the caller passed a struct pointer from a failed/unfinished operation.","triggerScenarios":"Calling GetChatData/GetMediaData via GetMediaBytes or GetIndexBufBytes when the SDK fills MediaData.outindexbuflen / MediaData.datalen with a negative int (SDK internal failure, uninitialized MediaData, or ABI mismatch from a wrong-architecture library).","commonSituations":"Running an x86 SDK dll on x64 process (or vice versa) so struct fields misalign; reading media data before GetMediaData finished; passing a default(IntPtr)-based MediaData after a failed call.","solutions":["Verify the loaded libWeWorkFinanceSdk library matches the process architecture (x64 vs x86).","Ensure GetMediaData returned 0 (success) and IsMediaDataFinished is true before reading data buffers.","Re-create the MediaData object and retry the media download; a transient SDK failure can poison the struct.","Check that your SDK version matches the one the wrapper was built against."],"exampleFix":"// before\nvar bytes = financeApi.GetMediaBytes(mediaData); // throws if datalen < 0\n// after\nif (!financeApi.IsMediaDataFinished(mediaData))\n{\n    throw new TimeoutException(\"media download not finished\");\n}\nvar bytes = financeApi.GetMediaBytes(mediaData);","handlingStrategy":"validation","validationCode":"int len = GetDataLen(mediaData);\nif (len < 0) throw new InvalidOperationException(\"Finance SDK returned invalid data length\");","typeGuard":"static bool HasValidBuffer(IntPtr ptr, int len) => len >= 0 && (len == 0 || ptr != IntPtr.Zero);","tryCatchPattern":"try { var bytes = api.GetMediaBytes(mediaData); }\ncatch (InvalidOperationException ex) { logger.LogError(ex, \"Finance SDK buffer invalid\"); /* retry download */ }","preventionTips":["Always check the return code of GetMediaData before reading buffers.","Match SDK bitness to the process architecture.","Recreate MediaData objects for each download instead of reusing them."],"tags":["native-interop","finance-sdk","invalid-data"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"be573f6f94bdbf718dd5f6cdecb137fbc7ff651e","analyzedAt":"2026-09-12T10:01:50.733Z","contentChangedAt":"2026-09-12T10:01:50.733Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}