Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.

Commit 95df0a9

Browse files
authored
Handle invalid schema object examples in OAS 2 (#221)
Handle invalid schema object examples in OAS 2
2 parents 97ff945 + 09bfa6d commit 95df0a9

File tree

6 files changed

+131
-8
lines changed

6 files changed

+131
-8
lines changed

packages/fury-adapter-swagger/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Fury Swagger Parser Changelog
22

3+
## 0.25.1 (2019-04-26)
4+
5+
### Bug Fixes
6+
7+
- Fixes a potential parser crash while handling an example value for a 'Schema
8+
Object' which contains an invalid reference.
9+
310
## 0.25.0 (2019-03-26)
411

512
### Enhancements

packages/fury-adapter-swagger/lib/json-schema.js

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ if (!Object.values) {
66
values.shim();
77
}
88

9+
class ReferenceError extends Error {}
10+
911
// Test whether a key is a special Swagger extension.
1012
const isExtension = (value, key) => _.startsWith(key, 'x-');
1113

1214
const parseReference = (reference) => {
1315
const parts = reference.split('/');
1416

1517
if (parts[0] !== '#') {
16-
throw new Error('Schema reference must start with document root (#)');
18+
throw new ReferenceError('Schema reference must start with document root (#)');
1719
}
1820

1921
if (parts[1] !== 'definitions' || parts.length !== 3) {
20-
throw new Error('Schema reference must be reference to #/definitions');
22+
throw new ReferenceError('Schema reference must be reference to #/definitions');
2123
}
2224

2325
const id = parts[2];
@@ -43,11 +45,11 @@ const lookupReference = (reference, root, depth) => {
4345
const parts = reference.split('/').reverse();
4446

4547
if (parts.pop() !== '#') {
46-
throw new Error('Schema reference must start with document root (#)');
48+
throw new ReferenceError('Schema reference must start with document root (#)');
4749
}
4850

4951
if (parts.pop() !== 'definitions') {
50-
throw new Error('Schema reference must be reference to #/definitions');
52+
throw new ReferenceError('Schema reference must be reference to #/definitions');
5153
}
5254

5355
const id = parts[parts.length - 1];
@@ -67,7 +69,7 @@ const lookupReference = (reference, root, depth) => {
6769
}
6870

6971
if (value === undefined) {
70-
throw new Error(`Reference to ${reference} does not exist`);
72+
throw new ReferenceError(`Reference to ${reference} does not exist`);
7173
}
7274

7375
return {
@@ -93,6 +95,20 @@ const pathHasCircularReference = (paths, path, reference) => {
9395
};
9496

9597
const dereference = (example, root, paths, path) => {
98+
// We shouldn't even be dereferencing examples, but given how swagger-parser
99+
// works it had been doing this from the start (which was caught later).
100+
//
101+
// See https://github.com/apiaryio/api-elements.js/issues/220
102+
//
103+
// At thsi point, changing that behaviour would be a significant breaking
104+
// change and it will affect some of our larger users. Not to mention that
105+
// swagger-parser will still dereference the examples in cases where our code
106+
// path doesn't, it won't be easy to solve.
107+
//
108+
// The below code attemps to dereference an example, but if we can't we
109+
// will just return the example (possibly a "reference object") to be
110+
// the example value.
111+
96112
if (example === null || example === undefined) {
97113
return example;
98114
}
@@ -105,7 +121,18 @@ const dereference = (example, root, paths, path) => {
105121
return null;
106122
}
107123

108-
const ref = lookupReference(example.$ref, root);
124+
let ref;
125+
126+
try {
127+
ref = lookupReference(example.$ref, root);
128+
} catch (error) {
129+
if (error instanceof ReferenceError) {
130+
// Cannot find the reference, use example
131+
return example;
132+
}
133+
134+
throw error;
135+
}
109136

110137
const newPaths = (paths || []).concat([currentPath]);
111138
return dereference(ref.referenced, root, newPaths, refPath);

packages/fury-adapter-swagger/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "fury-adapter-swagger",
3-
"version": "0.25.0",
3+
"version": "0.25.1",
44
"description": "Swagger 2.0 parser for Fury.js",
55
"author": "Apiary.io <[email protected]>",
66
"license": "MIT",
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"element": "parseResult",
3+
"content": [
4+
{
5+
"element": "category",
6+
"meta": {
7+
"classes": {
8+
"element": "array",
9+
"content": [
10+
{
11+
"element": "string",
12+
"content": "api"
13+
}
14+
]
15+
},
16+
"title": {
17+
"element": "string",
18+
"content": "My API"
19+
}
20+
},
21+
"attributes": {
22+
"version": {
23+
"element": "string",
24+
"content": "1.0.0"
25+
}
26+
},
27+
"content": [
28+
{
29+
"element": "category",
30+
"meta": {
31+
"classes": {
32+
"element": "array",
33+
"content": [
34+
{
35+
"element": "string",
36+
"content": "dataStructures"
37+
}
38+
]
39+
}
40+
},
41+
"content": [
42+
{
43+
"element": "dataStructure",
44+
"content": {
45+
"element": "array",
46+
"meta": {
47+
"id": {
48+
"element": "string",
49+
"content": "definitions/Test"
50+
}
51+
},
52+
"content": [
53+
{
54+
"element": "object",
55+
"content": [
56+
{
57+
"element": "member",
58+
"content": {
59+
"key": {
60+
"element": "string",
61+
"content": "$ref"
62+
},
63+
"value": {
64+
"element": "string",
65+
"content": "#/info"
66+
}
67+
}
68+
}
69+
]
70+
}
71+
]
72+
}
73+
}
74+
]
75+
}
76+
]
77+
}
78+
]
79+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
swagger: '2.0'
2+
info:
3+
title: My API
4+
version: 1.0.0
5+
paths: {}
6+
definitions:
7+
Test:
8+
type: array
9+
example:
10+
- $ref: '#/info'

packages/fury-cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"fury-adapter-apib-parser": "^0.14.0",
2727
"fury-adapter-apib-serializer": "^0.10.0",
2828
"fury-adapter-oas3-parser": "^0.7.4",
29-
"fury-adapter-swagger": "^0.25.0",
29+
"fury-adapter-swagger": "^0.25.1",
3030
"js-yaml": "^3.12.0",
3131
"minim": "^0.23.1"
3232
},

0 commit comments

Comments
 (0)