2
2
3
3
import { MANIFEST_FIELDS } from '../../constants' ;
4
4
import type { Reporter } from '../../reporters/index.js' ;
5
- import { isValidLicense } from './util.js' ;
5
+ import { isValidBin , isValidLicense } from './util.js' ;
6
6
import { normalizePerson , extractDescription } from './util.js' ;
7
7
import { hostedGitFragmentToGitUrl } from '../../resolvers/index.js' ;
8
8
import inferLicense from './infer-license.js' ;
@@ -12,6 +12,8 @@ const semver = require('semver');
12
12
const path = require ( 'path' ) ;
13
13
const url = require ( 'url' ) ;
14
14
15
+ const VALID_BIN_KEYS = / ^ [ a - z 0 - 9 _ - ] + $ / i;
16
+
15
17
const LICENSE_RENAMES : { [ key : string ] : ?string } = {
16
18
'MIT/X11' : 'MIT' ,
17
19
X11 : 'MIT' ,
@@ -159,6 +161,24 @@ export default (async function(
159
161
info . bin = { [ name ] : info . bin } ;
160
162
}
161
163
164
+ // Validate that the bin entries reference only files within their package, and that
165
+ // their name is a valid file name
166
+ if ( typeof info . bin === 'object' && info . bin !== null ) {
167
+ const bin : Object = info . bin ;
168
+ for ( const key of Object . keys ( bin ) ) {
169
+ const target = bin [ key ] ;
170
+ if ( ! VALID_BIN_KEYS . test ( key ) || ! isValidBin ( target ) ) {
171
+ delete bin [ key ] ;
172
+ warn ( reporter . lang ( 'invalidBinEntry' , info . name , key ) ) ;
173
+ } else {
174
+ bin [ key ] = path . normalize ( target ) ;
175
+ }
176
+ }
177
+ } else if ( typeof info . bin !== 'undefined' ) {
178
+ delete info . bin ;
179
+ warn ( reporter . lang ( 'invalidBinField' , info . name ) ) ;
180
+ }
181
+
162
182
// bundleDependencies is an alias for bundledDependencies
163
183
if ( info . bundledDependencies ) {
164
184
info . bundleDependencies = info . bundledDependencies ;
0 commit comments