{"record":{"id":"4212577794371b6d","repo":"antlr/antlr4","slug":"invalid-interval-421257","errorCode":null,"errorMessage":"invalid interval","messagePattern":"invalid interval","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"runtime/CSharp/src/UnbufferedCharStream.cs","lineNumber":430,"sourceCode":"        }\n\n        public virtual string SourceName\n        {\n            get\n            {\n                if (string.IsNullOrEmpty(name))\n                {\n                    return IntStreamConstants.UnknownSourceName;\n                }\n                return name;\n            }\n        }\n\n        public virtual string GetText(Interval interval)\n        {\n            if (interval.a < 0 || interval.b < interval.a - 1)\n            {\n                throw new ArgumentException(\"invalid interval\");\n            }\n            int bufferStartIndex = BufferStartIndex;\n            if (n > 0 && data[n - 1] == IntStreamConstants.EOF)\n            {\n                if (interval.a + interval.Length > bufferStartIndex + n)\n                {\n                    throw new ArgumentException(\"the interval extends past the end of the stream\");\n                }\n            }\n            if (interval.a < bufferStartIndex || interval.b >= bufferStartIndex + n)\n            {\n                throw new NotSupportedException(\"interval \" + interval + \" outside buffer: \" + bufferStartIndex + \"..\" + (bufferStartIndex + n - 1));\n            }\n            // convert from absolute to local index\n            int i = interval.a - bufferStartIndex;\n            // build a UTF-16 string from the Unicode code points in data\n            var sb = new StringBuilder(interval.Length);\n            for (int offset = 0; offset < interval.Length; offset++) {","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/antlr/antlr4/blob/7d5770395bb7b02eb56e7c62662cb1d7c08f42a3/runtime/CSharp/src/UnbufferedCharStream.cs#L412-L448","documentation":"GetText(Interval) first validates the interval itself. The start must be non-negative and the stop must not precede the start by more than one position; an empty interval (b == a-1) is allowed, but a negative start or reversed range is not. This catches malformed intervals before buffer bounds are considered.","triggerScenarios":"Passing Interval.Of(-1, x); passing an interval produced for an invalid/empty source range whose a is negative; or constructing b < a-1 through incorrect token-index arithmetic.","commonSituations":"Using ParserRuleContext.SourceInterval from contexts without a real source interval; error nodes or synthetic nodes during recovery; custom interval math that subtracts one too many; or default/uninitialized Interval values.","solutions":["Check interval.a >= 0 and interval.b >= interval.a - 1 before calling GetText.","Skip text extraction for invalid/synthetic parse-tree nodes.","Fix interval construction so stop is never before start-1."],"exampleFix":"// before\nstring text = chars.GetText(Interval.Of(-1, 2));\n\n// after\nvar interval = Interval.Of(-1, 2);\nif (interval.a >= 0 && interval.b >= interval.a - 1)\n    string text = chars.GetText(interval);","handlingStrategy":"validation","validationCode":"static bool IsValidInterval(Interval i) => i.a >= 0 && i.b >= i.a - 1;\n\nif (IsValidInterval(interval)) text = chars.GetText(interval);","typeGuard":null,"tryCatchPattern":"try { text = chars.GetText(interval); }\ncatch (ArgumentException ex) when (ex.Message == \"invalid interval\") { /* skip invalid/synthetic node text */ }","preventionTips":["Validate intervals before text extraction.","Skip contexts with invalid source intervals.","Use Interval.Of(start, stop) with stop >= start-1."],"tags":["antlr","csharp","intervals","char-stream","input-validation"],"backgroundTag":null,"analyzedSha":"7d5770395bb7b02eb56e7c62662cb1d7c08f42a3","analyzedAt":"2026-08-14T14:47:56.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}