| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /* eslint-disable
- max-len,
- no-return-assign,
- */
- // TODO: This file was created by bulk-decaffeinate.
- // Fix any style issues and re-enable lint.
- /*
- * decaffeinate suggestions:
- * DS101: Remove unnecessary use of Array.from
- * DS102: Remove unnecessary code created because of implicit returns
- * DS207: Consider shorter variations of null checks
- * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
- */
- // This file is shared between the frontend and server code of web, so that
- // filename validation is the same in both implementations.
- // The logic in all copies must be kept in sync:
- // app/src/Features/Project/SafePath.js
- // frontend/js/ide/directives/SafePath.js
- // frontend/js/features/file-tree/util/safe-path.js
- const load = function() {
- let SafePath
- const BADCHAR_RX = new RegExp(
- `\
- [\
- \\/\
- \\\\\
- \\*\
- \\u0000-\\u001F\
- \\u007F\
- \\u0080-\\u009F\
- \\uD800-\\uDFFF\
- ]\
- `,
- 'g'
- )
- const BADFILE_RX = new RegExp(
- `\
- (^\\.$)\
- |(^\\.\\.$)\
- |(^\\s+)\
- |(\\s+$)\
- `,
- 'g'
- )
- // Put a block on filenames which match javascript property names, as they
- // can cause exceptions where the code puts filenames into a hash. This is a
- // temporary workaround until the code in other places is made safe against
- // property names.
- //
- // The list of property names is taken from
- // ['prototype'].concat(Object.getOwnPropertyNames(Object.prototype))
- const BLOCKEDFILE_RX = new RegExp(`\
- ^(\
- prototype\
- |constructor\
- |toString\
- |toLocaleString\
- |valueOf\
- |hasOwnProperty\
- |isPrototypeOf\
- |propertyIsEnumerable\
- |__defineGetter__\
- |__lookupGetter__\
- |__defineSetter__\
- |__lookupSetter__\
- |__proto__\
- )$\
- `)
- const MAX_PATH = 1024 // Maximum path length, in characters. This is fairly arbitrary.
- return (SafePath = {
- // convert any invalid characters to underscores in the given filename
- clean(filename) {
- filename = filename.replace(BADCHAR_RX, '_')
- // for BADFILE_RX replace any matches with an equal number of underscores
- filename = filename.replace(BADFILE_RX, match =>
- new Array(match.length + 1).join('_')
- )
- // replace blocked filenames 'prototype' with '@prototype'
- filename = filename.replace(BLOCKEDFILE_RX, '@$1')
- return filename
- },
- // returns whether the filename is 'clean' (does not contain any invalid
- // characters or reserved words)
- isCleanFilename(filename) {
- return (
- SafePath.isAllowedLength(filename) &&
- !filename.match(BADCHAR_RX) &&
- !filename.match(BADFILE_RX)
- )
- },
- isBlockedFilename(filename) {
- return BLOCKEDFILE_RX.test(filename)
- },
- // returns whether a full path is 'clean' - e.g. is a full or relative path
- // that points to a file, and each element passes the rules in 'isCleanFilename'
- isCleanPath(path) {
- const elements = path.split('/')
- const lastElementIsEmpty = elements[elements.length - 1].length === 0
- if (lastElementIsEmpty) {
- return false
- }
- for (let element of Array.from(elements)) {
- if (element.length > 0 && !SafePath.isCleanFilename(element)) {
- return false
- }
- }
- // check for a top-level reserved name
- if (BLOCKEDFILE_RX.test(path.replace(/^\/?/, ''))) {
- return false
- } // remove leading slash if present
- return true
- },
- isAllowedLength(pathname) {
- return pathname.length > 0 && pathname.length <= MAX_PATH
- }
- })
- }
- module.exports = load()
|