Merge pull request #118 from gjsjohnmurray/add-formats

validate hostname, ipv4 and ipv6 formats (#100)
This commit is contained in:
Martin Aeschlimann 2021-11-29 13:33:34 +01:00 коммит произвёл GitHub
Родитель 386122c7f0 583380e8e3
Коммит 7d9158a27a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 58 добавлений и 1 удалений

Просмотреть файл

@ -23,7 +23,10 @@ const formats = {
'date-time': { errorMessage: localize('dateTimeFormatWarning', 'String is not a RFC3339 date-time.'), pattern: /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])T([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/i },
'date': { errorMessage: localize('dateFormatWarning', 'String is not a RFC3339 date.'), pattern: /^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/i },
'time': { errorMessage: localize('timeFormatWarning', 'String is not a RFC3339 time.'), pattern: /^([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(Z|(\+|-)([01][0-9]|2[0-3]):([0-5][0-9]))$/i },
'email': { errorMessage: localize('emailFormatWarning', 'String is not an e-mail address.'), pattern: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ }
'email': { errorMessage: localize('emailFormatWarning', 'String is not an e-mail address.'), pattern: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ },
'hostname': { errorMessage: localize('hostnameFormatWarning', 'String is not a hostname.'), pattern: /^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i },
'ipv4': { errorMessage: localize('ipv4FormatWarning', 'String is not an IPv4 address.'), pattern: /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/ },
'ipv6': { errorMessage: localize('ipv6FormatWarning', 'String is not an IPv6 address.'), pattern: /^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i },
};
export interface IProblem {
@ -683,6 +686,9 @@ function validate(n: ASTNode | undefined, schema: JSONSchema, validationResult:
case 'date':
case 'time':
case 'email':
case 'hostname':
case 'ipv4':
case 'ipv6':
const format = formats[schema.format];
if (!node.value || !format.pattern.exec(node.value)) {
validationResult.problems.push({

Просмотреть файл

@ -656,6 +656,57 @@ suite('JSON Parser', () => {
semanticErrors = validate('{"one":"//foo/bar"}', schemaWithURIReference);
assert.strictEqual(semanticErrors!.length, 0, 'uri-reference');
const schemaWithHostname = {
type: 'object',
properties: {
"hostname": {
type: 'string',
format: 'hostname'
}
}
};
semanticErrors = validate('{"hostname":"code.visualstudio.com"}', schemaWithHostname);
assert.strictEqual(semanticErrors!.length, 0, "hostname");
semanticErrors = validate('{"hostname":"foo/bar"}', schemaWithHostname);
assert.strictEqual(semanticErrors!.length, 1, "hostname");
assert.strictEqual(semanticErrors![0].message, 'String is not a hostname.');
const schemaWithIPv4 = {
type: 'object',
properties: {
"hostaddr4": {
type: 'string',
format: 'ipv4'
}
}
};
semanticErrors = validate('{"hostaddr4":"127.0.0.1"}', schemaWithIPv4);
assert.strictEqual(semanticErrors!.length, 0, "hostaddr4");
semanticErrors = validate('{"hostaddr4":"1916:0:0:0:0:F00:1:81AE"}', schemaWithIPv4);
assert.strictEqual(semanticErrors!.length, 1, "hostaddr4");
assert.strictEqual(semanticErrors![0].message, 'String is not an IPv4 address.');
const schemaWithIPv6 = {
type: 'object',
properties: {
"hostaddr6": {
type: 'string',
format: 'ipv6'
}
}
};
semanticErrors = validate('{"hostaddr6":"1916:0:0:0:0:F00:1:81AE"}', schemaWithIPv6);
assert.strictEqual(semanticErrors!.length, 0, "hostaddr6");
semanticErrors = validate('{"hostaddr6":"127.0.0.1"}', schemaWithIPv6);
assert.strictEqual(semanticErrors!.length, 1, "hostaddr6");
assert.strictEqual(semanticErrors![0].message, 'String is not an IPv6 address.');
const schemaWithEMail = {
type: 'object',
properties: {