From 49ac158dd24dbdb58e2d248b0dabd1671dede4ae Mon Sep 17 00:00:00 2001 From: Lars Wendler Date: Wed, 8 Jul 2026 23:02:24 +0200 Subject: [PATCH] Revert "Validate host links with PSL rules" This reverts commit 8f7c40caf11c5aee07221568cbf1b373b7e035c8. Because we cannot rely on files getting downloaded during build --- src/common/common.vcxproj | 2 - src/common/common.vcxproj.filters | 3 - src/common/gen-public-suffix.py | 71 --------------- src/common/meson.build | 12 +-- src/common/url.c | 146 +----------------------------- 5 files changed, 3 insertions(+), 231 deletions(-) delete mode 100644 src/common/gen-public-suffix.py diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index f870d613..928bdaf1 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -29,7 +29,6 @@ - @@ -112,7 +111,6 @@ Header Files - - Header Files - Header Files diff --git a/src/common/gen-public-suffix.py b/src/common/gen-public-suffix.py deleted file mode 100644 index cd3a96e6..00000000 --- a/src/common/gen-public-suffix.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python3 -import sys -import urllib.request -from pathlib import Path - -URLS = ( - "https://raw.githubusercontent.com/publicsuffix/list/main/public_suffix_list.dat", - "https://publicsuffix.org/list/public_suffix_list.dat", -) - - -def parse_rules(text: str): - rules = [] - for raw in text.splitlines(): - line = raw.strip() - if not line or line.startswith("//"): - continue - if " " in line or "\t" in line: - line = line.split()[0] - rules.append(line.lower()) - return sorted(set(rules)) - - -def emit_header(path: str, rules): - with open(path, "w", encoding="utf-8", newline="\n") as out: - out.write("#pragma once\n") - out.write("static const char * const public_suffix_rules[] = {\n") - for rule in rules: - escaped = rule.replace("\\", "\\\\").replace('"', '\\"') - out.write(f'\t"{escaped}",\n') - out.write("};\n") - out.write( - "static const unsigned int public_suffix_rules_len = sizeof(public_suffix_rules) / sizeof(public_suffix_rules[0]);\n" - ) - - -def main(): - if len(sys.argv) not in (2, 3): - raise SystemExit("usage: gen-public-suffix.py [source]") - output = Path(sys.argv[1]) - sources = [] - if len(sys.argv) == 3: - sources.append(Path(sys.argv[2])) - sources.extend( - [ - Path(__file__).with_name("public_suffix_list.dat"), - Path("/usr/share/publicsuffix/public_suffix_list.dat"), - Path("/app/share/publicsuffix/public_suffix_list.dat"), - ] - ) - data = None - for url in URLS: - try: - with urllib.request.urlopen(url, timeout=30) as resp: - data = resp.read().decode("utf-8") - break - except Exception: - pass - if data is None: - for source in sources: - if source.exists(): - data = source.read_text(encoding="utf-8") - break - if data is None: - raise SystemExit("unable to load public suffix list") - rules = parse_rules(data) - emit_header(str(output), rules) - - -if __name__ == "__main__": - main() diff --git a/src/common/meson.build b/src/common/meson.build index ddba0d32..1f792666 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -101,14 +101,6 @@ marshal = [ make_te = find_program('make-te.py') - -python3 = find_program('python3', required: true) - -public_suffix_data = custom_target('public_suffix_data_h', - output: 'public_suffix_data.h', - command: [python3, files('gen-public-suffix.py'), '@OUTPUT@'] -) - textevents = custom_target('textevents', input: 'textevents.in', output: ['textevents.h', 'textenums.h'], @@ -132,7 +124,7 @@ if get_option('plugin') endif zoitechat_common = static_library('zoitechatcommon', - sources: [textevents, public_suffix_data] + marshal + common_sources + secretstore_sources, + sources: [textevents] + marshal + common_sources + secretstore_sources, include_directories: config_h_include, dependencies: common_deps + common_sysinfo_deps, c_args: common_cflags, @@ -140,7 +132,7 @@ zoitechat_common = static_library('zoitechatcommon', ) zoitechat_common_dep = declare_dependency( - sources: [textevents, public_suffix_data] + marshal, + sources: [textevents] + marshal, link_with: zoitechat_common, include_directories: common_includes, compile_args: common_cflags, diff --git a/src/common/url.c b/src/common/url.c index 4966db30..1d3e8274 100644 --- a/src/common/url.c +++ b/src/common/url.c @@ -20,14 +20,12 @@ #include #include #include -#include #include "zoitechat.h" #include "zoitechatc.h" #include "cfgfiles.h" #include "fe.h" #include "tree.h" #include "url.h" -#include "public_suffix_data.h" #ifdef HAVE_STRINGS_H #include #endif @@ -37,7 +35,6 @@ GTree *url_btree = NULL; static gboolean regex_match (const GRegex *re, const char *word, int *start, int *end); static const GRegex *re_url (void); -static const GRegex *re_url_no_scheme (void); static const GRegex *re_email (void); static const GRegex *re_nick (void); static const GRegex *re_channel (void); @@ -45,8 +42,6 @@ static gboolean match_nick (const char *word, int *start, int *end); static gboolean match_channel (const char *word, int *start, int *end); static gboolean match_url (const char *word, int *start, int *end); static gboolean match_email (const char *word, int *start, int *end); -static gboolean host_has_public_suffix (const char *host); -static gboolean host_has_public_suffix_range (const char *word, int start, int end); static int url_free (char *url, void *data) @@ -271,16 +266,7 @@ match_channel (const char *word, int *start, int *end) static gboolean match_url (const char *word, int *start, int *end) { - if (regex_match (re_url (), word, start, end)) - return TRUE; - - if (!regex_match (re_url_no_scheme (), word, start, end)) - return FALSE; - - if (*start > 0 && word[*start - 1] == '@') - return FALSE; - - return host_has_public_suffix_range (word, *start, *end); + return regex_match (re_url (), word, start, end); } static gboolean @@ -407,114 +393,6 @@ regex_match (const GRegex *re, const char *word, int *start, int *end) return found; } -static gboolean -host_has_public_suffix_range (const char *word, int start, int end) -{ - char *candidate; - const char *host_start; - const char *host_end; - const char *host_colon; - gboolean ok; - int host_len; - char *host; - - candidate = g_strndup (word + start, end - start); - host_start = candidate; - host_end = candidate + strlen (candidate); - if (*host_start == '[') - { - g_free (candidate); - return FALSE; - } - host_colon = strchr (host_start, ':'); - if (host_colon) - host_end = host_colon; - host_colon = strchr (host_start, '/'); - if (host_colon && host_colon < host_end) - host_end = host_colon; - host_len = (int)(host_end - host_start); - if (host_len <= 0) - { - g_free (candidate); - return FALSE; - } - host = g_strndup (host_start, host_len); - ok = host_has_public_suffix (host); - g_free (host); - g_free (candidate); - return ok; -} - -static GHashTable * -public_suffix_table (void) -{ - static GHashTable *table = NULL; - unsigned int i; - - if (table) - return table; - - table = g_hash_table_new (g_str_hash, g_str_equal); - for (i = 0; i < public_suffix_rules_len; i++) - { - g_hash_table_add (table, (gpointer)public_suffix_rules[i]); - } - return table; -} - -static gboolean -host_has_public_suffix (const char *host) -{ - GHashTable *table; - gchar **labels; - int i; - int n; - gboolean matched = FALSE; - - if (!strchr (host, '.')) - return FALSE; - - labels = g_strsplit (host, ".", -1); - for (n = 0; labels[n]; n++) - { - if (labels[n][0] == '\0') - { - g_strfreev (labels); - return FALSE; - } - } - - table = public_suffix_table (); - for (i = 0; i < n; i++) - { - char *tail = g_strjoinv (".", &labels[i]); - if (g_hash_table_contains (table, tail)) - matched = TRUE; - if (i + 1 < n) - { - char *tail_wild = g_strjoinv (".", &labels[i + 1]); - char *wild = g_strconcat ("*.", tail_wild, NULL); - if (g_hash_table_contains (table, wild)) - matched = TRUE; - g_free (tail_wild); - g_free (wild); - } - if (i > 0) - { - char *exc = g_strconcat ("!", tail, NULL); - if (g_hash_table_contains (table, exc)) - matched = TRUE; - g_free (exc); - } - g_free (tail); - if (matched) - break; - } - - g_strfreev (labels); - return matched; -} - /* Miscellaneous description --- */ #define DOMAIN_LABEL "[\\pL\\pN](?:[-\\pL\\pN]{0,61}[\\pL\\pN])?" #define DOMAIN DOMAIN_LABEL "(\\." DOMAIN_LABEL ")*" @@ -599,28 +477,6 @@ re_url (void) return url_ret; } -static const GRegex * -re_url_no_scheme (void) -{ - static GRegex *url_ret = NULL; - GString *grist_gstr; - char *grist; - - if (url_ret) return url_ret; - - grist_gstr = g_string_new (NULL); - g_string_append (grist_gstr, "("); - g_string_append (grist_gstr, HOST_URL_OPT_TLD OPT_PORT); - g_string_append_printf (grist_gstr, "(/" PATH ")?"); - g_string_append (grist_gstr, ")"); - - grist = g_string_free (grist_gstr, FALSE); - url_ret = make_re (grist); - g_free (grist); - - return url_ret; -} - #define EMAIL_LOCAL_ATOM "[\\pL\\pN!#$%&'*+/=?^_`{|}~-]+" #define EMAIL_LOCAL EMAIL_LOCAL_ATOM "(\\." EMAIL_LOCAL_ATOM ")*" #define EMAIL EMAIL_LOCAL "@" DOMAIN TLD -- 2.55.0