MOO-cows Mailing List Archive

[Prev][Next][Index][Thread]

Re: FUP ate my db (and I did RTFM)



At 09:45 AM 5/28/96 PDT, dg@dcs.st-and.ac.uk wrote:
>I've got a sysadmin's file management room, which provides a Unix-shell like 
>interface. So all I'm getting from the user is a single string. I can't split 
>it because there isn't an intelligent way to split it (besides, it's too much 
>work). If /foo/bar is a directory, should that be ("/foo", "bar") or 
>("/foo/bar", ".") or (".", "foo/bar")? And what about references to /? Anyway, 
>this isn't the problem. Everything works fine.

Whatever . means, I'm not sure, I never used that to reference files.  I
assume you are keeping the cwd stored somewhere, then prepending it to path
they are specifing if they don't start it with a /.  We have code that
resolves relative path names also (altho, /dir_that_doesnt_exist/../bin =>
/bin, but shouldn't matter if you use the below code to determine that the
cwd is valid before you let them "enter" it).

If /foo/bar is a directory, then it should be referenced via "/foo/bar", no
questions.  Keep it consistant.  Note that:

;filelist("home", "rules")
=> the contents of "home"
whereas
;filelist("home/rules")
=> the contents of "home/rules"
Thusly, you'll have to always reference directories via a single string
(which is how I think it should be done anyway) if you want it to be
consistant.  (sidenote: filelist()'s second optional argument is the regexp
to match against, which doesn't match directories.)

This splits it "intelligently" (whatever that means):
@program $file_utils:valid_dir_or_file   this none this
" Takes one argument, a path, and returns a three element list";
" The first of which is boolean, the second of which is a string";
" If false, then the second is an error message";
" If true, then the second is the type of the argument (dir or file)";
" The third element is the parsed path, ready for splicing into one of the";
" builtins";
"";
" :valid_dir_or_file(\"home\")";
" => {1, \"dir\", {\"home\", \"\"}}";
" :valid_dir_or_file(\"home/Scrytch\")";
" => {1, \"dir\", {\"home/Scrytch\", \"\"}}";
" :valid_dir_or_file(\"/core.mods\")";
" => {0, \"file\", {\"\", \"core.mods\"}}";
" :valid_dir_or_file(\"home/nodir/\")";
" => {0, \"No such directory.\", {\"home/nodir\", \"\"}";
" :valid_dir_or_file(\"home/nofile\")";
" => {0, \"No such file or directory.\", {\"home\", \"nofile\"}}";
"";
" It assumes that you mean a directory if you end in a /";
"";
" Written by ThwartedEfforts for all those out there who need it.";
" Never tell a hacker that it can't be done or that it's too much work.";
{path} = args;
r = rindex(path, "/");
type = 0;
" by default";
if (r == length(path))
  " ends in /, they wanted a dir";
  type = 1;
endif
" parse it into before the last / and after the last /";
before = path[1..r - 1];
after = path[r + 1..$];
"";
if (type == 0)
  " check for the existances of files";
  {flist, dlist} = filelist(before);
  if (after in flist)
    return {1, "file", {before, after}};
  endif
  if (after in dlist)
    dir = tostr(before, before ? "/" | "", after);
    return {1, "dir", {dir, ""}};
  endif
endif
if (type == 1)
  " check for the existance of directories";
  dir = tostr(before, before ? "/" | "", after);
  if (fileexists(before, after))
    return {1, "dir", {dir, ""}};
  else
    return {0, "No such directory.", {dir, ""}};
  endif
endif
return {0, "No such file or directory.", {before, after}};
/* Last edited by ThwartedEfforts (#2) <~ThwartedEfforts> on Tuesday, May
28, 1996 at 10:57:38 PM */

Hope this helps in some way.

>>>I know it's an `invalid indirection'... whatever that is. What does it mean?
>>
>>In terms of FUP or in terms of when that error is raised normally?
>
>Normally.

;#-1:someverb()
;#-1.someprop

Trying to access something indirectly through an invalid source.  Perhaps it
does make sense that FUP raise that...

>>So don't let them do just anything.  Check to make sure that a file exists
>>using fileexists before calling file{read,write,append,delete,...}.  Use
>>filelist to determine if it's a directory or a file and only them them do
>>operations that are directory operations on directories and file operations
>>on files.  If you want some semblence of security, don't just pass the
>>arguments they pass you onto the builtins blindly.

What I said there is quite verbose. :)  Just use the above code.

>That's exactly what I'm doing! The user API to FUP is going to be very 
>limited. No subdirectories (each object gets its own directory), for example. 
>Bit the bit I ran into problems with is the wizard section, which will let you 
>do arbitrary file management.

I like to assume that those I have given wizard bits to know what they are
doing.. altho, I know I'm playing with fire when I do that. :)

>(BTW, I got your message twice for some reason.)

Because I sent it to you, and cc'ed moo-cows.

And Judy Anderson <yduj@cs.stanford.edu> put me in my place with:
>I haven't been following this discussion closely, but some of the
>responses I see are "why are you doing <illegal thing X>"---that's not
>a proper kind of response.  If there's a MOO eating bug, even if the
>user has to do something really grotty to trigger it, FUP should armor
>itself against the user, returning E_INVARG or whatever the
>appropriate error is for that particular illegal thing.  How does that
>saying go?  "It's not good enough to be foolproof---fools are too
>ingenious!"

How true!  And of course, I realized that as soon as I sent off the mail.  I
never tried to do something illegal, specificly because it's usually dumb to
do something like that (there is no valid reason for opening a directory as
a file and reading from it) -- which is the exact reason programmers can not
effectively debug their own code.  They are too familar with it.

Andy.



Follow-Ups:

Home | Subject Index | Thread Index