{"record":{"id":"b31b173291fcdb20","repo":"EllanJiang/GameFramework","slug":"code-is-invalid","errorCode":null,"errorMessage":"Code is invalid.","messagePattern":"Code is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Utility/Utility.Encryption.cs","lineNumber":111,"sourceCode":"            }\n\n            /// <summary>\n            /// 将 bytes 使用 code 做异或运算。此方法将复用并改写传入的 bytes 作为返回值，而不额外分配内存空间。\n            /// </summary>\n            /// <param name=\"bytes\">原始及异或后的二进制流。</param>\n            /// <param name=\"startIndex\">异或计算的开始位置。</param>\n            /// <param name=\"length\">异或计算长度。</param>\n            /// <param name=\"code\">异或二进制流。</param>\n            public static void GetSelfXorBytes(byte[] bytes, int startIndex, int length, byte[] code)\n            {\n                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;","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Utility/Utility.Encryption.cs#L93-L129","documentation":"Utility.Encryption.GetSelfXorBytes(byte[] bytes, int startIndex, int length, byte[] code) throws GameFrameworkException(\"Code is invalid.\") when the XOR encryption key array is null. The XOR routine needs at least one key byte to transform the buffer; a null code makes the operation impossible, so the library throws before mutating the data. This check fires only after the early-return when bytes itself is null.","triggerScenarios":"Calling GetSelfXorBytes / GetXorBytes / GetQuickSelfXorBytes with a null key, e.g. Utility.Converter.GetSelfXorBytes(data, 0, data.Length, null), commonly when the encryption key failed to load or was never set.","commonSituations":"Save-file encryption where the key comes from config that is missing; checksum/obfuscation helpers where a hardcoded key was removed during refactoring; uninitialized static key fields before initialization completes.","solutions":["Ensure the XOR key byte array is initialized (non-null, length > 0) before encrypting or decrypting.","Verify the code path that loads/provides the key actually ran (initialization order).","Guard with a null/empty check and skip or fail gracefully when no key is configured."],"exampleFix":"// before\nUtility.Converter.GetSelfXorBytes(data, 0, data.Length, xorKey);\n// after\nif (xorKey == null || xorKey.Length == 0) throw new InvalidOperationException(\"XOR key not configured\");\nUtility.Converter.GetSelfXorBytes(data, 0, data.Length, xorKey);","handlingStrategy":"validation","validationCode":"if (code == null || code.Length == 0) throw new InvalidOperationException(\"XOR key must be configured before encryption\");","typeGuard":"bool IsValidXorKey(byte[] code) => code != null && code.Length > 0;","tryCatchPattern":"try { Utility.Converter.GetSelfXorBytes(data, 0, data.Length, key); }\ncatch (GameFrameworkException ex) { Log.Error(\"XOR encryption failed: {0}\", ex.Message); /* abort save or use unencrypted fallback */ }","preventionTips":["Load and verify the XOR key once at startup; fail fast if missing.","Never pass keys that come from possibly-empty config values without a check.","Wrap encrypt/decrypt in a small facade so key validation happens in one place."],"tags":["null-argument","encryption","xor"],"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"}