aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuard/WireGuard/UI/macOS
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-01-07 12:02:23 -0500
committerRoopesh Chander <roop@roopc.net>2019-01-14 14:52:34 +0530
commit64fe4158794484fe416a047a3f8f326602033ec8 (patch)
tree35e6da1ad3e81832b1a0a4048571c2cd675cb887 /WireGuard/WireGuard/UI/macOS
parentAdded syntax highlighting conf textview (diff)
downloadwireguard-apple-64fe4158794484fe416a047a3f8f326602033ec8.tar.xz
wireguard-apple-64fe4158794484fe416a047a3f8f326602033ec8.zip
Highlighter: use original file from contrib/examples/highlighter
This makes it easier to track updates and make diffs. Also, disable things we don't support in the NetworkExtension app. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'WireGuard/WireGuard/UI/macOS')
-rw-r--r--WireGuard/WireGuard/UI/macOS/highlighter.c934
-rw-r--r--WireGuard/WireGuard/UI/macOS/highlighter.h40
2 files changed, 492 insertions, 482 deletions
diff --git a/WireGuard/WireGuard/UI/macOS/highlighter.c b/WireGuard/WireGuard/UI/macOS/highlighter.c
index 6edf575..cc4a74a 100644
--- a/WireGuard/WireGuard/UI/macOS/highlighter.c
+++ b/WireGuard/WireGuard/UI/macOS/highlighter.c
@@ -13,576 +13,584 @@
#include "highlighter.h"
typedef struct {
- const char *s;
- size_t len;
+ const char *s;
+ size_t len;
} string_span_t;
static bool is_valid_key(string_span_t s)
{
- if (s.len != 44 || s.s[43] != '=')
- return false;
-
- for (size_t i = 0; i < 43; ++i) {
- if (!((s.s[i] >= '/' && s.s[i] <= '9') ||
- (s.s[i] >= 'A' && s.s[i] <= 'Z') ||
- (s.s[i] >= 'a' && s.s[i] <= 'z') ||
- s.s[i] == '+'))
- return false;
- }
- return true;
+ if (s.len != 44 || s.s[43] != '=')
+ return false;
+
+ for (size_t i = 0; i < 43; ++i) {
+ if (!((s.s[i] >= '/' && s.s[i] <= '9') ||
+ (s.s[i] >= 'A' && s.s[i] <= 'Z') ||
+ (s.s[i] >= 'a' && s.s[i] <= 'z') ||
+ s.s[i] == '+'))
+ return false;
+ }
+ return true;
}
static bool is_valid_hostname(string_span_t s)
{
- size_t num_digit = 0, num_entity = s.len;
-
- if (s.len > 63 || !s.len)
- return false;
- if (s.s[0] == '-' || s.s[s.len - 1] == '-')
- return false;
- if (s.s[0] == '.' || s.s[s.len - 1] == '.')
- return false;
-
- for (size_t i = 0; i < s.len; ++i) {
- if (isdigit(s.s[i])) {
- ++num_digit;
- continue;
- }
- if (s.s[i] == '.') {
- --num_entity;
- continue;
- }
-
- if (!((s.s[i] >= 'A' && s.s[i] <= 'Z') ||
- (s.s[i] >= 'a' && s.s[i] <= 'z') ||
- s.s[i] == '-'))
- return false;
-
- if (i && s.s[i] == '.' && s.s[i - 1] == '.')
- return false;
- }
- return num_digit != num_entity;
+ size_t num_digit = 0, num_entity = s.len;
+
+ if (s.len > 63 || !s.len)
+ return false;
+ if (s.s[0] == '-' || s.s[s.len - 1] == '-')
+ return false;
+ if (s.s[0] == '.' || s.s[s.len - 1] == '.')
+ return false;
+
+ for (size_t i = 0; i < s.len; ++i) {
+ if (isdigit(s.s[i])) {
+ ++num_digit;
+ continue;
+ }
+ if (s.s[i] == '.') {
+ --num_entity;
+ continue;
+ }
+
+ if (!((s.s[i] >= 'A' && s.s[i] <= 'Z') ||
+ (s.s[i] >= 'a' && s.s[i] <= 'z') ||
+ s.s[i] == '-'))
+ return false;
+
+ if (i && s.s[i] == '.' && s.s[i - 1] == '.')
+ return false;
+ }
+ return num_digit != num_entity;
}
static bool is_valid_ipv4(string_span_t s)
{
- for (size_t j, i = 0, pos = 0; i < 4 && pos < s.len; ++i) {
- uint32_t val = 0;
-
- for (j = 0; j < 3 && pos + j < s.len && isdigit(s.s[pos + j]); ++j)
- val = 10 * val + s.s[pos + j] - '0';
- if (j == 0 || (j > 1 && s.s[pos] == '0') || val > 255)
- return false;
- if (pos + j == s.len && i == 3)
- return true;
- if (s.s[pos + j] != '.')
- return false;
- pos += j + 1;
- }
- return false;
+ for (size_t j, i = 0, pos = 0; i < 4 && pos < s.len; ++i) {
+ uint32_t val = 0;
+
+ for (j = 0; j < 3 && pos + j < s.len && isdigit(s.s[pos + j]); ++j)
+ val = 10 * val + s.s[pos + j] - '0';
+ if (j == 0 || (j > 1 && s.s[pos] == '0') || val > 255)
+ return false;
+ if (pos + j == s.len && i == 3)
+ return true;
+ if (s.s[pos + j] != '.')
+ return false;
+ pos += j + 1;
+ }
+ return false;
}
static bool is_valid_ipv6(string_span_t s)
{
- size_t pos = 0;
- bool seen_colon = false;
-
- if (s.len < 2)
- return false;
- if (s.s[pos] == ':' && s.s[++pos] != ':')
- return false;
- if (s.s[s.len - 1] == ':' && s.s[s.len - 2] != ':')
- return false;
-
- for (size_t j, i = 0; pos < s.len; ++i) {
- if (s.s[pos] == ':' && !seen_colon) {
- seen_colon = true;
- if (++pos == s.len)
- break;
- if (i == 7)
- return false;
- continue;
- }
- for (j = 0; j < 4 && pos + j < s.len && isxdigit(s.s[pos + j]); ++j);
- if (j == 0)
- return false;
- if (pos + j == s.len && (seen_colon || i == 7))
- break;
- if (i == 7)
- return false;
- if (s.s[pos + j] != ':') {
- if (s.s[pos + j] != '.' || (i < 6 && !seen_colon))
- return false;
- return is_valid_ipv4((string_span_t){ s.s + pos, s.len - pos });
- }
- pos += j + 1;
- }
- return true;
+ size_t pos = 0;
+ bool seen_colon = false;
+
+ if (s.len < 2)
+ return false;
+ if (s.s[pos] == ':' && s.s[++pos] != ':')
+ return false;
+ if (s.s[s.len - 1] == ':' && s.s[s.len - 2] != ':')
+ return false;
+
+ for (size_t j, i = 0; pos < s.len; ++i) {
+ if (s.s[pos] == ':' && !seen_colon) {
+ seen_colon = true;
+ if (++pos == s.len)
+ break;
+ if (i == 7)
+ return false;
+ continue;
+ }
+ for (j = 0; j < 4 && pos + j < s.len && isxdigit(s.s[pos + j]); ++j);
+ if (j == 0)
+ return false;
+ if (pos + j == s.len && (seen_colon || i == 7))
+ break;
+ if (i == 7)
+ return false;
+ if (s.s[pos + j] != ':') {
+ if (s.s[pos + j] != '.' || (i < 6 && !seen_colon))
+ return false;
+ return is_valid_ipv4((string_span_t){ s.s + pos, s.len - pos });
+ }
+ pos += j + 1;
+ }
+ return true;
}
static bool is_valid_u16(string_span_t s)
{
- uint32_t val = 0;
-
- if (s.len > 5 || !s.len)
- return false;
-
- for (size_t i = 0; i < s.len; ++i) {
- if (!isdigit(s.s[i]))
- return false;
- val = 10 * val + s.s[i] - '0';
- }
- return val <= 65535;
+ uint32_t val = 0;
+
+ if (s.len > 5 || !s.len)
+ return false;
+
+ for (size_t i = 0; i < s.len; ++i) {
+ if (!isdigit(s.s[i]))
+ return false;
+ val = 10 * val + s.s[i] - '0';
+ }
+ return val <= 65535;
}
static bool is_valid_port(string_span_t s)
{
- return is_valid_u16(s);
+ return is_valid_u16(s);
}
static bool is_valid_mtu(string_span_t s)
{
- return is_valid_u16(s);
+ return is_valid_u16(s);
}
static bool is_valid_persistentkeepalive(string_span_t s)
{
- if (s.len == 3 && !memcmp(s.s, "off", 3))
- return true;
- return is_valid_u16(s);
+ if (s.len == 3 && !memcmp(s.s, "off", 3))
+ return true;
+ return is_valid_u16(s);
}
+#ifndef MOBILE_WGQUICK_SUBSET
static bool is_valid_u32(string_span_t s)
{
- uint64_t val = 0;
-
- if (s.len > 10 || !s.len)
- return false;
-
- if (s.len > 2 && s.s[0] == '0' && s.s[1] == 'x') {
- for (size_t i = 2; i < s.len; ++i) {
- if (s.s[i] - '0' < 10)
- val = 16 * val + (s.s[i] - '0');
- else if ((s.s[i] | 32) - 'a' < 6)
- val = 16 * val + (s.s[i] | 32) - 'a' + 10;
- else
- return false;
- }
- } else {
- for (size_t i = 0; i < s.len; ++i) {
- if (!isdigit(s.s[i]))
- return false;
- val = 10 * val + s.s[i] - '0';
- }
- }
- return val <= 4294967295U;
+ uint64_t val = 0;
+
+ if (s.len > 10 || !s.len)
+ return false;
+
+ if (s.len > 2 && s.s[0] == '0' && s.s[1] == 'x') {
+ for (size_t i = 2; i < s.len; ++i) {
+ if (s.s[i] - '0' < 10)
+ val = 16 * val + (s.s[i] - '0');
+ else if ((s.s[i] | 32) - 'a' < 6)
+ val = 16 * val + (s.s[i] | 32) - 'a' + 10;
+ else
+ return false;
+ }
+ } else {
+ for (size_t i = 0; i < s.len; ++i) {
+ if (!isdigit(s.s[i]))
+ return false;
+ val = 10 * val + s.s[i] - '0';
+ }
+ }
+ return val <= 4294967295U;
}
static bool is_valid_fwmark(string_span_t s)
{
- if (s.len == 3 && !memcmp(s.s, "off", 3))
- return true;
- return is_valid_u32(s);
+ if (s.len == 3 && !memcmp(s.s, "off", 3))
+ return true;
+ return is_valid_u32(s);
}
static bool is_valid_table(string_span_t s)
{
- if (s.len == 4 && !memcmp(s.s, "auto", 3))
- return true;
- if (s.len == 3 && !memcmp(s.s, "off", 3))
- return true;
- /* This pretty much invalidates the other checks, but rt_names.c's
- * fread_id_name does no validation aside from this. */
- if (s.len < 512)
- return true;
- return is_valid_u32(s);
+ if (s.len == 4 && !memcmp(s.s, "auto", 3))
+ return true;
+ if (s.len == 3 && !memcmp(s.s, "off", 3))
+ return true;
+ /* This pretty much invalidates the other checks, but rt_names.c's
+ * fread_id_name does no validation aside from this. */
+ if (s.len < 512)
+ return true;
+ return is_valid_u32(s);
}
static bool is_valid_saveconfig(string_span_t s)
{
- return (s.len == 4 && !memcmp(s.s, "true", 4)) ||
- (s.len == 5 && !memcmp(s.s, "false", 5));
+ return (s.len == 4 && !memcmp(s.s, "true", 4)) ||
+ (s.len == 5 && !memcmp(s.s, "false", 5));
+}
+
+static bool is_valid_prepostupdown(string_span_t s)
+{
+ /* It's probably not worthwhile to try to validate a bash expression.
+ * So instead we just demand non-zero length. */
+ return s.len;
}
+#endif
static bool is_valid_scope(string_span_t s)
{
- if (s.len > 64 || !s.len)
- return false;
- for (size_t i = 0; i < s.len; ++i) {
- if (!((s.s[i] >= 'A' && s.s[i] <= 'Z') ||
- (s.s[i] >= 'a' && s.s[i] <= 'z') ||
- isdigit(s.s[i]) || s.s[i] == '_' ||
- s.s[i] == '=' || s.s[i] == '+' ||
- s.s[i] == '.' || s.s[i] == '-'))
- return false;
- }
- return true;
+ if (s.len > 64 || !s.len)
+ return false;
+ for (size_t i = 0; i < s.len; ++i) {
+ if (!((s.s[i] >= 'A' && s.s[i] <= 'Z') ||
+ (s.s[i] >= 'a' && s.s[i] <= 'z') ||
+ isdigit(s.s[i]) || s.s[i] == '_' ||
+ s.s[i] == '=' || s.s[i] == '+' ||
+ s.s[i] == '.' || s.s[i] == '-'))
+ return false;
+ }
+ return true;
}
static bool is_valid_endpoint(string_span_t s)
{
-
- if (!s.len)
- return false;
-
- if (s.s[0] == '[') {
- bool seen_scope = false;
- string_span_t hostspan = { s.s + 1, 0 };
-
- for (size_t i = 1; i < s.len; ++i) {
- if (s.s[i] == '%') {
- if (seen_scope)
- return false;
- seen_scope = true;
- if (!is_valid_ipv6(hostspan))
- return false;
- hostspan = (string_span_t){ s.s + i + 1, 0 };
- } else if (s.s[i] == ']') {
- if (seen_scope) {
- if (!is_valid_scope(hostspan))
- return false;
- } else if (!is_valid_ipv6(hostspan)) {
- return false;
- }
- if (i == s.len - 1 || s.s[i + 1] != ':')
- return false;
- return is_valid_port((string_span_t){ s.s + i + 2, s.len - i - 2 });
- } else {
- ++hostspan.len;
- }
- }
- return false;
- }
- for (size_t i = 0; i < s.len; ++i) {
- if (s.s[i] == ':') {
- string_span_t host = { s.s, i }, port = { s.s + i + 1, s.len - i - 1};
- return is_valid_port(port) && (is_valid_ipv4(host) || is_valid_hostname(host));
- }
- }
- return false;
+
+ if (!s.len)
+ return false;
+
+ if (s.s[0] == '[') {
+ bool seen_scope = false;
+ string_span_t hostspan = { s.s + 1, 0 };
+
+ for (size_t i = 1; i < s.len; ++i) {
+ if (s.s[i] == '%') {
+ if (seen_scope)
+ return false;
+ seen_scope = true;
+ if (!is_valid_ipv6(hostspan))
+ return false;
+ hostspan = (string_span_t){ s.s + i + 1, 0 };
+ } else if (s.s[i] == ']') {
+ if (seen_scope) {
+ if (!is_valid_scope(hostspan))
+ return false;
+ } else if (!is_valid_ipv6(hostspan)) {
+ return false;
+ }
+ if (i == s.len - 1 || s.s[i + 1] != ':')
+ return false;
+ return is_valid_port((string_span_t){ s.s + i + 2, s.len - i - 2 });
+ } else {
+ ++hostspan.len;
+ }
+ }
+ return false;
+ }
+ for (size_t i = 0; i < s.len; ++i) {
+ if (s.s[i] == ':') {
+ string_span_t host = { s.s, i }, port = { s.s + i + 1, s.len - i - 1};
+ return is_valid_port(port) && (is_valid_ipv4(host) || is_valid_hostname(host));
+ }
+ }
+ return false;
}
static bool is_valid_network(string_span_t s)
{
- for (size_t i = 0; i < s.len; ++i) {
- if (s.s[i] == '/') {
- string_span_t ip = { s.s, i }, cidr = { s.s + i + 1, s.len - i - 1};
- uint16_t cidrval = 0;
-
- if (cidr.len > 3 || !cidr.len)
- return false;
-
- for (size_t j = 0; j < cidr.len; ++j) {
- if (!isdigit(cidr.s[j]))
- return false;
- cidrval = 10 * cidrval + cidr.s[j] - '0';
- }
- if (is_valid_ipv4(ip))
- return cidrval <= 32;
- else if (is_valid_ipv6(ip))
- return cidrval <= 128;
- return false;
- }
- }
- return is_valid_ipv4(s) || is_valid_ipv6(s);
-}
+ for (size_t i = 0; i < s.len; ++i) {
+ if (s.s[i] == '/') {
+ string_span_t ip = { s.s, i }, cidr = { s.s + i + 1, s.len - i - 1};
+ uint16_t cidrval = 0;
-static bool is_valid_dns(string_span_t s)
-{
- return is_valid_ipv4(s) || is_valid_ipv6(s);
+ if (cidr.len > 3 || !cidr.len)
+ return false;
+
+ for (size_t j = 0; j < cidr.len; ++j) {
+ if (!isdigit(cidr.s[j]))
+ return false;
+ cidrval = 10 * cidrval + cidr.s[j] - '0';
+ }
+ if (is_valid_ipv4(ip))
+ return cidrval <= 32;
+ else if (is_valid_ipv6(ip))
+ return cidrval <= 128;
+ return false;
+ }
+ }
+ return is_valid_ipv4(s) || is_valid_ipv6(s);
}
-static bool is_valid_prepostupdown(string_span_t s)
+static bool is_valid_dns(string_span_t s)
{
- /* It's probably not worthwhile to try to validate a bash expression.
- * So instead we just demand non-zero length. */
- return s.len;
+ return is_valid_ipv4(s) || is_valid_ipv6(s);
}
enum keytype {
- InterfaceSection,
- PrivateKey,
- ListenPort,
- FwMark,
- Address,
- DNS,
- MTU,
- Table,
- PreUp, PostUp, PreDown, PostDown,
- SaveConfig,
-
- PeerSection,
- PublicKey,
- PresharedKey,
- AllowedIPs,
- Endpoint,
- PersistentKeepalive,
-
- Invalid
+ InterfaceSection,
+ PrivateKey,
+ ListenPort,
+ Address,
+ DNS,
+ MTU,
+#ifndef MOBILE_WGQUICK_SUBSET
+ FwMark,
+ Table,
+ PreUp, PostUp, PreDown, PostDown,
+ SaveConfig,
+#endif
+
+ PeerSection,
+ PublicKey,
+ PresharedKey,
+ AllowedIPs,
+ Endpoint,
+ PersistentKeepalive,
+
+ Invalid
};
static enum keytype section_for_keytype(enum keytype t)
{
- if (t > InterfaceSection && t < PeerSection)
- return InterfaceSection;
- if (t > PeerSection && t < Invalid)
- return PeerSection;
- return Invalid;
+ if (t > InterfaceSection && t < PeerSection)
+ return InterfaceSection;
+ if (t > PeerSection && t < Invalid)
+ return PeerSection;
+ return Invalid;
}
static enum keytype get_keytype(string_span_t s)
{
#define check_enum(t) do { if (s.len == strlen(#t) && !strncasecmp(#t, s.s, s.len)) return t; } while (0)
- check_enum(PrivateKey);
- check_enum(ListenPort);
- check_enum(FwMark);
- check_enum(Address);
- check_enum(DNS);
- check_enum(MTU);
- check_enum(Table);
- check_enum(PreUp);
- check_enum(PostUp);
- check_enum(PreDown);
- check_enum(PostDown);
- check_enum(PublicKey);
- check_enum(PresharedKey);
- check_enum(AllowedIPs);
- check_enum(Endpoint);
- check_enum(PersistentKeepalive);
- check_enum(SaveConfig);
- return Invalid;
+ check_enum(PrivateKey);
+ check_enum(ListenPort);
+ check_enum(Address);
+ check_enum(DNS);
+ check_enum(MTU);
+ check_enum(PublicKey);
+ check_enum(PresharedKey);
+ check_enum(AllowedIPs);
+ check_enum(Endpoint);
+ check_enum(PersistentKeepalive);
+#ifndef MOBILE_WGQUICK_SUBSET
+ check_enum(FwMark);
+ check_enum(Table);
+ check_enum(PreUp);
+ check_enum(PostUp);
+ check_enum(PreDown);
+ check_enum(PostDown);
+ check_enum(SaveConfig);
+#endif
+ return Invalid;
#undef check_enum
}
static enum keytype get_sectiontype(string_span_t s)
{
- if (s.len == 6 && !strncasecmp("[Peer]", s.s, 6))
- return PeerSection;
- if (s.len == 11 && !strncasecmp("[Interface]", s.s, 11))
- return InterfaceSection;
- return Invalid;
+ if (s.len == 6 && !strncasecmp("[Peer]", s.s, 6))
+ return PeerSection;
+ if (s.len == 11 && !strncasecmp("[Interface]", s.s, 11))
+ return InterfaceSection;
+ return Invalid;
}
struct highlight_span_array {
- size_t len, capacity;
- struct highlight_span *spans;
+ size_t len, capacity;
+ struct highlight_span *spans;
};
/* A useful OpenBSD-ism. */
static void *realloc_array(void *optr, size_t nmemb, size_t size)
{
- if ((nmemb >= (size_t)1 << (sizeof(size_t) * 4) ||
- size >= (size_t)1 << (sizeof(size_t) * 4)) &&
- nmemb > 0 && SIZE_MAX / nmemb < size) {
- errno = ENOMEM;
- return NULL;
- }
- return realloc(optr, size * nmemb);
+ if ((nmemb >= (size_t)1 << (sizeof(size_t) * 4) ||
+ size >= (size_t)1 << (sizeof(size_t) * 4)) &&
+ nmemb > 0 && SIZE_MAX / nmemb < size) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ return realloc(optr, size * nmemb);
}
static bool append_highlight_span(struct highlight_span_array *a, const char *o, string_span_t s, enum highlight_type t)
{
- if (!s.len)
- return true;
- if (a->len >= a->capacity) {
- struct highlight_span *resized;
-
- a->capacity = a->capacity ? a->capacity * 2 : 64;
- resized = realloc_array(a->spans, a->capacity, sizeof(*resized));
- if (!resized) {
- free(a->spans);
- memset(a, 0, sizeof(*a));
- return false;
- }
- a->spans = resized;
- }
- a->spans[a->len++] = (struct highlight_span){ t, s.s - o, s.len };
- return true;
+ if (!s.len)
+ return true;
+ if (a->len >= a->capacity) {
+ struct highlight_span *resized;
+
+ a->capacity = a->capacity ? a->capacity * 2 : 64;
+ resized = realloc_array(a->spans, a->capacity, sizeof(*resized));
+ if (!resized) {
+ free(a->spans);
+ memset(a, 0, sizeof(*a));
+ return false;
+ }
+ a->spans = resized;
+ }
+ a->spans[a->len++] = (struct highlight_span){ t, s.s - o, s.len };
+ return true;
}
static void highlight_multivalue_value(struct highlight_span_array *ret, const string_span_t parent, const string_span_t s, enum keytype section)
{
- switch (section) {
- case DNS:
- append_highlight_span(ret, parent.s, s, is_valid_dns(s) ? HighlightIP : HighlightError);
- break;
- case Address:
- case AllowedIPs: {
- size_t slash;
-
- if (!is_valid_network(s)) {
- append_highlight_span(ret, parent.s, s, HighlightError);
- break;
- }
- for (slash = 0; slash < s.len; ++slash) {
- if (s.s[slash] == '/')
- break;
- }
- if (slash == s.len) {
- append_highlight_span(ret, parent.s, s, HighlightIP);
- } else {
- append_highlight_span(ret, parent.s, (string_span_t){ s.s, slash }, HighlightIP);
- append_highlight_span(ret, parent.s, (string_span_t){ s.s + slash, 1 }, HighlightDelimiter);
- append_highlight_span(ret, parent.s, (string_span_t){ s.s + slash + 1, s.len - slash - 1 }, HighlightCidr);
- }
- break;
- }
- default:
- append_highlight_span(ret, parent.s, s, HighlightError);
- }
+ switch (section) {
+ case DNS:
+ append_highlight_span(ret, parent.s, s, is_valid_dns(s) ? HighlightIP : HighlightError);
+ break;
+ case Address:
+ case AllowedIPs: {
+ size_t slash;
+
+ if (!is_valid_network(s)) {
+ append_highlight_span(ret, parent.s, s, HighlightError);
+ break;
+ }
+ for (slash = 0; slash < s.len; ++slash) {
+ if (s.s[slash] == '/')
+ break;
+ }
+ if (slash == s.len) {
+ append_highlight_span(ret, parent.s, s, HighlightIP);
+ } else {
+ append_highlight_span(ret, parent.s, (string_span_t){ s.s, slash }, HighlightIP);
+ append_highlight_span(ret, parent.s, (string_span_t){ s.s + slash, 1 }, HighlightDelimiter);
+ append_highlight_span(ret, parent.s, (string_span_t){ s.s + slash + 1, s.len - slash - 1 }, HighlightCidr);
+ }
+ break;
+ }
+ default:
+ append_highlight_span(ret, parent.s, s, HighlightError);
+ }
}
static void highlight_multivalue(struct highlight_span_array *ret, const string_span_t parent, const string_span_t s, enum keytype section)
{
- string_span_t current_span = { s.s, 0 };
- size_t len_at_last_space = 0;
-
- for (size_t i = 0; i < s.len; ++i) {
- if (s.s[i] == ',') {
- current_span.len = len_at_last_space;
- highlight_multivalue_value(ret, parent, current_span, section);
- append_highlight_span(ret, parent.s, (string_span_t){ s.s + i, 1 }, HighlightDelimiter);
- len_at_last_space = 0;
- current_span = (string_span_t){ s.s + i + 1, 0 };
- } else if (s.s[i] == ' ' || s.s[i] == '\t') {
- if (&s.s[i] == current_span.s && !current_span.len)
- ++current_span.s;
- else
- ++current_span.len;
- } else {
- len_at_last_space = ++current_span.len;
- }
- }
- current_span.len = len_at_last_space;
- if (current_span.len)
- highlight_multivalue_value(ret, parent, current_span, section);
- else if (ret->spans[ret->len - 1].type == HighlightDelimiter)
- ret->spans[ret->len - 1].type = HighlightError;
+ string_span_t current_span = { s.s, 0 };
+ size_t len_at_last_space = 0;
+
+ for (size_t i = 0; i < s.len; ++i) {
+ if (s.s[i] == ',') {
+ current_span.len = len_at_last_space;
+ highlight_multivalue_value(ret, parent, current_span, section);
+ append_highlight_span(ret, parent.s, (string_span_t){ s.s + i, 1 }, HighlightDelimiter);
+ len_at_last_space = 0;
+ current_span = (string_span_t){ s.s + i + 1, 0 };
+ } else if (s.s[i] == ' ' || s.s[i] == '\t') {
+ if (&s.s[i] == current_span.s && !current_span.len)
+ ++current_span.s;
+ else
+ ++current_span.len;
+ } else {
+ len_at_last_space = ++current_span.len;
+ }
+ }
+ current_span.len = len_at_last_space;
+ if (current_span.len)
+ highlight_multivalue_value(ret, parent, current_span, section);
+ else if (ret->spans[ret->len - 1].type == HighlightDelimiter)
+ ret->spans[ret->len - 1].type = HighlightError;
}
static void highlight_value(struct highlight_span_array *ret, const string_span_t parent, const string_span_t s, enum keytype section)
{
- switch (section) {
- case PrivateKey:
- case PublicKey:
- case PresharedKey:
- append_highlight_span(ret, parent.s, s, is_valid_key(s) ? HighlightKey : HighlightError);
- break;
- case FwMark:
- append_highlight_span(ret, parent.s, s, is_valid_fwmark(s) ? HighlightFwMark : HighlightError);
- break;
- case Table:
- append_highlight_span(ret, parent.s, s, is_valid_table(s) ? HighlightTable : HighlightError);
- break;
- case MTU:
- append_highlight_span(ret, parent.s, s, is_valid_mtu(s) ? HighlightMTU : HighlightError);
- break;
- case SaveConfig:
- append_highlight_span(ret, parent.s, s, is_valid_saveconfig(s) ? HighlightSaveConfig : HighlightError);
- break;
- case PreUp:
- case PostUp:
- case PreDown:
- case PostDown:
- append_highlight_span(ret, parent.s, s, is_valid_prepostupdown(s) ? HighlightCmd : HighlightError);
- break;
- case ListenPort:
- append_highlight_span(ret, parent.s, s, is_valid_port(s) ? HighlightPort : HighlightError);
- break;
- case PersistentKeepalive:
- append_highlight_span(ret, parent.s, s, is_valid_persistentkeepalive(s) ? HighlightKeepalive : HighlightError);
- break;
- case Endpoint: {
- size_t colon;
-
- if (!is_valid_endpoint(s)) {
- append_highlight_span(ret, parent.s, s, HighlightError);
- break;
- }
- for (colon = s.len; colon --> 0;) {
- if (s.s[colon] == ':')
- break;
- }
- append_highlight_span(ret, parent.s, (string_span_t){ s.s, colon }, HighlightHost);
- append_highlight_span(ret, parent.s, (string_span_t){ s.s + colon, 1 }, HighlightDelimiter);
- append_highlight_span(ret, parent.s, (string_span_t){ s.s + colon + 1, s.len - colon - 1 }, HighlightPort);
- break;
- }
- case Address:
- case DNS:
- case AllowedIPs:
- highlight_multivalue(ret, parent, s, section);
- break;
- default:
- append_highlight_span(ret, parent.s, s, HighlightError);
- }
+ switch (section) {
+ case PrivateKey:
+ case PublicKey:
+ case PresharedKey:
+ append_highlight_span(ret, parent.s, s, is_valid_key(s) ? HighlightKey : HighlightError);
+ break;
+ case MTU:
+ append_highlight_span(ret, parent.s, s, is_valid_mtu(s) ? HighlightMTU : HighlightError);
+ break;
+#ifndef MOBILE_WGQUICK_SUBSET
+ case SaveConfig:
+ append_highlight_span(ret, parent.s, s, is_valid_saveconfig(s) ? HighlightSaveConfig : HighlightError);
+ break;
+ case FwMark:
+ append_highlight_span(ret, parent.s, s, is_valid_fwmark(s) ? HighlightFwMark : HighlightError);
+ break;
+ case Table:
+ append_highlight_span(ret, parent.s, s, is_valid_table(s) ? HighlightTable : HighlightError);
+ break;
+ case PreUp:
+ case PostUp:
+ case PreDown:
+ case PostDown:
+ append_highlight_span(ret, parent.s, s, is_valid_prepostupdown(s) ? HighlightCmd : HighlightError);
+ break;
+#endif
+ case ListenPort:
+ append_highlight_span(ret, parent.s, s, is_valid_port(s) ? HighlightPort : HighlightError);
+ break;
+ case PersistentKeepalive:
+ append_highlight_span(ret, parent.s, s, is_valid_persistentkeepalive(s) ? HighlightKeepalive : HighlightError);
+ break;
+ case Endpoint: {
+ size_t colon;
+
+ if (!is_valid_endpoint(s)) {
+ append_highlight_span(ret, parent.s, s, HighlightError);
+ break;
+ }
+ for (colon = s.len; colon --> 0;) {
+ if (s.s[colon] == ':')
+ break;
+ }
+ append_highlight_span(ret, parent.s, (string_span_t){ s.s, colon }, HighlightHost);
+ append_highlight_span(ret, parent.s, (string_span_t){ s.s + colon, 1 }, HighlightDelimiter);
+ append_highlight_span(ret, parent.s, (string_span_t){ s.s + colon + 1, s.len - colon - 1 }, HighlightPort);
+ break;
+ }
+ case Address:
+ case DNS:
+ case AllowedIPs:
+ highlight_multivalue(ret, parent, s, section);
+ break;
+ default:
+ append_highlight_span(ret, parent.s, s, HighlightError);
+ }
}
struct highlight_span *highlight_config(const char *config)
{
- struct highlight_span_array ret = { 0 };
- const string_span_t s = { config, strlen(config) };
- string_span_t current_span = { s.s, 0 };
- enum keytype current_section = Invalid, current_keytype = Invalid;
- enum { OnNone, OnKey, OnValue, OnComment, OnSection } state = OnNone;
- size_t len_at_last_space = 0, equals_location = 0;
-
- for (size_t i = 0; i <= s.len; ++i) {
- if (i == s.len || s.s[i] == '\n' || (state != OnComment && s.s[i] == '#')) {
- if (state == OnKey) {
- current_span.len = len_at_last_space;
- append_highlight_span(&ret, s.s, current_span, HighlightError);
- } else if (state == OnValue) {
- if (current_span.len) {
- append_highlight_span(&ret, s.s, (string_span_t){ s.s + equals_location, 1 }, HighlightDelimiter);
- current_span.len = len_at_last_space;
- highlight_value(&ret, s, current_span, current_keytype);
- } else {
- append_highlight_span(&ret, s.s, (string_span_t){ s.s + equals_location, 1 }, HighlightError);
- }
- } else if (state == OnSection) {
- current_span.len = len_at_last_space;
- current_section = get_sectiontype(current_span);
- append_highlight_span(&ret, s.s, current_span, current_section == Invalid ? HighlightError : HighlightSection);
- } else if (state == OnComment) {
- append_highlight_span(&ret, s.s, current_span, HighlightComment);
- }
- if (i == s.len)
- break;
- len_at_last_space = 0;
- current_keytype = Invalid;
- if (s.s[i] == '#') {
- current_span = (string_span_t){ s.s + i, 1 };
- state = OnComment;
- } else {
- current_span = (string_span_t){ s.s + i + 1, 0 };
- state = OnNone;
- }
- } else if (state == OnComment) {
- ++current_span.len;
- } else if (s.s[i] == ' ' || s.s[i] == '\t') {
- if (&s.s[i] == current_span.s && !current_span.len)
- ++current_span.s;
- else
- ++current_span.len;
- } else if (s.s[i] == '=' && state == OnKey) {
- current_span.len = len_at_last_space;
- current_keytype = get_keytype(current_span);
- enum keytype section = section_for_keytype(current_keytype);
- if (section == Invalid || current_keytype == Invalid || section != current_section)
- append_highlight_span(&ret, s.s, current_span, HighlightError);
- else
- append_highlight_span(&ret, s.s, current_span, HighlightKeytype);
- equals_location = i;
- current_span = (string_span_t){ s.s + i + 1, 0 };
- state = OnValue;
- } else {
- if (state == OnNone)
- state = s.s[i] == '[' ? OnSection : OnKey;
- len_at_last_space = ++current_span.len;
- }
- }
-
- append_highlight_span(&ret, s.s, (string_span_t){ s.s, -1 }, HighlightEnd);
- return ret.spans;
+ struct highlight_span_array ret = { 0 };
+ const string_span_t s = { config, strlen(config) };
+ string_span_t current_span = { s.s, 0 };
+ enum keytype current_section = Invalid, current_keytype = Invalid;
+ enum { OnNone, OnKey, OnValue, OnComment, OnSection } state = OnNone;
+ size_t len_at_last_space = 0, equals_location = 0;
+
+ for (size_t i = 0; i <= s.len; ++i) {
+ if (i == s.len || s.s[i] == '\n' || (state != OnComment && s.s[i] == '#')) {
+ if (state == OnKey) {
+ current_span.len = len_at_last_space;
+ append_highlight_span(&ret, s.s, current_span, HighlightError);
+ } else if (state == OnValue) {
+ if (current_span.len) {
+ append_highlight_span(&ret, s.s, (string_span_t){ s.s + equals_location, 1 }, HighlightDelimiter);
+ current_span.len = len_at_last_space;
+ highlight_value(&ret, s, current_span, current_keytype);
+ } else {
+ append_highlight_span(&ret, s.s, (string_span_t){ s.s + equals_location, 1 }, HighlightError);
+ }
+ } else if (state == OnSection) {
+ current_span.len = len_at_last_space;
+ current_section = get_sectiontype(current_span);
+ append_highlight_span(&ret, s.s, current_span, current_section == Invalid ? HighlightError : HighlightSection);
+ } else if (state == OnComment) {
+ append_highlight_span(&ret, s.s, current_span, HighlightComment);
+ }
+ if (i == s.len)
+ break;
+ len_at_last_space = 0;
+ current_keytype = Invalid;
+ if (s.s[i] == '#') {
+ current_span = (string_span_t){ s.s + i, 1 };
+ state = OnComment;
+ } else {
+ current_span = (string_span_t){ s.s + i + 1, 0 };
+ state = OnNone;
+ }
+ } else if (state == OnComment) {
+ ++current_span.len;
+ } else if (s.s[i] == ' ' || s.s[i] == '\t') {
+ if (&s.s[i] == current_span.s && !current_span.len)
+ ++current_span.s;
+ else
+ ++current_span.len;
+ } else if (s.s[i] == '=' && state == OnKey) {
+ current_span.len = len_at_last_space;
+ current_keytype = get_keytype(current_span);
+ enum keytype section = section_for_keytype(current_keytype);
+ if (section == Invalid || current_keytype == Invalid || section != current_section)
+ append_highlight_span(&ret, s.s, current_span, HighlightError);
+ else
+ append_highlight_span(&ret, s.s, current_span, HighlightKeytype);
+ equals_location = i;
+ current_span = (string_span_t){ s.s + i + 1, 0 };
+ state = OnValue;
+ } else {
+ if (state == OnNone)
+ state = s.s[i] == '[' ? OnSection : OnKey;
+ len_at_last_space = ++current_span.len;
+ }
+ }
+
+ append_highlight_span(&ret, s.s, (string_span_t){ s.s, -1 }, HighlightEnd);
+ return ret.spans;
}
diff --git a/WireGuard/WireGuard/UI/macOS/highlighter.h b/WireGuard/WireGuard/UI/macOS/highlighter.h
index 9368af6..d88638b 100644
--- a/WireGuard/WireGuard/UI/macOS/highlighter.h
+++ b/WireGuard/WireGuard/UI/macOS/highlighter.h
@@ -6,28 +6,30 @@
#include <sys/types.h>
enum highlight_type {
- HighlightSection,
- HighlightKeytype,
- HighlightKey,
- HighlightCmd,
- HighlightIP,
- HighlightCidr,
- HighlightHost,
- HighlightPort,
- HighlightTable,
- HighlightFwMark,
- HighlightMTU,
- HighlightSaveConfig,
- HighlightKeepalive,
- HighlightComment,
- HighlightDelimiter,
- HighlightError,
- HighlightEnd
+ HighlightSection,
+ HighlightKeytype,
+ HighlightKey,
+ HighlightIP,
+ HighlightCidr,
+ HighlightHost,
+ HighlightPort,
+ HighlightMTU,
+ HighlightKeepalive,
+ HighlightComment,
+ HighlightDelimiter,
+#ifndef MOBILE_WGQUICK_SUBSET
+ HighlightTable,
+ HighlightFwMark,
+ HighlightSaveConfig,
+ HighlightCmd,
+#endif
+ HighlightError,
+ HighlightEnd
};
struct highlight_span {
- enum highlight_type type;
- size_t start, len;
+ enum highlight_type type;
+ size_t start, len;
};
struct highlight_span *highlight_config(const char *config);