Skip to content

Commit

Permalink
fix(core) Properly handles flags in string regex validators
Browse files Browse the repository at this point in the history
Signed-off-by: jeromesimeon <[email protected]>
  • Loading branch information
jeromesimeon committed Aug 4, 2021
1 parent e11dae7 commit 6d9f073
Showing 5 changed files with 51 additions and 37 deletions.
23 changes: 6 additions & 17 deletions packages/concerto-core/lib/introspect/parser.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 5 additions & 10 deletions packages/concerto-core/lib/introspect/parser.pegjs
Original file line number Diff line number Diff line change
@@ -283,15 +283,10 @@ UnicodeEscapeSequence

RegularExpressionLiteral "regular expression"
= "/" pattern:$RegularExpressionBody "/" flags:$RegularExpressionFlags {
var value;

try {
value = new RegExp(pattern, flags);
} catch (e) {
error(e.message);
}

return { type: "Literal", value: value };
return {
pattern,
flags
};
}

RegularExpressionBody
@@ -1037,7 +1032,7 @@ StringFieldDeclaration
}

StringRegexValidator
= "regex" __ "=" __ regex:$RegularExpressionLiteral {
= "regex" __ "=" __ regex:RegularExpressionLiteral {
return regex
}

11 changes: 7 additions & 4 deletions packages/concerto-core/lib/introspect/stringvalidator.js
Original file line number Diff line number Diff line change
@@ -33,10 +33,13 @@ class StringValidator extends Validator{
* @throws {IllegalModelException}
*/
constructor(field, validator) {
super(field,validator);
super(field, validator);
try {
// discard the leading / and closing /
this.regex = new RegExp(validator.substring(1,validator.length-1));
if (validator.flags) {
this.regex = new RegExp(validator.pattern, validator.flags);
} else {
this.regex = new RegExp(validator.pattern);
}
}
catch(exception) {
this.reportError(exception.message);
@@ -53,7 +56,7 @@ class StringValidator extends Validator{
validate(identifier, value) {
if(value !== null) {
if(!this.regex.test(value)) {
this.reportError(identifier, 'Value + \'' + value + '\' failed to match validation regex: ' + this.regex);
this.reportError(identifier, 'Value \'' + value + '\' failed to match validation regex: ' + this.regex);
}
}
}
18 changes: 16 additions & 2 deletions packages/concerto-core/test/introspect/field.js
Original file line number Diff line number Diff line change
@@ -43,7 +43,7 @@ describe('Field', () => {
should.equal(f.validator, null);
});

it('should save the incoming validator', () => {
it('should save the incoming string validator', () => {

let f = new Field(mockClassDeclaration, {
id: {
@@ -52,7 +52,21 @@ describe('Field', () => {
propertyType: {
name: 'String'
},
regex: 'suchValidator'
regex: '/^suchValidator$/'
});
f.getValidator().validate('id', 'suchValidator');
});

it('should save the incoming string validator (with flag)', () => {

let f = new Field(mockClassDeclaration, {
id: {
name: 'field',
},
propertyType: {
name: 'String'
},
regex: '/^suchValidator$/u'
});
f.getValidator().validate('id', 'suchValidator');
});
21 changes: 17 additions & 4 deletions packages/concerto-core/test/introspect/stringvalidator.js
Original file line number Diff line number Diff line change
@@ -33,7 +33,7 @@ describe('StringValidator', () => {

it('should throw for invalid regexes', () => {
(() => {
new StringValidator(mockField, '/^[A-z/' );
new StringValidator(mockField, { pattern: '^[A-z' });
}).should.throw(/Validator error for field/);
});

@@ -42,22 +42,35 @@ describe('StringValidator', () => {
describe('#validate', () => {

it('should ignore a null string', () => {
let v = new StringValidator(mockField, '/^[A-z][A-z][0-9]{7}/' );
let v = new StringValidator(mockField, { pattern: '^[A-z][A-z][0-9]{7}' });
v.getRegex().toString().should.equal('/^[A-z][A-z][0-9]{7}/');
v.validate('id', null);
});

it('should validate a string', () => {
let v = new StringValidator(mockField, '/^[A-z][A-z][0-9]{7}/' );
let v = new StringValidator(mockField, { pattern: '^[A-z][A-z][0-9]{7}' });
v.validate('id', 'AB1234567');
});

it('should detect mismatch string', () => {
let v = new StringValidator(mockField, '/^[A-z][A-z][0-9]{7}/');
let v = new StringValidator(mockField, { pattern: '^[A-z][A-z][0-9]{7}' });

(() => {
v.validate('id', 'xyz');
}).should.throw(/Validator error for field id org.acme.myField/);
});

it('should validate a unicode string', () => {
let v = new StringValidator(mockField, { pattern: '^(?!null|true|false)(\\p{Lu}|\\p{Ll}|\\p{Lt}|\\p{Lm}|\\p{Lo}|\\p{Nl}|\\$|_|\\\\u[0-9A-Fa-f]{4})(?:\\p{Lu}|\\p{Ll}|\\p{Lt}|\\p{Lm}|\\p{Lo}|\\p{Nl}|\\$|_|\\\\u[0-9A-Fa-f]{4}|\\p{Mn}|\\p{Mc}|\\p{Nd}|\\p{Pc}|\\u200C|\\u200D)*$', flags: 'u' });
v.validate('id', 'AB1234567');
});

it('should not validate a unicode string', () => {
let v = new StringValidator(mockField, { pattern: '^(?!null|true|false)(\\p{Lu}|\\p{Ll}|\\p{Lt}|\\p{Lm}|\\p{Lo}|\\p{Nl}|\\$|_|\\\\u[0-9A-Fa-f]{4})(?:\\p{Lu}|\\p{Ll}|\\p{Lt}|\\p{Lm}|\\p{Lo}|\\p{Nl}|\\$|_|\\\\u[0-9A-Fa-f]{4}|\\p{Mn}|\\p{Mc}|\\p{Nd}|\\p{Pc}|\\u200C|\\u200D)*$', flags: 'u' });
(() => {
v.validate('id', '1FOO');
}).should.throw(/Validator error for field id org.acme.myField/);
});

});
});

0 comments on commit 6d9f073

Please sign in to comment.