SafePathTests.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /* eslint-disable
  2. max-len,
  3. no-return-assign,
  4. no-unused-vars,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. const { assert, expect } = require('chai')
  14. const sinon = require('sinon')
  15. const modulePath = '../../../../app/src/Features/Project/SafePath'
  16. const SandboxedModule = require('sandboxed-module')
  17. describe('SafePath', function () {
  18. beforeEach(function () {
  19. return (this.SafePath = SandboxedModule.require(modulePath))
  20. })
  21. describe('isCleanFilename', function () {
  22. it('should accept a valid filename "main.tex"', function () {
  23. const result = this.SafePath.isCleanFilename('main.tex')
  24. return result.should.equal(true)
  25. })
  26. it('should not accept an empty filename', function () {
  27. const result = this.SafePath.isCleanFilename('')
  28. return result.should.equal(false)
  29. })
  30. it('should not accept / anywhere', function () {
  31. const result = this.SafePath.isCleanFilename('foo/bar')
  32. return result.should.equal(false)
  33. })
  34. it('should not accept .', function () {
  35. const result = this.SafePath.isCleanFilename('.')
  36. return result.should.equal(false)
  37. })
  38. it('should not accept ..', function () {
  39. const result = this.SafePath.isCleanFilename('..')
  40. return result.should.equal(false)
  41. })
  42. it('should not accept * anywhere', function () {
  43. const result = this.SafePath.isCleanFilename('foo*bar')
  44. return result.should.equal(false)
  45. })
  46. it('should not accept leading whitespace', function () {
  47. const result = this.SafePath.isCleanFilename(' foobar.tex')
  48. return result.should.equal(false)
  49. })
  50. it('should not accept trailing whitespace', function () {
  51. const result = this.SafePath.isCleanFilename('foobar.tex ')
  52. return result.should.equal(false)
  53. })
  54. it('should not accept leading and trailing whitespace', function () {
  55. const result = this.SafePath.isCleanFilename(' foobar.tex ')
  56. return result.should.equal(false)
  57. })
  58. it('should not accept control characters (0-31)', function () {
  59. const result = this.SafePath.isCleanFilename('foo\u0010bar')
  60. return result.should.equal(false)
  61. })
  62. it('should not accept control characters (127, delete)', function () {
  63. const result = this.SafePath.isCleanFilename('foo\u007fbar')
  64. return result.should.equal(false)
  65. })
  66. it('should not accept control characters (128-159)', function () {
  67. const result = this.SafePath.isCleanFilename('foo\u0080\u0090bar')
  68. return result.should.equal(false)
  69. })
  70. it('should not accept surrogate characters (128-159)', function () {
  71. const result = this.SafePath.isCleanFilename('foo\uD800\uDFFFbar')
  72. return result.should.equal(false)
  73. })
  74. it('should accept javascript property names', function () {
  75. const result = this.SafePath.isCleanFilename('prototype')
  76. return result.should.equal(true)
  77. })
  78. it('should accept javascript property names in the prototype', function () {
  79. const result = this.SafePath.isCleanFilename('hasOwnProperty')
  80. return result.should.equal(true)
  81. })
  82. // this test never worked correctly because the spaces are not replaced by underscores in isCleanFilename
  83. // it 'should not accept javascript property names resulting from substitutions', ->
  84. // result = @SafePath.isCleanFilename ' proto '
  85. // result.should.equal false
  86. // it 'should not accept a trailing .', ->
  87. // result = @SafePath.isCleanFilename 'hello.'
  88. // result.should.equal false
  89. it('should not accept \\', function () {
  90. const result = this.SafePath.isCleanFilename('foo\\bar')
  91. return result.should.equal(false)
  92. })
  93. it('should reject filenames regardless of order (/g) for bad characters', function () {
  94. const result1 = this.SafePath.isCleanFilename('foo*bar.tex') // * is not allowed
  95. const result2 = this.SafePath.isCleanFilename('*foobar.tex') // bad char location is before previous match
  96. return result1.should.equal(false) && result2.should.equal(false)
  97. })
  98. it('should reject filenames regardless of order (/g) for bad filenames', function () {
  99. const result1 = this.SafePath.isCleanFilename('foo ') // trailing space
  100. const result2 = this.SafePath.isCleanFilename(' foobar') // leading space, match location is before previous match
  101. return result1.should.equal(false) && result2.should.equal(false)
  102. })
  103. })
  104. describe('isCleanPath', function () {
  105. it('should accept a valid filename "main.tex"', function () {
  106. const result = this.SafePath.isCleanPath('main.tex')
  107. return result.should.equal(true)
  108. })
  109. it('should accept a valid path "foo/main.tex"', function () {
  110. const result = this.SafePath.isCleanPath('foo/main.tex')
  111. return result.should.equal(true)
  112. })
  113. it('should accept empty path elements', function () {
  114. const result = this.SafePath.isCleanPath('foo//main.tex')
  115. return result.should.equal(true)
  116. })
  117. it('should not accept an empty filename', function () {
  118. const result = this.SafePath.isCleanPath('foo/bar/')
  119. return result.should.equal(false)
  120. })
  121. it('should accept a path that starts with a slash', function () {
  122. const result = this.SafePath.isCleanPath('/etc/passwd')
  123. return result.should.equal(true)
  124. })
  125. it('should not accept a path that has an asterisk as the 0th element', function () {
  126. const result = this.SafePath.isCleanPath('*/foo/bar')
  127. return result.should.equal(false)
  128. })
  129. it('should not accept a path that has an asterisk as a middle element', function () {
  130. const result = this.SafePath.isCleanPath('foo/*/bar')
  131. return result.should.equal(false)
  132. })
  133. it('should not accept a path that has an asterisk as the filename', function () {
  134. const result = this.SafePath.isCleanPath('foo/bar/*')
  135. return result.should.equal(false)
  136. })
  137. it('should not accept a path that contains an asterisk in the 0th element', function () {
  138. const result = this.SafePath.isCleanPath('f*o/bar/baz')
  139. return result.should.equal(false)
  140. })
  141. it('should not accept a path that contains an asterisk in a middle element', function () {
  142. const result = this.SafePath.isCleanPath('foo/b*r/baz')
  143. return result.should.equal(false)
  144. })
  145. it('should not accept a path that contains an asterisk in the filename', function () {
  146. const result = this.SafePath.isCleanPath('foo/bar/b*z')
  147. return result.should.equal(false)
  148. })
  149. it('should not accept multiple problematic elements', function () {
  150. const result = this.SafePath.isCleanPath('f*o/b*r/b*z')
  151. return result.should.equal(false)
  152. })
  153. it('should not accept a problematic path with an empty element', function () {
  154. const result = this.SafePath.isCleanPath('foo//*/bar')
  155. return result.should.equal(false)
  156. })
  157. it('should not accept javascript property names', function () {
  158. const result = this.SafePath.isCleanPath('prototype')
  159. return result.should.equal(false)
  160. })
  161. it('should not accept javascript property names in the prototype', function () {
  162. const result = this.SafePath.isCleanPath('hasOwnProperty')
  163. return result.should.equal(false)
  164. })
  165. it('should not accept javascript property names resulting from substitutions', function () {
  166. const result = this.SafePath.isCleanPath(' proto ')
  167. return result.should.equal(false)
  168. })
  169. })
  170. describe('isAllowedLength', function () {
  171. it('should accept a valid path "main.tex"', function () {
  172. const result = this.SafePath.isAllowedLength('main.tex')
  173. return result.should.equal(true)
  174. })
  175. it('should not accept an extremely long path', function () {
  176. const longPath = new Array(1000).join('/subdir') + '/main.tex'
  177. const result = this.SafePath.isAllowedLength(longPath)
  178. return result.should.equal(false)
  179. })
  180. it('should not accept an empty path', function () {
  181. const result = this.SafePath.isAllowedLength('')
  182. return result.should.equal(false)
  183. })
  184. })
  185. describe('clean', function () {
  186. it('should not modify a valid filename', function () {
  187. const result = this.SafePath.clean('main.tex')
  188. return result.should.equal('main.tex')
  189. })
  190. it('should replace invalid characters with _', function () {
  191. const result = this.SafePath.clean('foo/bar*/main.tex')
  192. return result.should.equal('foo_bar__main.tex')
  193. })
  194. it('should replace "." with "_"', function () {
  195. const result = this.SafePath.clean('.')
  196. return result.should.equal('_')
  197. })
  198. it('should replace ".." with "__"', function () {
  199. const result = this.SafePath.clean('..')
  200. return result.should.equal('__')
  201. })
  202. it('should replace a single trailing space with _', function () {
  203. const result = this.SafePath.clean('foo ')
  204. return result.should.equal('foo_')
  205. })
  206. it('should replace a multiple trailing spaces with ___', function () {
  207. const result = this.SafePath.clean('foo ')
  208. return result.should.equal('foo__')
  209. })
  210. it('should replace a single leading space with _', function () {
  211. const result = this.SafePath.clean(' foo')
  212. return result.should.equal('_foo')
  213. })
  214. it('should replace a multiple leading spaces with ___', function () {
  215. const result = this.SafePath.clean(' foo')
  216. return result.should.equal('__foo')
  217. })
  218. it('should prefix javascript property names with @', function () {
  219. const result = this.SafePath.clean('prototype')
  220. return result.should.equal('@prototype')
  221. })
  222. it('should prefix javascript property names in the prototype with @', function () {
  223. const result = this.SafePath.clean('hasOwnProperty')
  224. return result.should.equal('@hasOwnProperty')
  225. })
  226. })
  227. })