pmjones/fig-leaf — pull request #5 by simensen (2013-06-25 16:55:06+00:00)
Title: Tighten logic for "Logical Path Prefix"

**TL;DR**

The idea is to ensure that the spec handles all of our use cases and ensure that the code in the reference implementation addresses all of the concerns written in spec. Also, ensure that the reference implementation isn't doing things like sanitizing user input that aren't in the spec.

---

These changes solve some logical errors in the original definition that either were not accounted for or were somewhat ambiguous. The new definition accounts for root as a prefix (for example: `/`), the local prefix being able to be specified without a trailing separator, and the entire fully qualified logical path as the prefix.

I think the core of the problem was in how some of these issues were addressed in the reference implementation instead of addressing the underlying issues in the spec itself:

// make sure the logical prefix ends in a separator
rtrim($logical_prefix, $logical_sep) . $logical_sep;

This was silently addressing one case in the spec that was not covered (actually disallowed), in that if you specified a logical prefix of "/" (just the root), the rtrim would clear it and then by always appending the separator, it would result in "/" again. So the test case passed, but it did not really jive with the spec. This might have been obviously what we intended, but by adjusting the spec we can make it more clear exactly what we mean.

This also would have allowed someone to specify a logical prefix with any number of trailing separators. The comment implies that we might expect someone to pass in something w/o a separator at the end and we want to make sure there is one... either the spec requires it or it doesn't. Sanitizing user input like this can be dangerous because each implementation would be required to implement the same sanitization rules, otherwise one set of prefixes might work in one implementation but might not in another.

Bernhard's issues were with silently handling some of these issues with a code fix in the reference implementation rather than addressing the core of the problem: the wording of the _Logical Path Prefix_ description.

#### As to the specific changes to the definition:

> **Logical Path Prefix**: A string comprised of either a single _logical separator_, the _fully qualified logical path_, or any contiguous series of _logical separators_ and _logical segments_, starting from the beginning of a _fully qualified logical path_, that is followed by a _logical separator_. For example, given a _logical separator_ of "/" and a _fully qualified logical path_ of `/Foo/Bar/Baz`, then `/`, `/Foo`, `/Foo/Bar`, `/Foo/Bar/Baz` are valid _logical path prefixes_.

* Added **A single _logical separator_** to account for "/" prefixes
* `transform("Foo\\Bar", "\\", "\\", "/src/")` => `/src/`
* Allows considering "/" to be a valid prefix for "/Foo/Bar/Baz"
* Covers test case: `testBSRoot`
* Added **The _fully qualified logical path_** to account for matching the entire prefix
* `transform("Foo\\Bar", "Foo\\Bar", "\\", "/src/")` => `/src/`
* Allows considering "/Foo/Bar/Baz" to be a valid prefix for "/Foo/Bar/Baz"
* Covers test cases: `testBSDirectory`, `testBSFile`
* Changed from "terminated by" to **... that is followed by a _logical separator_** to account for not requiring the user input to have a trailing separator in the input
* Allows considering "/Foo" and "/Foo/Bar" (without trailing slashes) to be valid prefixes for "/Foo/Bar/Baz"
* Covers test cases: `testClassName`, `testResourceName`, `testDirectoryName`, `testBSPrefix`

#### As to the new rules:

* If the logical path is equal to the logical path prefix, the algorithm MUST return the file system path prefix.
* The spec should be explicit about what should happen in this case
* If the logical path prefix is not valid or cannot be found, the algorithm MUST return NULL.
* The spec should be explicit about what should happen in this case
* This is for protection (not allowing transformations for invalid prefixes)
* This gives us a potential avenue for testing implementations for whether or not they are doing this right

#### As to the changes to the reference implementation

* Returning the fs prefix immediately if the logical path prefix is the same as the fully qualified logical path
* Only appending the logical separator to the logical prefix in the case that the logical prefix is not the root
* Returning NULL if the fully qualified logical path does not contain the logical path (with the trailing separator) in order to ensure that partial/invalid matches are found (this addresses concerns like @drak's — [discussed here](https://github.com/php-fig/fig-standards/pull/138#issuecomment-19790302))
* Does not sanitize user input in any way. A user is expected to specify a valid logical path prefix as defined by the rules. Specifying anything else (like `/Foo/Bar/` for `/Foo/Bar/Baz`) is not expected to transform correctly.