SafePath.coffee 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. # This file is shared between the frontend and server code of web, so that
  2. # filename validation is the same in both implementations.
  3. # Both copies must be kept in sync:
  4. # app/coffee/Features/Project/SafePath.coffee
  5. # public/coffee/ide/directives/SafePath.coffee
  6. load = () ->
  7. BADCHAR_RX = ///
  8. [
  9. \/ # no slashes
  10. \* # no asterisk
  11. \u0000-\u001F # no control characters (0-31)
  12. \u007F # no delete
  13. \u0080-\u009F # no unicode control characters (C1)
  14. \uD800-\uDFFF # no unicode surrogate characters
  15. ]
  16. ///g
  17. BADFILE_RX = ///
  18. (^\.$) # reject . as a filename
  19. | (^\.\.$) # reject .. as a filename
  20. | (^\s+) # reject leading space
  21. | (\s+$) # reject trailing space
  22. ///g
  23. MAX_PATH = 1024 # Maximum path length, in characters. This is fairly arbitrary.
  24. SafePath =
  25. clean: (filename) ->
  26. filename = filename.replace BADCHAR_RX, '_'
  27. # for BADFILE_RX replace any matches with an equal number of underscores
  28. filename = filename.replace BADFILE_RX, (match) ->
  29. return new Array(match.length + 1).join("_")
  30. return filename
  31. isCleanFilename: (filename) ->
  32. return SafePath.isAllowedLength(filename) &&
  33. not filename.match(BADCHAR_RX) &&
  34. not filename.match(BADFILE_RX)
  35. isAllowedLength: (pathname) ->
  36. return pathname.length > 0 && pathname.length <= MAX_PATH
  37. if define?
  38. define [], load
  39. else
  40. module.exports = load()