Skip to content

Commit 3098c63

Browse files
committed
Fix usage of JS Object property names in data.
- Fixed usage of JavaScript Object property names in data. - **NOTE**: A class of bugs was causing term names such as `toString`, `valueOf`, and others to be dropped or produce bogus output. The fix could cause output triples to differ from previous versions if those special names were used. - Specifically, the problem was using `x in obj` instead of `obj.hasOwnProperty(x)` or a `Map`. - Fixed usage in contexts for expand and compact. - Attempted fixes in other parts of the code with similar `x in obj` usage. Finding actual realistic failing test cases proved difficult. - Help would be appreciated making test cases or finding other locations with a similar issue. - A few cleanups.
1 parent c3ee8fe commit 3098c63

File tree

6 files changed

+242
-66
lines changed

6 files changed

+242
-66
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
# jsonld ChangeLog
22

3+
## 1.6.0 - 2019-03-xx
4+
35
### Fixed
46
- Testing: Use explicit id and description skipping regexes.
7+
- Usage of JavaScript Object property names in data.
8+
- **NOTE**: A class of bugs was causing term names such as `toString`,
9+
`valueOf`, and others to be dropped or produce bogus output. The fix could
10+
cause output triples to differ from previous versions if those special
11+
names were used.
12+
- Specifically, the problem was using `x in obj` instead of
13+
`obj.hasOwnProperty(x)` or a `Map`.
14+
- Fixed usage in contexts for expand and compact.
15+
- Attempted fixes in other parts of the code with similar `x in obj` usage.
16+
Finding actual realistic failing test cases proved difficult.
17+
- Help would be appreciated making test cases or finding other locations with
18+
a similar issue.
519

620
### Changed
721
- Testing: Improve skip logging.

