Ruby - Как предотвратить стирание вашего жесткого диска при использовании команд удаления файлов и каталогов в вашем коде - PullRequest
1 голос
/ 18 января 2010

Я пишу некоторый код, который во время выполнения может создавать или удалять каталоги в пути проекта.Я на самом деле не использовал ruby ​​для обработки файлов, поэтому мне очень не хочется иметь код, который, если через несколько недель произойдет несколько ошибок, может привести к удалению других каталогов за пределами пути моего проекта.

Есть ли возможность сделать так, чтобы программа не могла удалять файлы вне своего собственного пути независимо от того, что было введено при деструктивных вызовах?

Ответы [ 6 ]

2 голосов
/ 19 января 2010

Pathname - это класс-оболочка для почти любых файловых операций.

require "pathname"
path= Pathname.new("/home/johannes")
path.directory? # => true
path.children # => [#<Pathname:.bash_history>, #<Pathname:Documents>, #<Pathname:Desktop>]
path.children.each do |p|
  p.delete if p.file?
end

Pathname#children не содержит . или .., поэтому вы случайно не идете вверх по дереву, а не вниз.Если вы все еще не доверяете коду, вы можете даже проверить, содержится ли путь в другом

Pathname.new("test") <=> Pathname.new("test/123") # => -1
2 голосов
/ 18 января 2010

В системе POSIX вы можете использовать Dir.chroot , чтобы изменить корень, который видит ваше приложение.Тогда ВСЕ действия, а не только удаление, будут ограничены каталогом проекта.Это означает, что внешние команды будут недоступны, если вы не сделаете их частью каталога вашего проекта.

Это стандартный метод «песочницы», используемый в системах на основе Unix.Это может быть сложно настроить (иногда устранять все внешние зависимости сложно), но при правильной настройке обеспечивает значительную защиту.

2 голосов
/ 18 января 2010

Возможно, вы захотите создать метод-обертку вокруг вашего любимого метода удаления (или, возможно, вокруг всего класса, поскольку не только удаление файлов является потенциально разрушительной файловой операцией), который расширит все представленные пути и проверит, начинаются ли ониваш путь "песочницы").Вы также можете попытаться переопределить метод удаления, если вы хотите нанести вред его всему приложению.

И, возможно, самым чистым решением из всех них будет создание нового пользователя в вашей системе и запуск вашей программы от его имени.

1 голос
/ 19 января 2010

У меня есть автоматические тесты, которые регулярно создают и уничтожают каталоги. Я выбрал два подхода:

  1. Используйте / tmp как можно больше. Модуль стандартной библиотеки 'tmpdir' создаст временные каталоги, которые будут уничтожены при выходе из вашей программы. Или

  2. Когда код создает каталог, который он будет впоследствии удалять, он удаляет файл маркера в каталог. Когда приходит время удалить каталог, если файл маркера не найден, код отказывается удалить каталог. Например, файл маркера может называться ".ok_to_delete".

1 голос
/ 18 января 2010

Вы можете использовать File.expand_path и File.dirname на входе и сравнить это с __FILE__.Так что-то вроде этого может работать:

File.delete(path) if File.dirname(File.expand_path(path)).include? File.dirname(File.expand_path(__FILE__))
1 голос
/ 18 января 2010

Вы можете создать массив имен файлов в каталоге вашего проекта, используя

my_files = Dir["/bla/bla/your/directory/**/*"]

, а затем просто проверьте, существует ли имя файла, переданное вашей функции "delete", в вашем массиве my_files.
Я уверен, что есть более элегантное решение, но это может сработать ^ _ ^

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...