Skip to content

Commit e5b0b33

Browse files
committed
Merge branch 'fix_remote_context' of https://github.com/umbreak/jsonld-java
See #303.
2 parents b856235 + b6edd7b commit e5b0b33

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed

core/src/main/java/com/github/jsonldjava/core/Context.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ && getTermDefinition(activeProperty).containsKey(JsonLdConsts.LANGUAGE)
143143
*/
144144
@SuppressWarnings("unchecked")
145145
public Context parse(Object localContext, List<String> remoteContexts) throws JsonLdError {
146+
if (remoteContexts == null) {
147+
remoteContexts = new ArrayList<String>();
148+
}
146149
return parse(localContext, remoteContexts, false);
147150
}
148151

@@ -163,11 +166,8 @@ public Context parse(Object localContext, List<String> remoteContexts) throws Js
163166
* @throws JsonLdError
164167
* If there is an error parsing the contexts.
165168
*/
166-
private Context parse(Object localContext, List<String> remoteContexts,
169+
private Context parse(Object localContext, final List<String> remoteContexts,
167170
boolean parsingARemoteContext) throws JsonLdError {
168-
if (remoteContexts == null) {
169-
remoteContexts = new ArrayList<String>();
170-
}
171171
// 1. Initialize result to the result of cloning active context.
172172
Context result = this.clone(); // TODO: clone?
173173
// 2)
@@ -193,7 +193,8 @@ else if (context instanceof String) {
193193
if (remoteContexts.contains(uri)) {
194194
throw new JsonLdError(Error.RECURSIVE_CONTEXT_INCLUSION, uri);
195195
}
196-
remoteContexts.add(uri);
196+
List<String> nextRemoteContexts = new ArrayList<>(remoteContexts);
197+
nextRemoteContexts.add(uri);
197198

198199
// 3.2.3: Dereference context
199200
final RemoteDocument rd = this.options.getDocumentLoader().loadDocument(uri);
@@ -208,7 +209,7 @@ else if (context instanceof String) {
208209
.get(JsonLdConsts.CONTEXT);
209210

210211
// 3.2.4
211-
result = result.parse(tempContext, remoteContexts, true);
212+
result = result.parse(tempContext, nextRemoteContexts, true);
212213
// 3.2.5
213214
continue;
214215
} else if (!(context instanceof Map)) {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package com.github.jsonldjava.core;
2+
3+
import com.github.jsonldjava.utils.JsonUtils;
4+
import org.junit.AfterClass;
5+
import org.junit.BeforeClass;
6+
import org.junit.Test;
7+
8+
import java.io.IOException;
9+
10+
import static org.junit.Assert.assertEquals;
11+
import static org.junit.Assert.fail;
12+
13+
14+
public class ContextRecursionTest {
15+
16+
@BeforeClass
17+
public static void setup() {
18+
System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "true");
19+
}
20+
21+
@AfterClass
22+
public static void tearDown() {
23+
System.setProperty(DocumentLoader.DISALLOW_REMOTE_CONTEXT_LOADING, "false");
24+
}
25+
26+
@Test
27+
public void testIssue302_allowedRecursion() throws IOException {
28+
29+
final String contextB = "{\"@context\": [\"http://localhost/d\", {\"b\": \"http://localhost/b\"} ] }";
30+
final String contextC = "{\"@context\": [\"http://localhost/d\", {\"c\": \"http://localhost/c\"} ] }";
31+
final String contextD = "{\"@context\": [\"http://localhost/e\", {\"d\": \"http://localhost/d\"} ] }";
32+
final String contextE = "{\"@context\": {\"e\": \"http://localhost/e\"} }";
33+
34+
final DocumentLoader dl = new DocumentLoader();
35+
dl.addInjectedDoc("http://localhost/b", contextB);
36+
dl.addInjectedDoc("http://localhost/c", contextC);
37+
dl.addInjectedDoc("http://localhost/d", contextD);
38+
dl.addInjectedDoc("http://localhost/e", contextE);
39+
final JsonLdOptions options = new JsonLdOptions();
40+
options.setDocumentLoader(dl);
41+
42+
final String jsonString = "{\"@context\": [\"http://localhost/d\", \"http://localhost/b\", \"http://localhost/c\", {\"a\": \"http://localhost/a\"} ], \"a\": \"A\", \"b\": \"B\", \"c\": \"C\", \"d\": \"D\"}";
43+
final Object json = JsonUtils.fromString(jsonString);
44+
final Object expanded = JsonLdProcessor.expand(json, options);
45+
assertEquals(
46+
"[{http://localhost/a=[{@value=A}], http://localhost/b=[{@value=B}], http://localhost/c=[{@value=C}], http://localhost/d=[{@value=D}]}]",
47+
expanded.toString());
48+
}
49+
50+
@Test
51+
public void testCyclicRecursion() throws IOException {
52+
53+
final String contextC = "{\"@context\": [\"http://localhost/d\", {\"c\": \"http://localhost/c\"} ] }";
54+
final String contextD = "{\"@context\": [\"http://localhost/e\", {\"d\": \"http://localhost/d\"} ] }";
55+
final String contextE = "{\"@context\": [\"http://localhost/c\", {\"e\": \"http://localhost/e\"} ] }";
56+
57+
final DocumentLoader dl = new DocumentLoader();
58+
dl.addInjectedDoc("http://localhost/c", contextC);
59+
dl.addInjectedDoc("http://localhost/d", contextD);
60+
dl.addInjectedDoc("http://localhost/e", contextE);
61+
final JsonLdOptions options = new JsonLdOptions();
62+
options.setDocumentLoader(dl);
63+
64+
final String jsonString = "{\"@context\": [\"http://localhost/c\", {\"a\": \"http://localhost/a\"} ]}";
65+
final Object json = JsonUtils.fromString(jsonString);
66+
try {
67+
JsonLdProcessor.expand(json, options);
68+
fail("it should throw");
69+
} catch(JsonLdError err) {
70+
assertEquals(JsonLdError.Error.RECURSIVE_CONTEXT_INCLUSION, err.getType());
71+
assertEquals("recursive context inclusion: http://localhost/c", err.getMessage());
72+
}
73+
}
74+
75+
}

0 commit comments

Comments
 (0)