4
4
var originalUncaughtExceptionListeners = process . listeners ( "uncaughtException" ) ;
5
5
6
6
var fs = require ( 'fs-extra' ) ;
7
+ var os = require ( 'os' ) ;
7
8
var path = require ( 'path' ) ;
8
9
var solc = require ( './index.js' ) ;
9
10
var smtchecker = require ( './smtchecker.js' ) ;
@@ -34,26 +35,48 @@ function abort (msg) {
34
35
process . exit ( 1 ) ;
35
36
}
36
37
37
- function readFileCallback ( path ) {
38
- path = program . basePath + '/' + path ;
39
- if ( fs . existsSync ( path ) ) {
38
+ function readFileCallback ( sourcePath ) {
39
+ if ( program . basePath )
40
+ sourcePath = program . basePath + '/' + sourcePath ;
41
+ if ( fs . existsSync ( sourcePath ) ) {
40
42
try {
41
- return { 'contents' : fs . readFileSync ( path ) . toString ( 'utf8' ) }
43
+ return { 'contents' : fs . readFileSync ( sourcePath ) . toString ( 'utf8' ) }
42
44
} catch ( e ) {
43
- return { error : 'Error reading ' + path + ': ' + e } ;
45
+ return { error : 'Error reading ' + sourcePath + ': ' + e } ;
44
46
}
45
47
} else
46
- return { error : 'File not found at ' + path }
48
+ return { error : 'File not found at ' + sourcePath }
47
49
}
48
- function stripBasePath ( path ) {
49
- if ( program . basePath && path . startsWith ( program . basePath ) )
50
- return path . slice ( program . basePath . length ) ;
51
- else
52
- return path ;
50
+
51
+ function withUnixPathSeparators ( filePath ) {
52
+ if ( os . platform !== 'win32' )
53
+ // On UNIX-like systems forward slashes in paths are just a part of the file name.
54
+ return filePath ;
55
+
56
+ return filePath . replace ( / \\ / g, "/" ) ;
57
+ }
58
+
59
+ function stripBasePath ( sourcePath ) {
60
+ const absoluteBasePath = ( program . basePath ? path . resolve ( program . basePath ) : path . resolve ( '.' ) ) ;
61
+
62
+ // Compared to base path stripping logic in solc this is much simpler because path.resolve()
63
+ // handles symlinks correctly (does not resolve them except in work dir) and strips .. segments
64
+ // from paths going beyond root (e.g. `/../../a/b/c` -> `/a/b/c/`). It's simpler also because it
65
+ // ignores less important corner cases: drive letters are not stripped from absolute paths on
66
+ // Windows and UNC paths are not handled in a special way (at least on Linux). Finally, it has
67
+ // very little test coverage so there might be more differences that we are just not aware of.
68
+ const absoluteSourcePath = path . resolve ( sourcePath ) ;
69
+ const relativeSourcePath = path . relative ( absoluteBasePath , absoluteSourcePath ) ;
70
+
71
+ if ( relativeSourcePath . startsWith ( '../' ) )
72
+ // Path can't be made relative without stepping outside of base path so return absolute one.
73
+ return withUnixPathSeparators ( absoluteSourcePath ) ;
74
+
75
+ return withUnixPathSeparators ( relativeSourcePath ) ;
53
76
}
54
77
55
78
var callbacks = undefined
56
- if ( program . basePath )
79
+ if ( program . basePath || ! program . standardJson )
57
80
callbacks = { 'import' : readFileCallback } ;
58
81
59
82
if ( program . standardJson ) {
@@ -167,4 +190,4 @@ originalUncaughtExceptionListeners.forEach(function (listener) {
167
190
168
191
if ( hasError ) {
169
192
process . exit ( 1 ) ;
170
- }
193
+ }
0 commit comments