Re: "tla build-config" question and suggestion

Thomas Lord <[email protected]>
Newsgroups gmane.comp.version-control.arch.user
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.