@@ -190,6 +190,7 @@ const win32 = {
190190 let resolvedDevice = '' ;
191191 let resolvedTail = '' ;
192192 let resolvedAbsolute = false ;
193+ let slashCheck = false ;
193194
194195 for ( let i = args . length - 1 ; i >= - 1 ; i -- ) {
195196 let path ;
@@ -221,6 +222,10 @@ const win32 = {
221222 }
222223 }
223224
225+ if ( i === args . length - 1 &&
226+ isPathSeparator ( StringPrototypeCharCodeAt ( path , path . length - 1 ) ) ) {
227+ slashCheck = true ;
228+ }
224229 const len = path . length ;
225230 let rootEnd = 0 ;
226231 let device = '' ;
@@ -268,10 +273,16 @@ const win32 = {
268273 j ++ ;
269274 }
270275 if ( j === len || j !== last ) {
271- // We matched a UNC root
272- device =
273- `\\\\${ firstPart } \\${ StringPrototypeSlice ( path , last , j ) } ` ;
274- rootEnd = j ;
276+ if ( firstPart !== '.' && firstPart !== '?' ) {
277+ // We matched a UNC root
278+ device =
279+ `\\\\${ firstPart } \\${ StringPrototypeSlice ( path , last , j ) } ` ;
280+ rootEnd = j ;
281+ } else {
282+ // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0)
283+ device = `\\\\${ firstPart } ` ;
284+ rootEnd = 4 ;
285+ }
275286 }
276287 }
277288 }
@@ -323,9 +334,21 @@ const win32 = {
323334 resolvedTail = normalizeString ( resolvedTail , ! resolvedAbsolute , '\\' ,
324335 isPathSeparator ) ;
325336
326- return resolvedAbsolute ?
327- `${ resolvedDevice } \\${ resolvedTail } ` :
328- `${ resolvedDevice } ${ resolvedTail } ` || '.' ;
337+ if ( ! resolvedAbsolute ) {
338+ return `${ resolvedDevice } ${ resolvedTail } ` || '.' ;
339+ }
340+
341+ if ( resolvedTail . length === 0 ) {
342+ return slashCheck ? `${ resolvedDevice } \\` : resolvedDevice ;
343+ }
344+
345+ if ( slashCheck ) {
346+ return resolvedTail === '\\' ?
347+ `${ resolvedDevice } \\` :
348+ `${ resolvedDevice } \\${ resolvedTail } \\` ;
349+ }
350+
351+ return `${ resolvedDevice } \\${ resolvedTail } ` ;
329352 } ,
330353
331354 /**
@@ -381,17 +404,22 @@ const win32 = {
381404 ! isPathSeparator ( StringPrototypeCharCodeAt ( path , j ) ) ) {
382405 j ++ ;
383406 }
384- if ( j === len ) {
385- // We matched a UNC root only
386- // Return the normalized version of the UNC root since there
387- // is nothing left to process
388- return `\\\\${ firstPart } \\${ StringPrototypeSlice ( path , last ) } \\` ;
389- }
390- if ( j !== last ) {
391- // We matched a UNC root with leftovers
392- device =
393- `\\\\${ firstPart } \\${ StringPrototypeSlice ( path , last , j ) } ` ;
394- rootEnd = j ;
407+ if ( j === len || j !== last ) {
408+ if ( firstPart === '.' || firstPart === '?' ) {
409+ // We matched a device root (e.g. \\\\.\\PHYSICALDRIVE0)
410+ device = `\\\\${ firstPart } ` ;
411+ rootEnd = 4 ;
412+ } else if ( j === len ) {
413+ // We matched a UNC root only
414+ // Return the normalized version of the UNC root since there
415+ // is nothing left to process
416+ return `\\\\${ firstPart } \\${ StringPrototypeSlice ( path , last ) } \\` ;
417+ } else {
418+ // We matched a UNC root with leftovers
419+ device =
420+ `\\\\${ firstPart } \\${ StringPrototypeSlice ( path , last , j ) } ` ;
421+ rootEnd = j ;
422+ }
395423 }
396424 }
397425 }
@@ -1162,6 +1190,7 @@ const posix = {
11621190 resolve ( ...args ) {
11631191 let resolvedPath = '' ;
11641192 let resolvedAbsolute = false ;
1193+ let slashCheck = false ;
11651194
11661195 for ( let i = args . length - 1 ; i >= - 1 && ! resolvedAbsolute ; i -- ) {
11671196 const path = i >= 0 ? args [ i ] : posixCwd ( ) ;
@@ -1171,8 +1200,17 @@ const posix = {
11711200 if ( path . length === 0 ) {
11721201 continue ;
11731202 }
1203+ if ( i === args . length - 1 &&
1204+ isPosixPathSeparator ( StringPrototypeCharCodeAt ( path ,
1205+ path . length - 1 ) ) ) {
1206+ slashCheck = true ;
1207+ }
11741208
1175- resolvedPath = `${ path } /${ resolvedPath } ` ;
1209+ if ( resolvedPath . length !== 0 ) {
1210+ resolvedPath = `${ path } /${ resolvedPath } ` ;
1211+ } else {
1212+ resolvedPath = path ;
1213+ }
11761214 resolvedAbsolute =
11771215 StringPrototypeCharCodeAt ( path , 0 ) === CHAR_FORWARD_SLASH ;
11781216 }
@@ -1184,10 +1222,20 @@ const posix = {
11841222 resolvedPath = normalizeString ( resolvedPath , ! resolvedAbsolute , '/' ,
11851223 isPosixPathSeparator ) ;
11861224
1187- if ( resolvedAbsolute ) {
1188- return `/${ resolvedPath } ` ;
1225+ if ( ! resolvedAbsolute ) {
1226+ if ( resolvedPath . length === 0 ) {
1227+ return '.' ;
1228+ }
1229+ if ( slashCheck ) {
1230+ return `${ resolvedPath } /` ;
1231+ }
1232+ return resolvedPath ;
1233+ }
1234+
1235+ if ( resolvedPath . length === 0 || resolvedPath === '/' ) {
1236+ return '/' ;
11891237 }
1190- return resolvedPath . length > 0 ? resolvedPath : '.' ;
1238+ return slashCheck ? `/ ${ resolvedPath } /` : `/ ${ resolvedPath } ` ;
11911239 } ,
11921240
11931241 /**
@@ -1271,11 +1319,35 @@ const posix = {
12711319 if ( from === to )
12721320 return '' ;
12731321
1274- const fromStart = 1 ;
1275- const fromEnd = from . length ;
1322+ // Trim any leading slashes
1323+ let fromStart = 0 ;
1324+ while ( fromStart < from . length &&
1325+ StringPrototypeCharCodeAt ( from , fromStart ) === CHAR_FORWARD_SLASH ) {
1326+ fromStart ++ ;
1327+ }
1328+ // Trim trailing slashes
1329+ let fromEnd = from . length ;
1330+ while (
1331+ fromEnd - 1 > fromStart &&
1332+ StringPrototypeCharCodeAt ( from , fromEnd - 1 ) === CHAR_FORWARD_SLASH
1333+ ) {
1334+ fromEnd -- ;
1335+ }
12761336 const fromLen = fromEnd - fromStart ;
1277- const toStart = 1 ;
1278- const toLen = to . length - toStart ;
1337+
1338+ // Trim any leading slashes
1339+ let toStart = 0 ;
1340+ while ( toStart < to . length &&
1341+ StringPrototypeCharCodeAt ( to , toStart ) === CHAR_FORWARD_SLASH ) {
1342+ toStart ++ ;
1343+ }
1344+ // Trim trailing slashes
1345+ let toEnd = to . length ;
1346+ while ( toEnd - 1 > toStart &&
1347+ StringPrototypeCharCodeAt ( to , toEnd - 1 ) === CHAR_FORWARD_SLASH ) {
1348+ toEnd -- ;
1349+ }
1350+ const toLen = toEnd - toStart ;
12791351
12801352 // Compare paths to find the longest common path from root
12811353 const length = ( fromLen < toLen ? fromLen : toLen ) ;
0 commit comments