diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-08-10 14:44:03 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-08-10 14:44:03 -0400 |
| commit | 611ebeab13b64d505ad4b44d0f80b3d0e9fb8dba (patch) | |
| tree | f0edc3737d3e7366aad896355f2f7628bc2d8840 /src/environment.c | |
| parent | 98cadc2135be65abcf9dff53d87af9ea549757a2 (diff) | |
Add full protection against accessing fields and methods that start with
underscores outside of the scope where the type is defined.
Diffstat (limited to 'src/environment.c')
| -rw-r--r-- | src/environment.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/environment.c b/src/environment.c index 0bcdd592..93b5a16c 100644 --- a/src/environment.c +++ b/src/environment.c @@ -749,7 +749,7 @@ binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name) return ns_env ? get_binding(ns_env, name) : NULL; } -PUREFUNC binding_t *get_constructor(env_t *env, type_t *t, arg_ast_t *args) +PUREFUNC binding_t *get_constructor(env_t *env, type_t *t, arg_ast_t *args, bool allow_underscores) { env_t *type_env = get_namespace_by_type(env, t); if (!type_env) return NULL; @@ -758,15 +758,27 @@ PUREFUNC binding_t *get_constructor(env_t *env, type_t *t, arg_ast_t *args) for (int64_t i = constructors.length-1; i >= 0; i--) { binding_t *b = constructors.data + i*constructors.stride; DeclareMatch(fn, b->type, FunctionType); + if (!allow_underscores) { + for (arg_t *arg = fn->args; arg; arg = arg->next) + if (arg->name[0] == '_') + goto next_constructor; + } if (type_eq(fn->ret, t) && is_valid_call(env, fn->args, args, false)) return b; + next_constructor: continue; } // Fall back to promotion: for (int64_t i = constructors.length-1; i >= 0; i--) { binding_t *b = constructors.data + i*constructors.stride; DeclareMatch(fn, b->type, FunctionType); + if (!allow_underscores) { + for (arg_t *arg = fn->args; arg; arg = arg->next) + if (arg->name[0] == '_') + goto next_constructor2; + } if (type_eq(fn->ret, t) && is_valid_call(env, fn->args, args, true)) return b; + next_constructor2: continue; } return NULL; } |
