From 5131fdff6294b075cc760a8014ef8c9b6d1bf5d8 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 9 Mar 2024 18:47:56 -0500 Subject: Improve handling of secret text --- builtins/text.c | 2 +- builtins/types.h | 1 + compile.c | 14 ++++++++++---- typecheck.c | 5 ++++- types.h | 1 + 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/builtins/text.c b/builtins/text.c index 4641bc1d..70d9be57 100644 --- a/builtins/text.c +++ b/builtins/text.c @@ -25,7 +25,7 @@ public CORD Text__as_text(const void *text, bool colorize, const TypeInfo *info) { if (!text) return info->TextInfo.lang; - CORD ret = Text__quoted(*(CORD*)text, colorize); + CORD ret = info->TextInfo.secret ? "(*****)" : Text__quoted(*(CORD*)text, colorize); if (!streq(info->TextInfo.lang, "Text")) ret = colorize ? CORD_all("\x1b[1m$", info->TextInfo.lang, "\x1b[m", ret) : CORD_all("$", info->TextInfo.lang, ret); return ret; diff --git a/builtins/types.h b/builtins/types.h index d26c86be..528701ff 100644 --- a/builtins/types.h +++ b/builtins/types.h @@ -29,6 +29,7 @@ typedef struct TypeInfo { } PointerInfo; struct { const char *lang; + bool secret; } TextInfo; struct { const struct TypeInfo *item; diff --git a/compile.c b/compile.c index a35ce177..f6784594 100644 --- a/compile.c +++ b/compile.c @@ -582,7 +582,12 @@ CORD compile(env_t *env, ast_t *ast) } case TextJoin: { const char *lang = Match(ast, TextJoin)->lang; - type_t *text_t = Type(TextType, .lang=lang); + type_t *text_t = Table_str_get(*env->types, lang ? lang : "Text"); + if (!text_t || text_t->tag != TextType) + code_err(ast, "%s is not a valid text language name", lang); + if (Match(text_t, TextType)->secret) + code_err(ast, "%s text is marked secret, so you cannot use %s literals in code. Please load the content from a secure location instead", + lang, lang); table_t *lang_ns = lang ? Table_str_get(*env->type_namespaces, lang) : NULL; ast_list_t *chunks = Match(ast, TextJoin)->children; if (!chunks) { @@ -604,7 +609,8 @@ CORD compile(env_t *env, ast_t *ast) for (int64_t i = 1; i <= Table_length(*lang_ns); i++) { struct {const char *name; binding_t *b; } *entry = Table_entry(*lang_ns, i); if (entry->b->type->tag != FunctionType) continue; - if (strncmp(entry->name, "escape_", strlen("escape_")) != 0) continue; + if (!(streq(entry->name, "escape") || strncmp(entry->name, "escape_", strlen("escape_")) == 0)) + continue; auto fn = Match(entry->b->type, FunctionType); if (!fn->args || fn->args->next) continue; if (fn->ret->tag != TextType || !streq(Match(fn->ret, TextType)->lang, lang)) @@ -1237,9 +1243,9 @@ CORD compile(env_t *env, ast_t *ast) auto def = Match(ast, LangDef); CORD_appendf(&env->code->typedefs, "typedef CORD %s_t;\n", def->name); CORD_appendf(&env->code->typedefs, "extern const TypeInfo %s;\n", def->name); - CORD_appendf(&env->code->typeinfos, "public const TypeInfo %s = {%zu, %zu, {.tag=TextInfo, .TextInfo={%s}}};\n", + CORD_appendf(&env->code->typeinfos, "public const TypeInfo %s = {%zu, %zu, {.tag=TextInfo, .TextInfo={%s, .secret=%s}}};\n", def->name, sizeof(CORD), __alignof__(CORD), - Text__quoted(def->name, false), "}}};\n"); + Text__quoted(def->name, false), def->secret ? "yes" : "no"); compile_namespace(env, def->name, def->namespace); return CORD_EMPTY; } diff --git a/typecheck.c b/typecheck.c index bab1920b..9c9b3b19 100644 --- a/typecheck.c +++ b/typecheck.c @@ -182,13 +182,16 @@ void bind_statement(env_t *env, ast_t *statement) case LangDef: { auto def = Match(statement, LangDef); - type_t *type = Type(TextType, .lang=def->name); + type_t *type = Type(TextType, .lang=def->name, .secret=def->secret); Table_str_set(env->types, def->name, type); env_t *ns_env = namespace_env(env, def->name); set_binding(ns_env, "from_unsafe_text", new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=Type(TextType)), .ret=type), .code=CORD_all("(", def->name, "_t)"))); + set_binding(ns_env, "text_content", + new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=Type(TextType)), .ret=type), + .code="(Text_t)")); for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) bind_statement(ns_env, stmt->ast); diff --git a/types.h b/types.h index 50e69778..75dff3bc 100644 --- a/types.h +++ b/types.h @@ -65,6 +65,7 @@ struct type_s { } NumType; struct { const char *lang; + bool secret; } TextType; struct { type_t *item_type; -- cgit v1.2.3