diff --git a/python/ql/lib/semmle/python/Module.qll b/python/ql/lib/semmle/python/Module.qll index fa756fc9655..0a083eec9a8 100644 --- a/python/ql/lib/semmle/python/Module.qll +++ b/python/ql/lib/semmle/python/Module.qll @@ -177,7 +177,7 @@ private predicate legalDottedName(string name) { } bindingset[name] -private predicate legalShortName(string name) { name.regexpMatch("(\\p{L}|_)(\\p{L}|\\d|_)*") } +predicate legalShortName(string name) { name.regexpMatch("(\\p{L}|_)(\\p{L}|\\d|_)*") } private string moduleNameFromBase(Container file) { // We used to also require `isPotentialPackage(f)` to hold in this case, diff --git a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll index c6dfcb90ad3..a56737a4831 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll @@ -10,6 +10,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.internal.ImportResolution private import semmle.python.ApiGraphs private import semmle.python.filters.Tests +private import semmle.python.Module // very much inspired by the draft at https://github.com/github/codeql/pull/5632 module NotExposed { @@ -114,7 +115,11 @@ module NotExposed { predicate isAllowedModule(Module mod) { // don't include anything found in site-packages exists(mod.getFile().getRelativePath()) and - not mod.getFile().getRelativePath().regexpMatch("(?i)(^|/)examples?/.*") + not mod.getFile().getRelativePath().regexpMatch("(?i)(^|/)examples?/.*") and + // to counter things like `my-example/app/foo.py` being allowed under `app.foo` + forall(string part | part = mod.getFile().getParent().getRelativePath().splitAt("/") | + legalShortName(part) + ) } predicate isTestCode(AstNode ast) {