aboutsummaryrefslogtreecommitdiff
path: root/src/environment.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-08-10 14:44:03 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-08-10 14:44:03 -0400
commit611ebeab13b64d505ad4b44d0f80b3d0e9fb8dba (patch)
treef0edc3737d3e7366aad896355f2f7628bc2d8840 /src/environment.c
parent98cadc2135be65abcf9dff53d87af9ea549757a2 (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.c14
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;
}