Implement resource limits for regular expression evaluation. Tweaked

to roughly match the Cocoa behaviour, but can be changed through 
the GSRegularExpressionWorkLimit user default.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@39872 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Niels Grewe 2016-06-17 09:04:04 +00:00
parent ac2d08d2a1
commit 0d98f56eca
4 changed files with 156 additions and 8 deletions

View file

@ -46,6 +46,8 @@
#import "Foundation/NSTextCheckingResult.h"
#import "Foundation/NSArray.h"
#import "Foundation/NSCoder.h"
#import "Foundation/NSUserDefaults.h"
#import "Foundation/NSNotification.h"
/**
@ -293,6 +295,48 @@ callback(const void *context, int32_t steps)
return stop;
}
#define DEFAULT_WORK_LIMIT 1500
/**
* The work limit specifies the number of iterations the matcher will do before
* aborting an operation. This ensures that degenerate pattern/input
* combinations don't send the application into what for all intents and
* purposes seems like an infinite loop.
*/
static int32_t _workLimit = DEFAULT_WORK_LIMIT;
+ (void) _defaultsChanged: (NSNotification*)n
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
id value = [defs objectForKey: @"GSRegularExpressionWorkLimit"];
int32_t newLimit = DEFAULT_WORK_LIMIT;
if ([value respondsToSelector: @selector(intValue)])
{
int32_t v = [value intValue];
if (v >= 0)
{
newLimit = v;
}
}
_workLimit = newLimit;
}
+ (void) initialize
{
if (self == [NSRegularExpression class])
{
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(_defaultsChanged:)
name: NSUserDefaultsDidChangeNotification
object: nil];
[self _defaultsChanged: nil];
}
}
/**
* Sets up a libicu regex object for use. Note: the documentation states that
* NSRegularExpression must be thread safe. To accomplish this, we store a
@ -328,6 +372,7 @@ setupRegex(URegularExpression *regex,
{
uregex_useTransparentBounds(r, TRUE, &s);
}
uregex_setTimeLimit(r, _workLimit, &s);
if (U_FAILURE(s))
{
uregex_close(r);
@ -363,6 +408,7 @@ setupRegex(URegularExpression *regex,
{
uregex_useTransparentBounds(r, TRUE, &s);
}
uregex_setTimeLimit(r, _workLimit, &s);
if (U_FAILURE(s))
{
uregex_close(r);