lib/compact.js

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ api.compact = ({
113113

114114
// recursively compact object
115115
if(_isObject(element)) {
116-
if(options.link && '@id' in element && element['@id'] in options.link) {
116+
if(options.link && '@id' in element &&
117+
options.link.hasOwnProperty(element['@id'])) {
117118
// check for a linked element to reuse
118119
const linked = options.link[element['@id']];
119120
for(let i = 0; i < linked.length; ++i) {
@@ -129,7 +130,7 @@ api.compact = ({
129130
api.compactValue({activeCtx, activeProperty, value: element, options});
130131
if(options.link && _isSubjectReference(element)) {
131132
// store linked element
132-
if(!(element['@id'] in options.link)) {
133+
if(!(options.link.hasOwnProperty(element['@id']))) {
133134
options.link[element['@id']] = [];
134135
}
135136
options.link[element['@id']].push({expanded: element, compacted: rval});
@@ -144,7 +145,7 @@ api.compact = ({
144145

145146
if(options.link && '@id' in element) {
146147
// store linked element
147-
if(!(element['@id'] in options.link)) {
148+
if(!options.link.hasOwnProperty(element['@id'])) {
148149
options.link[element['@id']] = [];
149150
}
150151
options.link[element['@id']].push({expanded: element, compacted: rval});
@@ -208,8 +209,8 @@ api.compact = ({
208209

209210
// handle double-reversed properties
210211
for(const compactedProperty in compactedValue) {
211-
if(activeCtx.mappings[compactedProperty] &&
212-
activeCtx.mappings[compactedProperty].reverse) {
212+
if(activeCtx.mappings.has(compactedProperty) &&
213+
activeCtx.mappings.get(compactedProperty).reverse) {
213214
const value = compactedValue[compactedProperty];
214215
const container = _getContextValue(
215216
activeCtx, compactedProperty, '@container') || [];
@@ -297,8 +298,8 @@ api.compact = ({
297298
relativeTo: {vocab: true},
298299
reverse: insideReverse
299300
});
300-
const nestProperty = (itemActiveProperty in activeCtx.mappings) ?
301-
activeCtx.mappings[itemActiveProperty]['@nest'] : null;
301+
const nestProperty = activeCtx.mappings.has(itemActiveProperty) ?
302+
activeCtx.mappings.get(itemActiveProperty)['@nest'] : null;
302303
let nestResult = rval;
303304
if(nestProperty) {
304305
_checkNestProperty(activeCtx, nestProperty, options);
@@ -326,8 +327,8 @@ api.compact = ({
326327

327328
// if itemActiveProperty is a @nest property, add values to nestResult,
328329
// otherwise rval
329-
const nestProperty = (itemActiveProperty in activeCtx.mappings) ?
330-
activeCtx.mappings[itemActiveProperty]['@nest'] : null;
330+
const nestProperty = activeCtx.mappings.has(itemActiveProperty) ?
331+
activeCtx.mappings.get(itemActiveProperty)['@nest'] : null;
331332
let nestResult = rval;
332333
if(nestProperty) {
333334
_checkNestProperty(activeCtx, nestProperty, options);
@@ -384,7 +385,7 @@ api.compact = ({
384385
relativeTo: {vocab: true}
385386
})] = expandedItem['@index'];
386387
}
387-
} else if(itemActiveProperty in nestResult) {
388+
} else if(nestResult.hasOwnProperty(itemActiveProperty)) {
388389
// can't use @list container for more than 1 list
389390
throw new JsonLdError(
390391
'JSON-LD compact error; property has a "@list" @container ' +
@@ -401,7 +402,7 @@ api.compact = ({
401402
container.includes('@index') && _isSimpleGraph(expandedItem))) {
402403
// get or create the map object
403404
let mapObject;
404-
if(itemActiveProperty in nestResult) {
405+
if(nestResult.hasOwnProperty(itemActiveProperty)) {
405406
mapObject = nestResult[itemActiveProperty];
406407
} else {
407408
nestResult[itemActiveProperty] = mapObject = {};
@@ -472,7 +473,7 @@ api.compact = ({
472473
// handle language and index maps
473474
// get or create the map object
474475
let mapObject;
475-
if(itemActiveProperty in nestResult) {
476+
if(nestResult.hasOwnProperty(itemActiveProperty)) {
476477
mapObject = nestResult[itemActiveProperty];
477478
} else {
478479
nestResult[itemActiveProperty] = mapObject = {};
@@ -736,7 +737,7 @@ api.compactIri = ({
736737
if(iri.indexOf(vocab) === 0 && iri !== vocab) {
737738
// use suffix as relative iri if it is not a term in the active context
738739
const suffix = iri.substr(vocab.length);
739-
if(!(suffix in activeCtx.mappings)) {
740+
if(!activeCtx.mappings.has(suffix)) {
740741
return suffix;
741742
}
742743
}
@@ -767,9 +768,9 @@ api.compactIri = ({
767768
// 2. value is null, which means we're not compacting an @value, AND
768769
// the mapping matches the IRI
769770
const curie = term + ':' + iri.substr(entry.iri.length);
770-
const isUsableCurie = (activeCtx.mappings[term]._prefix &&
771-
(!(curie in activeCtx.mappings) ||
772-
(value === null && activeCtx.mappings[curie]['@id'] === iri)));
771+
const isUsableCurie = (activeCtx.mappings.get(term)._prefix &&
772+
(!activeCtx.mappings.has(curie) ||
773+
(value === null && activeCtx.mappings.get(curie)['@id'] === iri)));
773774

774775
// select curie if it is shorter or the same length but lexicographically
775776
// less than the current choice
@@ -834,8 +835,8 @@ api.compactValue = ({activeCtx, activeProperty, value, options}) => {
834835
(keyCount === 2 && '@index' in value && !preserveIndex));
835836
const hasDefaultLanguage = ('@language' in activeCtx);
836837
const isValueString = _isString(value['@value']);
837-
const hasNullMapping = (activeCtx.mappings[activeProperty] &&
838-
activeCtx.mappings[activeProperty]['@language'] === null);
838+
const hasNullMapping = (activeCtx.mappings.has(activeProperty) &&
839+
activeCtx.mappings.get(activeProperty)['@language'] === null);
839840
if(isValueOnlyKey &&
840841
(!hasDefaultLanguage || !isValueString || hasNullMapping)) {
841842
return value['@value'];
@@ -948,9 +949,9 @@ api.removePreserve = (ctx, input, options) => {
948949
iri: '@id',
949950
relativeTo: {vocab: true}
950951
});
951-
if(idAlias in input) {
952+
if(input.hasOwnProperty(idAlias)) {
952953
const id = input[idAlias];
953-
if(id in options.link) {
954+
if(options.link.hasOwnProperty(id)) {
954955
const idx = options.link[id].indexOf(input);
955956
if(idx !== -1) {
956957
// already visited
@@ -1020,9 +1021,9 @@ function _selectTerm(
10201021
// try to compact value to a term
10211022
const term = api.compactIri(
10221023
{activeCtx, iri: value['@id'], relativeTo: {vocab: true}});
1023-
if(term in activeCtx.mappings &&
1024-
activeCtx.mappings[term] &&
1025-
activeCtx.mappings[term]['@id'] === value['@id']) {
1024+
if(activeCtx.mappings.has(term) &&
1025+
activeCtx.mappings.get(term) &&
1026+
activeCtx.mappings.get(term)['@id'] === value['@id']) {
10261027
// prefer @vocab
10271028
prefs.push.apply(prefs, ['@vocab', '@id']);
10281029
} else {

0 commit comments

Comments
 (0)