Skip to content

Commit

Permalink
Validate language tags
Browse files Browse the repository at this point in the history
  • Loading branch information
rubensworks committed Mar 16, 2020
1 parent 8bc5c15 commit 318e3e6
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/JsonLdParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,14 @@ export interface IJsonLdParserOptions {
* this must be explicitly set to true.
*/
validateValueIndexes?: boolean;
/**
* If values should be strictly checked.
* If true, an error will be thrown on invalid value ranged.
* if false, the resulting triple/quad will be omitted.
*
* Defaults to false.
*/
strictRanges?: boolean;
/**
* The graph to use as default graph when no explicit @graph is set.
* Defaults to dataFactory.defaultGraph().
Expand Down
2 changes: 2 additions & 0 deletions lib/ParsingContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class ParsingContext {
public readonly processingMode: string;
public readonly errorOnInvalidProperties: boolean;
public readonly validateValueIndexes: boolean;
public readonly strictRanges: boolean;
public readonly rootContext: Promise<IJsonLdContextNormalized>;
public readonly defaultGraph?: RDF.Term;

Expand Down Expand Up @@ -73,6 +74,7 @@ export class ParsingContext {
this.processingMode = options.processingMode || JsonLdParser.DEFAULT_PROCESSING_MODE;
this.errorOnInvalidProperties = options.errorOnInvalidIris;
this.validateValueIndexes = options.validateValueIndexes;
this.strictRanges = options.strictRanges;
this.defaultGraph = options.defaultGraph;

// Initialize stacks
Expand Down
9 changes: 9 additions & 0 deletions lib/Util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class Util {
public static readonly XSD_INTEGER: string = Util.XSD + 'integer';
public static readonly XSD_DOUBLE: string = Util.XSD + 'double';
public static readonly RDF: string = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
public static readonly REGEX_LANGUAGE_TAG: RegExp = /^[a-zA-Z]+(-[a-zA-Z0-9]+)*$/;

public readonly dataFactory: RDF.DataFactory;
public readonly rdfFirst: RDF.NamedNode;
Expand Down Expand Up @@ -239,6 +240,14 @@ export class Util {
// Language tags are always normalized to lowercase.
valueLanguage = valueLanguage.toLowerCase();

if (!Util.REGEX_LANGUAGE_TAG.test(valueLanguage)) {
if (this.parsingContext.strictRanges) {
throw new Error(`The value of an '@language' must be a valid language tag, got '${
JSON.stringify(valueLanguage)}'`);
} else {
return null;
}
}
return this.dataFactory.literal(val, valueLanguage);
} else if (valueType) { // Validate @type
if (typeof valueType !== 'string') {
Expand Down
11 changes: 11 additions & 0 deletions test/Util-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,17 @@ describe('Util', () => {
new Error('When an \'@language\' is set, the value of \'@value\' must be a string, got \'true\''));
});

it('with a @value and invalid @language should return null', async () => {
return expect(util.valueToTerm(context, 'key', { '@value': 'abc', '@language': 'en us' }, 0))
.resolves.toBeNull();
});

it('with a @value and invalid @language should throw an error when strictRanges is true', async () => {
util.parsingContext.strictRanges = true;
return expect(util.valueToTerm(context, 'key', { '@value': 'abc', '@language': 'en us' }, 0))
.rejects.toThrow(new Error('The value of an \'@language\' must be a valid language tag, got \'"en us"\''));
});

it('with a @value and boolean @type should throw an error', async () => {
return expect(util.valueToTerm(context, 'key', { '@value': 'abc', '@type': true }, 0))
.rejects.toThrow(new Error('The value of an \'@type\' must be a string, got \'true\''));
Expand Down

0 comments on commit 318e3e6

Please sign in to comment.