Best practices when writing destructive code

Im going to be making and removing lots of directories using ruby and Im
feeling a bit uneasy about it. One of my fears is that a potential typo
after refactoring, cutting and pasting etc could cause my program to
delete innocent and system vital directories.

This creation and deletion code will be spread around my project and not
just one place which makes it more prone to errors. For instance my
tests will have to constantly remove any directories created during
testing.

Am i just being paranoid or do you black belt ruby developers have a few
tricks to guard yourself from this hazzard?

2010/1/20 Adam A. [email protected]:

Am i just being paranoid or do you black belt ruby developers have a few
tricks to guard yourself from this hazzard?

One thing I do during initial phases is to not execute the destructive
code but rather print it to stdout or stderr so I can see what would
happen. Another approach would be to copy your directory structure to
some temporary space and see what happens.

DRY is also a practice that helps avoid mistakes if you apply it to
the definition of the thing you temporarily create and then want to
remove. For example

require ‘fileutils’

def temp_dir(name)
name = name.clone unless name.frozen?
Dir.mkdir name
begin
yield name
ensure
FileUtils.rm_rf name
end
end

Then

temp_dir “/tmp/foo” do |d|
File.open “#{d}/bar”, “w” do |io|
io.puts “test”
end
end

… and you do not have to repeat the name of the directory.

Kind regards

robert

On Wed, Jan 20, 2010 at 4:09 AM, Adam A. [email protected]
wrote:

Im going to be making and removing lots of directories using ruby and Im
feeling a bit uneasy about it. One of my fears is that a potential typo
after refactoring, cutting and pasting etc could cause my program to
delete innocent and system vital directories.

  1. Create a VM instance, install your code there, take a snapshot.

  2. Fire away – if something blows up, revert to snapshot. :slight_smile:

Cheap virtualization rocks…

On 2010-01-20, Adam A. [email protected] wrote:

This creation and deletion code will be spread around my project and not
just one place which makes it more prone to errors.

So write a standard tool and use it from everywhere.

Am i just being paranoid or do you black belt ruby developers have a few
tricks to guard yourself from this hazzard?

One thing would be to sanity check that the directories in question are
in
a particular area that you think you have the right to create and delete
files in.

Another would be to run on a system with a decent security model as an
unprivileged user. :slight_smile:

-s

Adam A. wrote:

Im going to be making and removing lots of directories using ruby and Im
feeling a bit uneasy about it. One of my fears is that a potential typo
after refactoring, cutting and pasting etc could cause my program to
delete innocent and system vital directories.

This creation and deletion code will be spread around my project and not
just one place which makes it more prone to errors.

If you think that’s a problem, then why not refactor it into one place
and test the heck out of it?

For instance my
tests will have to constantly remove any directories created during
testing.

Yeah, that’s common. I use the Tempfile module for this.

Am i just being paranoid or do you black belt ruby developers have a few
tricks to guard yourself from this hazzard?

Best,
–Â
Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Sorry for the late reply, weekend break. Thank you all so very much for
your responses.

Ive refactored, extracted the repetitive code into one method, tested it
till it bled and for good measure created a new user account to restrict
any fallout.

2010/1/26 Adam A. [email protected]:

Sorry for the late reply, weekend break.

Wow! Where do you get 5+ days weekend break? :wink:

Thank you all so very much for
your responses.

You’re welcome!

Ive refactored, extracted the repetitive code into one method, tested it
till it bled and for good measure created a new user account to restrict
any fallout.

Sounds like you are pretty safe now.

Kind regards

robert

Another hint: use File.expand_path(…) and then check the beginning of
the path matches a particular expression.

target = “/var/tmp/…/…/etc/passwd”

unless File.expand_path(target).index("/var/tmp/") == 0
raise “You cannot access that file!!”
end

Brian C. wrote:

Another hint: use File.expand_path(…) and then check the beginning of
the path matches a particular expression.

target = “/var/tmp/…/…/etc/passwd”

unless File.expand_path(target).index(“/var/tmp/”) == 0
raise “You cannot access that file!!”

Reimplement OS permissions in Ruby? Why?

end

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

Marnen Laibow-Koser [email protected] writes:

Brian C. wrote:

Another hint: use File.expand_path(…) and then check the beginning of
the path matches a particular expression.

target = “/var/tmp/…/…/etc/passwd”

unless File.expand_path(target).index(“/var/tmp/”) == 0
raise “You cannot access that file!!”

Reimplement OS permissions in Ruby? Why?

The obvious reason is to cope with circumstances where you cannot take
good advantage of the OS permissions scheme: e.g. when you do not have
root access. A “normal” unix user will almsot certainly be able to read
the /etc/passwd file (too much breaks otherwise) and so will any program
they run.

-dan