-
-
Notifications
You must be signed in to change notification settings - Fork 346
Improve path join test assertion messages and fix minor test bugs #1528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This rewrites the custom message in that assertion so it states the applicable semantics and avoids claiming that `c:relative` and `c:\relative` are equivalent, which is not generally, nor usually, the case. (The message was also written with an unescaped `\r` in a non-raw string literal, but a literal `\r` was intended. The new wording no longer includes an explicit path, but if that is added then the problem can be avoided by writing `\\r` or writing a raw string.) This relates to: - https://github.com/Byron/gitoxide/pull/1374/files/e955770c0b5c06a6c8518a06df4aa0cc3b506f16#r1721045107
Although the path `C:` is relative because it indicates the current directory on the C: drive, it still "takes over" when concatenated after at most if not all paths (including absolute paths). When the paths it is concatenated with are absolute paths with drive letters other than C:, this behavior, while not obvious, is conceptually clear such that no other behavior could be correct. This is because the (drive-specific) current directory on the C: drive is not located on another drive, and therefore not found under any path that specifies a drive that is not C:. (There are other situations where `C:` on the right takes precedence where the explanation is less elegant, but they are mostly not relevant to the assertions currently present here.) This relates to: - https://github.com/Byron/gitoxide/pull/1374/files/e955770c0b5c06a6c8518a06df4aa0cc3b506f16#r1721055278 - https://github.com/Byron/gitoxide/pull/1374/files/e955770c0b5c06a6c8518a06df4aa0cc3b506f16#r1721079186
Since the paths `/absolute` and `\absolute` are not absolute paths on Windows.
This abbreviates the significance of `\\localhost` more specifically, as win-absolute-unc-host rather than win-absolue-unc. It also points out what seems unusual about joining `\` and `\\localhost` to get `\localhost` with just one backslash. This message should be further revised to state why this behavior happens or otherwise describe it clearly, once known. (Or if this turns out to be a bug in the standard library, then that can be stated, with an issue link either in the code or commit message.) This relates to: - https://github.com/Byron/gitoxide/pull/1374/files/e955770c0b5c06a6c8518a06df4aa0cc3b506f16#r1721079809
So they test what they strongly appear to be intending to test: the behavior of a UNC-style path `\\localhost`. They were instead testing `\localhost` because `\\` in a non-raw string becomes a single backslash. Although the symbolic representations in the assertion messages were clear enough to identify what the tests intended to test, this also adjusts those slightly so they remain comparable to the corresponding Windows tests whose assertion messages were recently changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These identify specific comments in #1374 (review) to which these changes relate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for digging into this again and for the clarifications.
Indeed, these tests only exists to 'test' the std::path::Path
implementation and get a feeling what happens in varying scenarios. Hopefully having written these down gives enough confidence that joining two relative paths won't accidentally create an absolute path, which could certainly be exploited.
I had not mentioned why I did not also add a clarifying comment for this (which was present before, not introduced here, but which I had considered clarifying here): I had originally planned to comment that this was a workaround for rust-lang/rust-clippy#12244. This would also add another source of information about how paths that start with I didn't include this because the In the tests, the leading- These variables were originally named I think that diagnostic is only for literals. Commenting out the suppression on Windows does not seem to give any new Because the tests are supposed to speak for themselves, I am reluctant to add a big commented explanation about these issues to the file. But if I can think of something that would improve clarity without making the code more cumbersome to read or work with, then I'll open another PR.
Some relative paths would of course also be exploitable, such as if permitted paths could produce a relative path with a For paths like With all that said, on Windows, you can join two relative paths to produce an absolute path, because use std::path::Path;
fn main() {
let drive = Path::new("C:");
let slash = Path::new("/");
let backslash = Path::new(r"\");
let drive_slash = drive.join(slash);
let drive_backslash = drive.join(backslash);
for path in [drive, slash, backslash, drive_slash.as_path(), drive_backslash.as_path()] {
let path_str = path.to_str().expect("valid Unicode");
println!("{:3} relative? {:5} absolute? {}", path_str, path.is_relative(), path.is_absolute());
}
} On Windows, that outputs:
Conceptually (and informally), what is happening is that But because we are not allowing paths like |
Thanks for sharing! Paths are…fascinating :).
Since these tests are merely for documenting current behaviour, I think making it more obvious what they are testing (or what one should or could learn) is in their interest. Please feel free to open a PR with additional remarks, it's valuable to write it down while it's in active memory. |
This builds on 025e788 (GitoxideLabs#1528) and 6daaba3 (GitoxideLabs#1844), using `r` and `br` string literals in more places where it helps use fewer backslashes, where doing so seems to improve readability.
This fixes inaccurate assertion messages in the path-joining tests, improves some messages that were okay but capable of being clarified, and renames a couple of variables to avoid making it seem like relative paths are absolute. Most of the changes are to the Windows tests. This relates to #1374 (review).
It also corrects a few tests where the same thing was asserted multiple times with a different message rather than asserting the subtly different claim that the message showed was intended, or where it tested paths with a different number of backslashes than the context and message show were meant.
Finally, though this is only a refactoring, it changes all string literals with backslash-containing paths to be raw string literals. I think this makes it easier and also faster to understand what paths are being tested, and generally improves readability a bit.
(Sometimes it makes sense to write all Windows paths as raw string literals, even those without backslashes, but I didn't do that, because in this case I think it would produce an effect that, one way or another, would be confusing or at least feel strange, when comparing corresponding tests in the Windows and non-Windows build configurations.)
Several assertion messages had contained expressions of surprise at the effects. When rewording made this clear, I removed such wording. Elsewhere I kept it. In one place, I even added it: I do not know why concatenating
\
and\\localhost
on Windows produces\localhost
, and it seems like the intent had even been to assert that it produces\\localhost
(because it characterized the result as being UNC). But it does produce\localhost
for some reason. Hopefully the message there can be improved further, but unless more is known about that now, I think my characerization as "strangely, single-backslashed host" may still be an improvement.Some more details are available in commit messages and, in what may be an easier form to work with, in review comments I've posted below on particular changes.