shared.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. const {
  2. CHAR_DOT,
  3. CHAR_FORWARD_SLASH
  4. } = require('./constants')
  5. exports.normalizeString = function normalizeString (path, allowAboveRoot, separator, isPathSeparator) {
  6. let res = ''
  7. let lastSegmentLength = 0
  8. let lastSlash = -1
  9. let dots = 0
  10. let code = 0
  11. for (let i = 0; i <= path.length; ++i) {
  12. if (i < path.length) {
  13. code = path.charCodeAt(i)
  14. } else if (isPathSeparator(code)) {
  15. break
  16. } else {
  17. code = CHAR_FORWARD_SLASH
  18. }
  19. if (isPathSeparator(code)) {
  20. if (lastSlash === i - 1 || dots === 1) ;
  21. else if (dots === 2) {
  22. if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== CHAR_DOT || res.charCodeAt(res.length - 2) !== CHAR_DOT) {
  23. if (res.length > 2) {
  24. const lastSlashIndex = res.lastIndexOf(separator)
  25. if (lastSlashIndex === -1) {
  26. res = ''
  27. lastSegmentLength = 0
  28. } else {
  29. res = res.substring(0, lastSlashIndex)
  30. lastSegmentLength =
  31. res.length - 1 - res.lastIndexOf(separator)
  32. }
  33. lastSlash = i
  34. dots = 0
  35. continue
  36. } else if (res.length !== 0) {
  37. res = ''
  38. lastSegmentLength = 0
  39. lastSlash = i
  40. dots = 0
  41. continue
  42. }
  43. }
  44. if (allowAboveRoot) {
  45. res += res.length > 0 ? `${separator}..` : '..'
  46. lastSegmentLength = 2
  47. }
  48. } else {
  49. if (res.length > 0) {
  50. res += `${separator}${path.substring(lastSlash + 1, i)}`
  51. } else {
  52. res = path.substring(lastSlash + 1, i)
  53. }
  54. lastSegmentLength = i - lastSlash - 1
  55. }
  56. lastSlash = i
  57. dots = 0
  58. } else if (code === CHAR_DOT && dots !== -1) {
  59. ++dots
  60. } else {
  61. dots = -1
  62. }
  63. }
  64. return res
  65. }