From: David Masover Date: 2011-06-18T11:40:16+09:00 Subject: Re: RFC - One word alias for require_relative On Friday, June 17, 2011 08:35:35 PM Ilias Lazaridis wrote: > On 18 Ιούν, 02:30, Yukihiro Matsumoto wrote: > > Hi, > > > > In message "Re: RFC - One word alias for require_relative" > > > > on Sat, 18 Jun 2011 06:40:36 +0900, Ilias Lazaridis writes: [snip] > > |I like the word "involve" more, but as "require!" reminds clearly the > > |original "require", it's the first choice. > > > > Unfortunately the general rule for the "!" in the method name, at > > least in the standard library, is that it means "more dangerous than > > the version without bang". Since require! does not follow this rule, > > and not worthy to change the rule. So it's no chance to have require! > > in the standard library. > > I've read somewhere that it's a security risk to have the local > directory in the library path (which "require" accesses). Thus > "require_relative" became necessary. > > require_relative *has* the local directory in it's "path", We've been over this, and I honestly thought you understood last time. require_relative is relative to the directory containing the current file. That is, require_relative 'foo' is equivalent to this: require File.join(File.dirname(__FILE__), 'foo') The security risk you are talking about is from the working directory. That is, if require! worked in the "dangerous" way you seem to think it would, it would then be equivalent to this: require File.join(Dir.pwd, 'foo') These are different. They often, but not always, point to the same file, and (surprisingly) you acknowledged this and admitted your mistake. Now, requiring relative to the working directory is a security risk. As I've explained (to you!) before: Suppose I put a ruby script in my PATH, to use as a command. It has 'require "foo"' in it. If I then cd into some untrusted directory and run my command, some clever user could have put a malicious foo.rb file in that directory. It doesn't have to be me, either -- suppose my Ruby script is setuid root. Now any user can create, at their leisure, a malicious Ruby script with the name of one of the libraries required by this script, and run it, and now they've rooted my machine. This isn't even particularly far-fetched. I realize it doesn't apply to you, being on Windows and all, but this is a use case Ruby fits particularly well. By contrast, requiring relative to the current file isn't dangerous at all. Unless the attacker has write access to the directory you've installed the script into, they can't inject anything. So, sorry, it's not dangerous in any sense that would suggest a bang method. It's just different, and it's different in that it's, well, relative to the current file. I wonder how we would name a method that is different in that it's _relative_ to something. Hmm... > It is "more > powerful than the version without bang" - and thus "more dangerous". Nope, "more powerful" isn't what's meant by "more dangerous". It's also not necessarily true here. The standard system require is pretty powerful -- require_relative can only require relative to the current file, while the system require can require relative to a configurable list of directories. Seems like the system require is more powerful to me. An example of something which is "more dangerous" -- in DataMapper, there are bang versions of save, update, delete, etc, which bypass validations in order to be more efficient (often resulting in only executing a single line of SQL instead of having to load each record and perform validations before saving/deleting). And of course, you should be familiar with things like Array#sort vs Array#sort! -- one modifies the original array, the other creates a copy first, and is thus safer if you don't know who might have the original array. > But even if not, the "!" rule could be extended Didn't Matz have something to say about that? I think he did: On Friday, June 17, 2011 06:30:32 PM Yukihiro Matsumoto wrote: > Since require! does not follow this rule, > and not worthy to change the rule. So it's no chance to have require! > in the standard library. Not worthy to change the rule. But even if we change it to this (if this isn't already a fair description): > "!" for "flat" functions (e.g. "flat" Kernel functions which do not > operate strictly on an object) is used to indicate: > * "you should know what you do, possible risks" (= more dangerous), > or > * "more powerful implementation", (essentially this means: more > dangerous). require_relative is neither riskier, nor more powerful, nor more dangerous, and there's no particular reason you need to know what you're doing with it more than with require. It's. Just. Different. That's all. And the way in which it's different is described by the current name.