-
Notifications
You must be signed in to change notification settings - Fork 111
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
Add func KATI_visibility_prefix #275
Conversation
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.
One minor nit.
src/var.cc
Outdated
std::string referencingFile(loc.filename); | ||
bool valid = false; | ||
for (const std::string& prefix : prefixes) { | ||
if (referencingFile.find(prefix) == 0) { |
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.
It would seem that the preferred syntax here is: if HasPrefix(referencingFile, prefix) {
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.
+1, and if you use HasPrefix
you can use loc.filename
directly instead of creating a copy of it in referencingFile
.
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.
Also from our discussion, this should only check path prefixes instead of string prefixes (i.e. ven is not a prefix of vendor/)
This is how visibility works in soong/bazel, see https://cs.android.com/android/platform/superproject/main/+/main:build/soong/android/visibility.go;l=174;drc=9a24d909369ae20566c85dfbfe8b14054ed6dd5d
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.
re: prefix matching -- sounds good to me.
src/var.h
Outdated
@@ -73,6 +73,10 @@ class Var : public Evaluable { | |||
bool SelfReferential() const { return self_referential_; } | |||
void SetSelfReferential() { self_referential_ = true; } | |||
|
|||
std::vector<std::string> VisibilityPrefix() const { return visibility_prefix_; } |
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.
Return const std::vector<std::string>&
to avoid copies. Also change the signature to match where you call this function.
src/var.cc
Outdated
std::string referencingFile(loc.filename); | ||
bool valid = false; | ||
for (const std::string& prefix : prefixes) { | ||
if (referencingFile.find(prefix) == 0) { |
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.
+1, and if you use HasPrefix
you can use loc.filename
directly instead of creating a copy of it in referencingFile
.
std::stringstream ss(args[1]->Eval(ev)); | ||
std::string prefix; | ||
while (ss >> prefix) { | ||
prefixes.push_back(prefix); |
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.
There should be some checks here:
- The path doesn't start with a / or ../ (isn't absolute)
- The path is equal to
NormalizePath(path)
- One path isn't a prefix of another
VAR2 := $$(BAZ) | ||
VAR3 = $$(BAZ) | ||
VAR4 = $($(BAZ)) | ||
VAR5 := $($(BAZ)) |
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.
VAR3, VAR4, and VAR5 are not being tested because the makefile errored out at VAR2. You should move them into separate tests.
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.
From our discussion, VAR2/VAR3 aren't referenced due to the double dollar sign, and VAR4 isn't because the recursive expansion means it's not expanded.
That VAR4 case is a bug in my eyes, we should also check for usages via recursive expansion. This may require expanding recursive assignments immediately but then throwing away the results.
src/var.cc
Outdated
} | ||
} | ||
if (!valid) { | ||
ERROR("%s is not a valid file to reference variable %s. Line #%d", loc.filename, name, loc.lineno); |
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.
Please print out the valid locations the variable can be in as part of the error message.
endif | ||
|
||
test: | ||
@: |
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.
Please add a test that involves multiple makefiles, and a test like:
$(KATI_visibility_prefix BAZ, baz)
FOO := BAZ
X := $($(FOO)) # should be an error
4ddffa7
to
958bd22
Compare
935f0cd
to
7a22bea
Compare
if (HasPrefix(prefix, "/")) { | ||
ERROR_LOC(ev->loc(), "Visibility prefix should not start with /"); | ||
} | ||
if (HasPrefix(prefix, "../")) { |
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.
This allows "./../", which has the same effect. The best solution is probably to just not print normalizedPrefix in line 681, rather than trying to detect all of the places where the passed argument would escape the workspace.
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.
I think this is fine, ./../
would fail the normalization check.
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.
What is the purpose of having this check here? If it was removed completely the normalization check would still fail.
This check is either:
- redundant because of the normalization check, or
- insufficient in its effort to avoid leaking the parent directory name in the normalization check. If leaking the parent directory is considered bad, then just drop that from the error message below.
In any case, this check provides no added value.
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.
NormalizePath
can still produce paths starting with ../
. For example, ../foo
is a normalized path. But a ../
anywhere else in the path would be removed by the normalization process, e.g. foo/../../bar
normalizes to ../bar
, so we'd catch it.
I don't think this check is either redundant or insufficient.
It's not really about leaking the parent directory name, it's that you'd never want to make a variable visible to a location outside of the android source tree, so we should deny that nonsense argument.
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.
I was misunderstanding NormalizePath
, and expecting "../foo" to turn into an absolute path.
Agreed.
7a22bea
to
18ec8a7
Compare
syntax: $(KATI_visibility_prefix var, prefix) 1, Add a func KATI_visibility_prefix that takes a variable name and a list of strings, set this variable's visibility to these strings. Each string represents the relative path from the root, and is considered as prefix. e.g. $(KATI_visibility_prefix VAR, vendor/ device/b baz.mk) --> VAR is visible to "vendor/foo.mk", "device/bar.mk", "device/baz.mk", "baz.mk", but not visible to "bar.mk", "vendor.mk" or "vendor/baz.mk". If variable visibility is set more than once, and with a different list of strings, an error will occur. 2. When a variable is being referenced, if this variable has visibility prefix set, check if the current referencing file matches the visibility prefix. Throw an error if not. 3. In $(KATI_visibility_prefix FOO, prefix) If FOO is not defined, create a variable FOO with empty value. The prefix can also be reference to variable. If so, this function will expand the reference and set the visibility_prefix.
18ec8a7
to
238a9f1
Compare
syntax: $(KATI_visibility_prefix var, prefix)
e.g. $(KATI_visibility_prefix VAR, vendor/ device/b baz.mk) --> VAR is visible to "vendor/foo.mk", "device/bar.mk", "device/baz.mk", "baz.mk", but not visible to "bar.mk", "vendor.mk" or "vendor/baz.mk".
If variable visibility is set more than once, and with a different list of strings, an error will occur.
When a variable is being referenced, if this variable has visibility prefix set, check if the current referencing file matches the visibility prefix. Throw an error if not.
In $(KATI_visibility_prefix FOO, prefix):
If FOO is not defined, create a variable FOO with empty value.
The prefix can also be reference to variable. If so, this function will expand the reference and set the visibility_prefix.