gnu-arch-users
[Top][All Lists]
Advanced

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

Re: [Gnu-arch-users] "tla build-config" question and suggestion


From: Thomas Lord
Subject: Re: [Gnu-arch-users] "tla build-config" question and suggestion
Date: Fri, 14 Apr 2006 10:31:12 -0700
User-agent: Thunderbird 1.5 (X11/20060313)

Ludovic Courtès wrote:
Anyway, I guess you'd agree that `is_non_upwards_relative_path ()' could
also be fixed quite trivially (let alone symlinks first).  Roughly (in
Scheme):   [syntactic simplification of ., .., and empty elements]
Not simply, because that is not how the kernel interprets paths. You can syntactically
simplify . and empty path elements but not ..

Think of it in terms of an invariant:

   Where:
            P is a directory specification in a config file
            C(P) is P canonicalized
            R is a path to the root of the composite tree

    Preserve the invariant that, after the tree has been fully built,
             R/P  and R/C(P) are both paths to the same directory

During tree construction there should also be an invariant about symlinks:

      No prefix path of P (including P itself) names a symbolic link

I think that you think that that second invariant implies that C(P) can
syntactically eliminate .. elements but that isn't so because the element
eliminated when getting rid of the .. might be something other than
a regular directory.   Consider these examples given:

            cd R
            touch foo
            ln -s bar ~/
            mkdir baz
            mkdir .pgp

then if:
           P = foo/../baz
           C(P) = baz

then P and C(P) do not name the same directory.   Similarly:

            P = bar/../.pgp
            C(P) = .pgp

again, P and C(P) do not name the same directory.

Now, if you really, really wanted syntactic .. canonicalization of config
files then I guess you could:

      1. canonicalize using an algorithm like the one you showed
2. at build time, verify that P and C(P) always resolve to the same directory 3. verify that P and C(P) always name a new directory under the root, R 4. verify that no prefix path of P or C(P) points outside of the tree rooted at R

That seems like a long way to go for not much return, to me. Contrast with:

      1. config files must contain only relative paths with no .. elements
      2. (optional) canonicalize to eliminate . and empty path elements
3. at build time, ensure that no prefix of P or C(P) names a symbolic link

  (define (canonicalize-path path)
    (let loop ((path (string-split path #\/))
               (result '()))
      (if (null? path)
          (fold (lambda (comp res)
                  (if (string=? res "")
                      comp
                      (string-append res "/" comp)))
                ""
                (reverse! result))
          (loop (cdr path)
                (let ((component (car path)))
                  (cond ((string=? component "..")
                         (if (null? result)
                             (error "breaking out of tree root" path)
                             (cdr result)))
                        ((string=? component ".")
                         result)
                        (else (cons component result))))))))

I admit that implementing it in C would be a bit harder, though not
unfeasible.

IMO, that's typically the kind of functionality we'd expect from the C
library instead of having to roll our own every time...

The C library traditionally doesn't contain that functionality because it does not
interpret paths the same way the kernel does.

The C library is missing lots of stuff -- path manipulation functions included -- but that isn't one of them. The function you are describing would make sense
in a C library for hacking URLs

-t





reply via email to

[Prev in Thread] Current Thread [Next in Thread]