Skip to content

Commit bcb5f46

Browse files
Merge pull request #7192 from johnhenley/issue-search-regex-7191
FIX: Site crawler regex improvement #7191
2 parents 7895e96 + eb942ad commit bcb5f46

1 file changed

Lines changed: 71 additions & 24 deletions

File tree

DNN Platform/Library/Services/Search/Internals/InternalSearchControllerImpl.cs

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ internal class InternalSearchControllerImpl : IInternalSearchController
4141
private const string SearchableModuleDefsCacheKey = "SearchableModuleDefs";
4242
private const string LocalizedResxFile = "~/DesktopModules/Admin/SearchResults/App_LocalResources/SearchableModules.resx";
4343

44-
private const string HtmlTagsWithAttrs = "<[a-z_:][\\w:.-]*(\\s+(?<attr>\\w+\\s*?=\\s*?[\"'].*?[\"']))+\\s*/?>";
44+
private const string HtmlTagsWithAttrs = "<[a-z_:][\\w:.-]*(?>(?:\\s+(?<attr>\\w+\\s*?=\\s*?[\"'].*?[\"']))*)?\\s*/?>";
4545

4646
private const string AttrText = "[\"'](?<text>.*?)[\"']";
4747
private static readonly ILog Logger = LoggerSource.Instance.GetLogger(typeof(InternalSearchControllerImpl));
4848

4949
private static readonly string[] HtmlAttributesToRetain = { "alt", "title" };
5050
private static readonly DataProvider DataProvider = DataProvider.Instance();
5151

52-
private static readonly Regex StripOpeningTagsRegex = new Regex(@"<\w*\s*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
53-
private static readonly Regex StripClosingTagsRegex = new Regex(@"</\w*\s*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
54-
private static readonly Regex HtmlTagsRegex = new Regex(HtmlTagsWithAttrs, RegexOptions.IgnoreCase | RegexOptions.Compiled);
55-
private static readonly Regex AttrTextRegex = new Regex(AttrText, RegexOptions.Compiled);
52+
private static readonly Regex StripOpeningTagsRegex = RegexUtils.GetCachedRegex(@"<\w*\s*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
53+
private static readonly Regex StripClosingTagsRegex = RegexUtils.GetCachedRegex(@"</\w*\s*>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
54+
private static readonly Regex HtmlTagsRegex = RegexUtils.GetCachedRegex(HtmlTagsWithAttrs, RegexOptions.IgnoreCase | RegexOptions.Compiled);
55+
private static readonly Regex AttrTextRegex = RegexUtils.GetCachedRegex(AttrText, RegexOptions.Compiled);
5656

5757
private readonly IHostSettings hostSettings;
5858
private readonly IServiceProvider serviceProvider;
@@ -298,43 +298,90 @@ private static string StripTagsRetainAttributes(string html, IEnumerable<string>
298298
if (!string.IsNullOrEmpty(strippedString))
299299
{
300300
// Remove all opening HTML Tags with no attributes
301-
strippedString = StripOpeningTagsRegex.Replace(strippedString, emptySpace);
301+
try
302+
{
303+
strippedString = StripOpeningTagsRegex.Replace(strippedString, emptySpace);
304+
}
305+
catch (RegexMatchTimeoutException ex)
306+
{
307+
DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
308+
return string.Empty;
309+
}
310+
catch
311+
{
312+
throw;
313+
}
302314

303315
// Remove all closing HTML Tags
304-
strippedString = StripClosingTagsRegex.Replace(strippedString, emptySpace);
316+
try
317+
{
318+
strippedString = StripClosingTagsRegex.Replace(strippedString, emptySpace);
319+
}
320+
catch (RegexMatchTimeoutException ex)
321+
{
322+
DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
323+
return string.Empty;
324+
}
325+
catch
326+
{
327+
throw;
328+
}
305329
}
306330

307331
if (!string.IsNullOrEmpty(strippedString))
308332
{
309333
var list = new List<string>();
310-
311-
foreach (var match in HtmlTagsRegex.Matches(strippedString).Cast<Match>())
334+
try
312335
{
313-
var captures = match.Groups["attr"].Captures;
314-
foreach (var capture in captures.Cast<Capture>())
336+
foreach (var match in HtmlTagsRegex.Matches(strippedString).Cast<Match>())
315337
{
316-
var val = capture.Value.Trim();
317-
var pos = val.IndexOf('=');
318-
if (pos > 0)
338+
var captures = match.Groups["attr"].Captures;
339+
foreach (var capture in captures.Cast<Capture>())
319340
{
320-
var attr = val.Substring(0, pos).Trim();
321-
if (attributesList.Contains(attr))
341+
var val = capture.Value.Trim();
342+
var pos = val.IndexOf('=');
343+
if (pos > 0)
322344
{
323-
var text = AttrTextRegex.Match(val).Groups["text"].Value.Trim();
324-
if (text.Length > 0 && !list.Contains(text))
345+
var attr = val.Substring(0, pos).Trim();
346+
if (attributesList.Contains(attr))
325347
{
326-
list.Add(text);
348+
try
349+
{
350+
var text = AttrTextRegex.Match(val).Groups["text"].Value.Trim();
351+
if (text.Length > 0 && !list.Contains(text))
352+
{
353+
list.Add(text);
354+
}
355+
}
356+
catch (RegexMatchTimeoutException ex)
357+
{
358+
DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
359+
return string.Empty;
360+
}
361+
catch
362+
{
363+
throw;
364+
}
327365
}
328366
}
329367
}
330-
}
331368

332-
if (list.Count > 0)
333-
{
334-
strippedString = strippedString.Replace(match.ToString(), string.Join(" ", list));
335-
list.Clear();
369+
if (list.Count > 0)
370+
{
371+
strippedString = strippedString.Replace(match.ToString(), string.Join(" ", list));
372+
list.Clear();
373+
}
336374
}
337375
}
376+
catch (RegexMatchTimeoutException ex)
377+
{
378+
DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
379+
return string.Empty;
380+
}
381+
catch
382+
{
383+
throw;
384+
}
338385
}
339386

340387
// If not decoded, decode and strip again. Becareful with recursive

0 commit comments

Comments
 (0)