From f26b3d2205247cefb1d132372f15ce9c48acb504 Mon Sep 17 00:00:00 2001 From: FARHAD SHAKERIN Date: Sun, 4 Dec 2022 22:18:12 -0800 Subject: [PATCH] [FR DateTimeV2] Stack overflow fix in .NET (#3050) --- .../Parsers/BaseDurationParser.cs | 11 +++++++- Specs/DateTime/French/DateTimeModel.json | 27 ++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseDurationParser.cs b/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseDurationParser.cs index 9f08ef6d2e..3088611999 100644 --- a/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseDurationParser.cs +++ b/.NET/Microsoft.Recognizers.Text.DateTime/Parsers/BaseDurationParser.cs @@ -398,7 +398,16 @@ private DateTimeResolutionResult ParseMergedDuration(string text, DateObject ref var durationExtractor = this.config.DurationExtractor; // DurationExtractor without parameter will not extract merged duration - var ers = durationExtractor.Extract(text, referenceTime); + + // TrimStart() was added to address a bug with french duration expression "depuis ans" + // for which the basecase of the recursive call (i.e., if(ers.Count <= 1)) + // would never be reached in which case the stack would overflow. + // The statement if(minStart){...} is meant to find the isolated unit as explained in + // the below comment. However, if there is whitespace before the extacted entity + // (as in " ans") the minStart will be greater than 1 and the Followed Unit regex + // keeps on matching with "ans" and it adds it to ers and it always has + // more than one item in it, hence the recursion never ends. + var ers = durationExtractor.Extract(text.TrimStart(), referenceTime); // If the duration extractions do not start at 0, check if the input starts with an isolated unit. // This happens for example with patterns like "next week and 3 days" where "next" is not part of the extraction. diff --git a/Specs/DateTime/French/DateTimeModel.json b/Specs/DateTime/French/DateTimeModel.json index 992cbe1aa7..4e608dcb21 100644 --- a/Specs/DateTime/French/DateTimeModel.json +++ b/Specs/DateTime/French/DateTimeModel.json @@ -3624,7 +3624,7 @@ "End": 67 } ] - }, + }, { "Input": "Je vais rentrer le 4 janvier 2019.", "NotSupported": "dotnet, javascript, python, java", @@ -8694,6 +8694,27 @@ } ] }, + { + "Input": "bonjour la maison n'est plus habitée depuis ans", + "Results": [ + { + "Text": "depuis ans", + "Start": 37, + "End": 46, + "TypeName": "datetimeV2.duration", + "Resolution": { + "values": [ + { + "timex": "P1Y", + "Mod": "since", + "type": "duration", + "value": "31536000" + } + ] + } + } + ] + }, { "Input": "Rechercher les enregistrements durent moins de 2 heures ou plus de 4 jours et pas moins de 30 minutes.", "NotSupported": "dotnet, javascript, python, java", @@ -21372,7 +21393,7 @@ "type": "time", "value": "08:00:00" }, - { + { "timex": "T20", "type": "time", "value": "20:00:00" @@ -21400,7 +21421,7 @@ "type": "time", "value": "01:00:00" }, - { + { "timex": "T13", "type": "time", "value": "13:00:00"