1
1
import type { NumOrString , Path } from "@thi.ng/api" ;
2
2
import { isArray } from "@thi.ng/checks/is-array" ;
3
+ import { isNumber } from "@thi.ng/checks/is-number" ;
3
4
import { isProtoPath } from "@thi.ng/checks/is-proto-path" ;
4
5
import { isString } from "@thi.ng/checks/is-string" ;
5
- import { assert } from "@thi.ng/errors/assert " ;
6
+ import { illegalArgs } from "@thi.ng/errors/illegal-arguments " ;
6
7
7
8
/**
8
9
* Converts the given key path to canonical form (array).
9
10
*
11
+ * @remarks
12
+ * If given path is an array, performs a safety check to ensure that all path
13
+ * items are strings or numbers and that illegal paths like `[["__proto__"],
14
+ * "foo"]` will be disallowed (throws an error).
15
+ *
16
+ * Also see {@link disallowProtoPath}.
17
+ *
10
18
* ```
11
19
* toPath("a.b.c");
12
20
* // ["a", "b", "c"]
@@ -20,16 +28,20 @@ import { assert } from "@thi.ng/errors/assert";
20
28
*
21
29
* @param path -
22
30
*/
23
- export const toPath = ( path : Path ) : readonly NumOrString [ ] =>
24
- isArray ( path )
25
- ? < any [ ] > path
26
- : isString ( path )
27
- ? path . length > 0
28
- ? path . split ( "." )
29
- : [ ]
30
- : path != null
31
- ? [ path ]
32
- : [ ] ;
31
+ export const toPath = ( path : Path ) : readonly NumOrString [ ] => {
32
+ if ( isArray ( path ) ) {
33
+ if ( ! path . every ( ( x ) => isString ( x ) || isNumber ( x ) ) ) __illegal ( path ) ;
34
+ return < any [ ] > path ;
35
+ } else {
36
+ return isString ( path )
37
+ ? path . length > 0
38
+ ? path . split ( "." )
39
+ : [ ]
40
+ : path != null
41
+ ? < any [ ] > [ path ]
42
+ : [ ] ;
43
+ }
44
+ } ;
33
45
34
46
/**
35
47
* Takes an arbitrary object and lookup path. Descends into object along
@@ -59,10 +71,11 @@ export const exists = (obj: any, path: Path) => {
59
71
} ;
60
72
61
73
/**
62
- * Helper function to analyze given `path` using
74
+ * Helper function. First converts given `path` using {@link toPath} and then
75
+ * analyzes it via
63
76
* [`isProtoPath()`](https://docs.thi.ng/umbrella/checks/functions/isProtoPath.html).
64
77
* Throws an error if path contains any property which might lead to prototype
65
- * poisoning.
78
+ * poisoning. Returns converted path if valid.
66
79
*
67
80
* @remarks
68
81
* The following properties are considered illegal.
@@ -73,6 +86,12 @@ export const exists = (obj: any, path: Path) => {
73
86
*
74
87
* @param path -
75
88
*/
76
- export const disallowProtoPath = ( path : Path ) => (
77
- assert ( ! isProtoPath ( path ) , `unsafe path: '${ path } '` ) , path
78
- ) ;
89
+ export const disallowProtoPath = ( path : Path ) : readonly NumOrString [ ] => {
90
+ const $path = toPath ( path ) ;
91
+ if ( isProtoPath ( $path ) ) __illegal ( path ) ;
92
+ return $path ;
93
+ } ;
94
+
95
+ /** @internal */
96
+ const __illegal = ( path : any ) =>
97
+ illegalArgs ( `illegal path: ${ JSON . stringify ( path ) } ` ) ;
0 commit comments