Skip to content

Commit dd10265

Browse files
committed
some fixes for path traversal
1 parent 93f0d44 commit dd10265

File tree

2 files changed

+64
-20
lines changed

2 files changed

+64
-20
lines changed

src/docTree.spec.ts

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,24 @@ describe('docTree', () => {
203203
});
204204

205205
test('should not return siblings for root platform or guide paths', () => {
206-
expect(
207-
getNextNode(createNode('platforms/javascript', 'JavaScript'))
208-
).toBeUndefined();
209-
expect(
210-
getNextNode(createNode('platforms/javascript/guides/nextjs', 'Next.js'))
211-
).toBeUndefined();
206+
const platforms = createNode('platforms', 'Platforms');
207+
const js = createNode('platforms/javascript', 'JavaScript');
208+
const python = createNode('platforms/python', 'Python');
209+
platforms.children = [js, python];
210+
platforms.children.forEach(child => {
211+
child.parent = platforms;
212+
});
213+
214+
const nextjs = createNode('platforms/javascript/guides/nextjs', 'Next.js');
215+
const angular = createNode('platforms/javascript/guides/angular', 'Angular');
216+
js.children = [nextjs, angular];
217+
js.children.forEach(child => {
218+
child.parent = js;
219+
});
220+
221+
expect(getNextNode(js)).toBeUndefined();
222+
expect(getNextNode(nextjs)).toBeUndefined();
223+
expect(getNextNode(angular)).toBeUndefined();
212224
});
213225
});
214226

@@ -259,12 +271,37 @@ describe('docTree', () => {
259271
});
260272

261273
test('should not return siblings for root platform or guide paths', () => {
262-
expect(
263-
getPreviousNode(createNode('platforms/javascript', 'JavaScript'))
264-
).toBeUndefined();
265-
expect(
266-
getPreviousNode(createNode('platforms/javascript/guides/nextjs', 'Next.js'))
267-
).toBeUndefined();
274+
const platforms = createNode('platforms', 'Platforms');
275+
const js = createNode('platforms/javascript', 'JavaScript');
276+
const python = createNode('platforms/python', 'Python');
277+
platforms.children = [js, python];
278+
platforms.children.forEach(child => {
279+
child.parent = platforms;
280+
});
281+
282+
const nextjs = createNode('platforms/javascript/guides/nextjs', 'Next.js');
283+
const angular = createNode('platforms/javascript/guides/angular', 'Angular');
284+
js.children = [nextjs, angular];
285+
js.children.forEach(child => {
286+
child.parent = js;
287+
});
288+
289+
expect(getPreviousNode(js)).toBe(undefined);
290+
expect(getPreviousNode(python)).toBe(undefined);
291+
expect(getPreviousNode(nextjs)).toBe(undefined);
292+
expect(getPreviousNode(angular)).toBe(undefined);
293+
});
294+
295+
test('should not return /platforms as previous page', () => {
296+
const docs = createNode('', 'Docs');
297+
const platforms = createNode('platforms', 'Platforms');
298+
const accounts = createNode('accounts', 'Accounts');
299+
docs.children = [platforms, accounts];
300+
docs.children.forEach(child => {
301+
child.parent = docs;
302+
});
303+
304+
expect(getPreviousNode(accounts)).toBe(undefined);
268305
});
269306
});
270307

src/docTree.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,22 @@ export function nodeForPath(node: DocNode, path: string | string[]): DocNode | u
156156
export const getNextNode = (node: DocNode): DocNode | undefined => {
157157
const children = node.children.filter(filterVisibleSiblings).sort(sortSiblingsByOrder);
158158
// Check for children first
159-
if (children.length > 0) {
159+
if (
160+
children.length > 0 &&
161+
!isRootPlatformPath(children[0].path) &&
162+
!isRootGuidePath(children[0].path)
163+
) {
160164
return children[0];
161165
}
162166

163167
// If no children, look for siblings or parent siblings
164168
let currentNode: DocNode | undefined = node;
165169
while (currentNode?.parent) {
166-
if (
167-
isRootPlatformPath(currentNode.parent.path) ||
168-
isRootGuidePath(currentNode.parent.path)
169-
) {
170-
return undefined;
171-
}
172-
173170
const nextSibling = getNextSiblingNode(currentNode);
174171
if (nextSibling) {
172+
if (isRootPlatformPath(nextSibling.path) || isRootGuidePath(nextSibling.path)) {
173+
return undefined;
174+
}
175175
return nextSibling;
176176
}
177177
currentNode = currentNode.parent;
@@ -186,8 +186,15 @@ export const getNextNode = (node: DocNode): DocNode | undefined => {
186186
* the previous sibling, or the previous sibling of a parent node.
187187
*/
188188
export const getPreviousNode = (node: DocNode): DocNode | undefined => {
189+
if (isRootPlatformPath(node.path) || isRootGuidePath(node.path)) {
190+
return undefined;
191+
}
192+
189193
const previousSibling = getPreviousSiblingNode(node);
190194
if (previousSibling) {
195+
if (previousSibling.path === 'platforms') {
196+
return undefined;
197+
}
191198
return previousSibling;
192199
}
193200
return node.parent;

0 commit comments

Comments
 (0)