Skip to content

Commit

Permalink
Add support for pcre2_set_max_pattern_compiled_length
Browse files Browse the repository at this point in the history
  • Loading branch information
ltrzesniewski committed Jun 12, 2024
1 parent 529a0b6 commit 7b07a4f
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/PCRE.NET.Native/pcrenet_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ typedef struct
uint32_t max_pattern_length;
uint32_t compile_extra_options;
uint32_t max_var_lookbehind;
uint32_t max_pattern_compiled_length;
} pcrenet_compile_input;

typedef struct
Expand Down Expand Up @@ -43,6 +44,9 @@ PCRENET_EXPORT(void, compile)(const pcrenet_compile_input* input, pcrenet_compil
if (input->max_pattern_length)
pcre2_set_max_pattern_length(context, input->max_pattern_length);

if (input->max_pattern_compiled_length)
pcre2_set_max_pattern_compiled_length(context, input->max_pattern_compiled_length);

if (input->max_var_lookbehind != MAX_VARLOOKBEHIND)
pcre2_set_max_varlookbehind(context, input->max_var_lookbehind);

Expand Down
36 changes: 36 additions & 0 deletions src/PCRE.NET.Tests/PcreNet/PcreRegexTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,40 @@ public void should_return_pattern_string()
var re = new PcreRegex("foo|bar");
Assert.That(re.ToString(), Is.EqualTo("foo|bar"));
}

[Test]
[TestCase(10u, ExpectedResult = true)]
[TestCase(3u, ExpectedResult = true)]
[TestCase(2u, ExpectedResult = false)]
public bool should_limit_max_pattern_length(uint maxLength)
{
return TryCompilePattern("foo", new PcreRegexSettings { MaxPatternLength = maxLength }) is not null;
}

[Test]
[TestCase(1000u, ExpectedResult = true)]
[TestCase(2u, ExpectedResult = false)]
public bool should_limit_max_compiled_pattern_length(uint maxLength)
{
var re = TryCompilePattern("foo", new PcreRegexSettings { MaxPatternCompiledLength = maxLength });
if (re is null)
return false;

Console.WriteLine(re.PatternInfo.PatternSize);
Assert.That(re.PatternInfo.PatternSize, Is.LessThanOrEqualTo(maxLength));
return true;
}

private static PcreRegex? TryCompilePattern(string pattern, PcreRegexSettings settings)
{
try
{
return new PcreRegex(pattern, settings);
}
catch (PcrePatternException ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
}
1 change: 1 addition & 0 deletions src/PCRE.NET.Tests/PcreNet/Support/RegexKeyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public void should_compare_equal()
BackslashR = PcreBuildInfo.BackslashR,
ParensLimit = PcreBuildInfo.ParensLimit,
MaxPatternLength = null,
MaxPatternCompiledLength = null,
MaxVarLookbehind = 255
};

Expand Down
1 change: 1 addition & 0 deletions src/PCRE.NET/Internal/Native.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ internal ref struct compile_input
public uint max_pattern_length;
public uint compile_extra_options;
public uint max_var_lookbehind;
public uint max_pattern_compiled_length;
}

[StructLayout(LayoutKind.Sequential)]
Expand Down
21 changes: 21 additions & 0 deletions src/PCRE.NET/PcreRegexSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public sealed class PcreRegexSettings
private PcreBackslashR? _backslashR;
private uint? _parensLimit;
private uint? _maxPatternLength;
private uint? _maxPatternCompiledLength;
private uint? _maxVarLookbehind;
private PcreExtraCompileOptions _extraCompileOptions;
private PcreJitCompileOptions _jitCompileOptions;
Expand Down Expand Up @@ -86,6 +87,23 @@ public uint? MaxPatternLength
}
}

/// <summary>
/// The maximum size, in bytes, for the memory needed to hold the compiled version of a pattern.
/// </summary>
/// <remarks>
/// This facility is provided so that applications that accept patterns from external sources can limit the amount of memory they use.
/// The default is the largest number that a <see cref="IntPtr"/> variable can hold, which is effectively unlimited.
/// </remarks>
public uint? MaxPatternCompiledLength
{
get => _maxPatternCompiledLength;
set
{
EnsureIsMutable();
_maxPatternCompiledLength = value;
}
}

/// <summary>
/// The maximum length for the number of characters matched by a variable-length lookbehind assertion.
/// </summary>
Expand Down Expand Up @@ -150,6 +168,7 @@ private PcreRegexSettings(PcreRegexSettings settings, bool readOnly)
_backslashR = settings._backslashR;
_parensLimit = settings._parensLimit;
_maxPatternLength = settings._maxPatternLength;
_maxPatternCompiledLength = settings._maxPatternCompiledLength;
_maxVarLookbehind = settings._maxVarLookbehind;
_extraCompileOptions = settings._extraCompileOptions;
_jitCompileOptions = settings._jitCompileOptions;
Expand All @@ -164,6 +183,7 @@ internal bool CompareValues(PcreRegexSettings other)
&& BackslashR == other.BackslashR
&& ParensLimit == other.ParensLimit
&& MaxPatternLength == other.MaxPatternLength
&& MaxPatternCompiledLength == other.MaxPatternCompiledLength
&& MaxVarLookbehind == other.MaxVarLookbehind
&& ExtraCompileOptions == other.ExtraCompileOptions
&& JitCompileOptions == other.JitCompileOptions;
Expand Down Expand Up @@ -191,6 +211,7 @@ internal void FillCompileInput(ref Native.compile_input input)
input.bsr = (uint)_backslashR.GetValueOrDefault();
input.parens_nest_limit = _parensLimit.GetValueOrDefault();
input.max_pattern_length = _maxPatternLength.GetValueOrDefault();
input.max_pattern_compiled_length = _maxPatternCompiledLength.GetValueOrDefault();
input.max_var_lookbehind = MaxVarLookbehind;
input.compile_extra_options = (uint)_extraCompileOptions;
}
Expand Down

0 comments on commit 7b07a4f

Please sign in to comment.