6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
import { execSync } from 'child_process' ;
9
+ import * as fs from 'fs' ;
9
10
import * as path from 'path' ;
10
11
import * as semver from 'semver' ;
11
12
import { Arguments , Option } from '../models/interface' ;
@@ -22,10 +23,7 @@ import { Schema as UpdateCommandSchema } from './update';
22
23
23
24
const npa = require ( 'npm-package-arg' ) ;
24
25
25
- const oldConfigFileNames = [
26
- '.angular-cli.json' ,
27
- 'angular-cli.json' ,
28
- ] ;
26
+ const oldConfigFileNames = [ '.angular-cli.json' , 'angular-cli.json' ] ;
29
27
30
28
export class UpdateCommand extends SchematicCommand < UpdateCommandSchema > {
31
29
public readonly allowMissingWorkspace = true ;
@@ -184,12 +182,45 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
184
182
} else if ( typeof migrations !== 'string' ) {
185
183
this . logger . error ( 'Package contains a malformed migrations field.' ) ;
186
184
185
+ return 1 ;
186
+ } else if ( path . posix . isAbsolute ( migrations ) || path . win32 . isAbsolute ( migrations ) ) {
187
+ this . logger . error (
188
+ 'Package contains an invalid migrations field. Absolute paths are not permitted.' ,
189
+ ) ;
190
+
187
191
return 1 ;
188
192
}
189
193
190
- // if not non-relative, add package name
191
- if ( migrations . startsWith ( '.' ) || migrations . startsWith ( '/' ) ) {
192
- migrations = path . join ( packageName , migrations ) ;
194
+ // Normalize slashes
195
+ migrations = migrations . replace ( / \\ / g, '/' ) ;
196
+
197
+ if ( migrations . startsWith ( '../' ) ) {
198
+ this . logger . error (
199
+ 'Package contains an invalid migrations field. ' +
200
+ 'Paths outside the package root are not permitted.' ,
201
+ ) ;
202
+
203
+ return 1 ;
204
+ }
205
+
206
+ // Check if it is a package-local location
207
+ const localMigrations = path . join ( packageNode . path , migrations ) ;
208
+ if ( fs . existsSync ( localMigrations ) ) {
209
+ migrations = localMigrations ;
210
+ } else {
211
+ // Try to resolve from package location.
212
+ // This avoids issues with package hoisting.
213
+ try {
214
+ migrations = require . resolve ( migrations , { paths : [ packageNode . path ] } ) ;
215
+ } catch ( e ) {
216
+ if ( e . code === 'MODULE_NOT_FOUND' ) {
217
+ this . logger . error ( 'Migrations for package were not found.' ) ;
218
+ } else {
219
+ this . logger . error ( `Unable to resolve migrations for package. [${ e . message } ]` ) ;
220
+ }
221
+
222
+ return 1 ;
223
+ }
193
224
}
194
225
195
226
return this . runSchematic ( {
@@ -219,9 +250,11 @@ export class UpdateCommand extends SchematicCommand<UpdateCommandSchema> {
219
250
}
220
251
221
252
// If a specific version is requested and matches the installed version, skip.
222
- if ( pkg . type === 'version' &&
223
- typeof node === 'object' &&
224
- node . package . version === pkg . fetchSpec ) {
253
+ if (
254
+ pkg . type === 'version' &&
255
+ typeof node === 'object' &&
256
+ node . package . version === pkg . fetchSpec
257
+ ) {
225
258
this . logger . info ( `Package '${ pkg . name } ' is already at '${ pkg . fetchSpec } '.` ) ;
226
259
continue ;
227
260
}
0 commit comments