{"record":{"id":"0478ddce5ec6aed9","repo":"XINCGer/Unity3DTraining","slug":"recursion-limit-must-be-positive","errorCode":null,"errorMessage":"Recursion limit must be positive","messagePattern":"Recursion limit must be positive","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/CodedInputStream.cs","lineNumber":197,"sourceCode":"\n        /// <summary>\n        /// Creates a new CodedInputStream reading data from the given\n        /// stream and buffer, using the specified limits.\n        /// </summary>\n        /// <remarks>\n        /// This chains to the version with the default limits instead of vice versa to avoid\n        /// having to check that the default values are valid every time.\n        /// </remarks>\n        internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, int sizeLimit, int recursionLimit)\n            : this(input, buffer, bufferPos, bufferSize)\n        {\n            if (sizeLimit <= 0)\n            {\n                throw new ArgumentOutOfRangeException(\"sizeLimit\", \"Size limit must be positive\");\n            }\n            if (recursionLimit <= 0)\n            {\n                throw new ArgumentOutOfRangeException(\"recursionLimit!\", \"Recursion limit must be positive\");\n            }\n            this.sizeLimit = sizeLimit;\n            this.recursionLimit = recursionLimit;\n        }\n        #endregion\n\n        /// <summary>\n        /// Creates a <see cref=\"CodedInputStream\"/> with the specified size and recursion limits, reading\n        /// from an input stream.\n        /// </summary>\n        /// <remarks>\n        /// This method exists separately from the constructor to reduce the number of constructor overloads.\n        /// It is likely to be used considerably less frequently than the constructors, as the default limits\n        /// are suitable for most use cases.\n        /// </remarks>\n        /// <param name=\"input\">The input stream to read from</param>\n        /// <param name=\"sizeLimit\">The total limit of data to read from the stream.</param>\n        /// <param name=\"recursionLimit\">The maximum recursion depth to allow while reading.</param>","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/XINCGer/Unity3DTraining/blob/016f98412ea5e11756b286736f479b66ab6216d5/NetWorkAndResources/Socket_Protobuff/Assets/Plugins/Google.Protobuf/CodedInputStream.cs#L179-L215","documentation":"The same internal constructor requires recursionLimit > 0. The recursion limit caps how deeply nested protobuf groups/messages may be while parsing, protecting against stack exhaustion from malicious or deeply nested payloads. Zero or negative values are rejected immediately.","triggerScenarios":"Internal construction with a recursionLimit of 0 or less — e.g. passing default(int), or copying a limit field from a configuration object that was never initialized.","commonSituations":"Custom deserialization pipelines (reflection/InternalsVisibleTo) with a config struct where the recursion-depth setting defaulted to 0; copying constants incorrectly when adapting the library.","solutions":["Use a sane positive recursion limit (Google.Protobuf defaults to 64); pass Math.Max(1, configuredLimit).","Initialize the configuration field that carries the recursion limit; do not rely on default(int).","Prefer the public CodedInputStream constructors over the internal overload."],"exampleFix":"// before\nvar reader = NewInternal(input, buf, pos, size, sizeLimit, config.RecursionLimit);\n// after\nint recursionLimit = config.RecursionLimit > 0 ? config.RecursionLimit : 64;\nvar reader = NewInternal(input, buf, pos, size, sizeLimit, recursionLimit);","handlingStrategy":"validation","validationCode":"int recursionLimit = Math.Max(1, configuredRecursionLimit);","typeGuard":"bool IsValidRecursionLimit(int limit) => limit > 0;","tryCatchPattern":"try { CreateReader(..., recursionLimit); } catch (ArgumentOutOfRangeException ex) { logger.LogError(ex, \"recursionLimit must be positive, got {V}\", recursionLimit); recursionLimit = 64; }","preventionTips":["Use Google.Protobuf's default recursion limit (64) unless you have a measured reason otherwise.","Give config fields non-zero defaults; treat 0 as 'unset' and substitute the default.","Never pass default(int) as a limit parameter."],"tags":["protobuf","argument-out-of-range","recursion"],"backgroundTag":"invalid-argument-value","analyzedSha":"016f98412ea5e11756b286736f479b66ab6216d5","analyzedAt":"2026-09-12T01:08:58.711Z","contentChangedAt":"2026-09-12T01:08:58.711Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}