Perforce paths should start with a forward slash#41972
Conversation
|
Codenotify: Notifying subscribers in CODENOTIFY files for diff f32c06d...3fc101d.
|
| if !strings.HasPrefix(rule, "/") { | ||
| rule = "/" + rule | ||
| } |
There was a problem hiding this comment.
This is so that existing path rules get a leading slash when compiled (if they don't have one), so that we don't have to worry about migrations.
There was a problem hiding this comment.
I think you can add a code comment here that explains this (because sooner or later someone will come along and think "don't we add these slashes when writing PathIncludes?")
| // see one level of the tree at a time so we have no way of knowing which path leads | ||
| // to a file the user is allowed to see. | ||
| if strings.HasPrefix(rule, "*") { | ||
| if strings.HasPrefix(rule, "*") || strings.HasPrefix(rule, "/*") { |
There was a problem hiding this comment.
We just have to check for both cases here, as we cannot be sure where this function is called (It's also possible to do the prefix adding above here)
There was a problem hiding this comment.
Can we instead make sure that the rule string starts with / as we do in other places? Would make the code follow the same convention everywhere.
There was a problem hiding this comment.
Yeah, I think that's better (hence my comment above). Only thought of it after working through my own PR. But now that I have a second opinion feeling the same, I'll add it
| for { | ||
| lastSlash := strings.LastIndex(rule, "/") | ||
| if lastSlash == -1 { | ||
| if lastSlash <= 0 { |
There was a problem hiding this comment.
Since all rules start with a slash now, the lastSlash index will never be -1, so we check for <= 0 instead. (i.e. it used to break on something.java, now it needs to break on /something.java
mrnugget
left a comment
There was a problem hiding this comment.
Leaving final approval to everyone else, since I still miss too much context, but on the surface this looks good!
| if !strings.HasPrefix(rule, "/") { | ||
| rule = "/" + rule | ||
| } |
There was a problem hiding this comment.
I think you can add a code comment here that explains this (because sooner or later someone will come along and think "don't we add these slashes when writing PathIncludes?")
| parsedLine.isExclusion = true // is an exclusion | ||
| parsedLine.match = parsedLine.match[1:] // trim leading - | ||
| parsedLine.isExclusion = true // is an exclusion | ||
| parsedLine.match = strings.TrimPrefix(parsedLine.match, "-") // trim leading - |
There was a problem hiding this comment.
+1 for this change, love that it makes the code more explicit in intentions.
| s = strings.TrimPrefix(s, "//") | ||
| if !strings.HasPrefix(s, "/") { | ||
| s = "/" + s // make sure path starts with a '/' | ||
| } |
There was a problem hiding this comment.
Instead of trimming the slashes from prefix and then adding them later, could we do some regex magic here? Or is this performance critical?
There was a problem hiding this comment.
It's pretty performance critical, especially now that we have to exhaust the entire list of rules to make sure we enforce them correctly.
But I'd say the fact that it's generally referred to as "regex magic" is the bigger deterrent for not using it, especially here where we want to be sure (and understand) what we're doing
There was a problem hiding this comment.
Haha, I read "regex magic" in my email inbox, put on my Batcape to come swooping in here and point at the "no magic!" sign on the wall and you beat me to it, Petri.
In all seriousness: I like how simple this is, so my vote goes for this, even if it can look a bit redundant.
| // see one level of the tree at a time so we have no way of knowing which path leads | ||
| // to a file the user is allowed to see. | ||
| if strings.HasPrefix(rule, "*") { | ||
| if strings.HasPrefix(rule, "*") || strings.HasPrefix(rule, "/*") { |
There was a problem hiding this comment.
Can we instead make sure that the rule string starts with / as we do in other places? Would make the code follow the same convention everywhere.
| setSubRepositoryPermissionsForUsers( | ||
| repository: "UmVwb3NpdG9yeTox" | ||
| userPermissions: [{bindID: "alice", pathIncludes: ["*"], pathExcludes: ["*_test.go"]}] | ||
| userPermissions: [{bindID: "alice", pathIncludes: ["/*"], pathExcludes: ["/*_test.go"]}] |
There was a problem hiding this comment.
Now that we always expect a / prefix, do we want to update this resolver to enforce that?
| read group Rome * //depot/.../something.java ## Can read all files named 'something.java' | ||
| read group Rome * -//depot/dev/prodA/... ## Except files in this directory | ||
| `, | ||
| cannotReadAny: []string{"dev/prodA/something.java", "dev/prodA/another_dir/something.java"}, |
There was a problem hiding this comment.
Can we also confirm that it doesn't match these paths with leading slahes? For example /dev/prodA/something.java
Should we open a patch for this upstream? |
|
@camdencheek we could try. At this point I'm not 100% sure if it's a bug, or a misunderstanding (either from us, or from the package maintainer), because the package seems very solid with a vast array of test cases. I can open an issue and see if they reply |
Solves #41927
There is a bug in the
gobwas/globpackage we use where the filesomething.javacannot be matched to the path**/something.java. This is because**/something.javaget's converted to a suffix of/something.java, which !=something.java.One solution is to prepend all file checks with a
/, however this breaks another case:We store all paths without forward slashes. So a path like
dev/test/**then becomes unmatchable to/dev/test/some_test.java, due to the difference in forward slash at the front.By ensuring that all paths and file matches start with a forward slash (i.e. being explicit about the root directory), this solves both cases.
Test plan
Updated unit tests. Added new unit tests