static inline int http_date_parse_word(struct http_date_parser *parser, int maxchars, string_t **word_r) { string_t *word; int i; if (parser->cur >= parser->end || !i_isalpha(parser->cur[0])) return 0; word = t_str_new(maxchars); str_append_c(word, parser->cur[0]); parser->cur++; for (i=0; i < maxchars-1; i++) { if (parser->cur >= parser->end || !i_isalpha(parser->cur[0])) break; str_append_c(word, parser->cur[0]); parser->cur++; } if (i_isalpha(parser->cur[0])) return -1; *word_r = word; return 1; }
int uri_cut_scheme(const char **uri_p, const char **scheme_r) { const char *p = *uri_p; size_t len = 1; /* RFC 3968: * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ if (!i_isalpha(*p)) return -1; p++; while (len < URI_MAX_SCHEME_NAME_LEN && *p != '\0') { if (!i_isalnum(*p) && *p != '+' && *p != '-' && *p != '.') break; p++; len++; } if (*p != ':') return -1; if (scheme_r != NULL) *scheme_r = t_strdup_until(*uri_p, p); *uri_p = p + 1; return 0; }
bool sieve_variable_identifier_is_valid(const char *identifier) { const char *p = identifier; size_t plen = strlen(identifier); const char *pend; if ( plen == 0 || plen >= EXT_VARIABLES_MAX_VARIABLE_NAME_LEN ) return FALSE; pend = PTR_OFFSET(identifier, plen); if ( *p == '_' || i_isalpha(*p) ) { p++; while ( p < pend && (*p == '_' || i_isalnum(*p)) ) { p++; } } return ( p == pend ); }
static const char *ext_enotify_uri_scheme_parse(const char **uri_p) { string_t *scheme = t_str_new(EXT_ENOTIFY_MAX_SCHEME_LEN); const char *p = *uri_p; unsigned int len = 0; /* RFC 3968: * * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) * * FIXME: we do not allow '%' in schemes. Is this correct? */ if ( !i_isalpha(*p) ) return NULL; str_append_c(scheme, *p); p++; while ( *p != '\0' && len < EXT_ENOTIFY_MAX_SCHEME_LEN ) { if ( !i_isalnum(*p) && *p != '+' && *p != '-' && *p != '.' ) break; str_append_c(scheme, *p); p++; len++; } if ( *p != ':' ) return NULL; p++; *uri_p = p; return str_c(scheme); }
/* Expand key code - returns TRUE if successful. */ static int expand_key(const char *key, GSList **out, int *limit) { GSList *tmp; const char *start; int last_hyphen; if ((*limit)-- < 0) { return FALSE; } /* meta-^W^Gf -> ^[-^W-^G-f */ start = NULL; last_hyphen = TRUE; for (; *key != '\0'; key++) { if (start != NULL) { if (i_isalnum(*key) || *key == '_') { /* key combo continues */ continue; } if (!expand_combo(start, key-1, out, limit)) return FALSE; expand_out_char(*out, '-'); start = NULL; } if (*key == '-') { if (last_hyphen) { expand_out_char(*out, '-'); expand_out_char(*out, '-'); } last_hyphen = !last_hyphen; } else if (*key == '^') { expand_out_char(*out, '^'); /* ctrl-code */ if (key[1] != '\0' && key[1] != '-') { key++; expand_out_char(*out, *key); } else { /* escaped syntax for ^, see gui-readline.c */ expand_out_char(*out, '-'); } expand_out_char(*out, '-'); last_hyphen = FALSE; /* optional */ } else if (last_hyphen && i_isalpha(*key)) { /* possibly beginning of keycombo */ start = key; last_hyphen = FALSE; } else if (g_utf8_validate(key, -1, NULL)) { /* Assume we are looking at the start of a * multibyte sequence we will receive as-is, * so add it to the list as-is. */ const char *p, *end = g_utf8_next_char(key); for (p = key; p != end; p++) expand_out_char(*out, *p); expand_out_char(*out, '-'); /* The for loop skips past the remaining character. * Nasty, I know... */ key = end - 1; last_hyphen = FALSE; } else { expand_out_char(*out, *key); expand_out_char(*out, '-'); last_hyphen = FALSE; /* optional */ } } if (start != NULL) return expand_combo(start, key-1, out, limit); for (tmp = *out; tmp != NULL; tmp = tmp->next) { GString *str = tmp->data; g_string_truncate(str, str->len-1); } return TRUE; }
/* check if quit message is a netsplit message */ int quitmsg_is_split(const char *msg) { const char *host1, *host2, *p; int prev, len, host1_dot, host2_dot; g_return_val_if_fail(msg != NULL, FALSE); /* NOTE: there used to be some paranoia checks (some older IRC clients have even more), but they're pretty useless nowadays, since IRC server prefixes the quit message with a space if it looks like a netsplit message. So, the check is currently just: - host1.domain1 host2.domain2 - top-level domains have to be 2+ characters long, containing only alphabets - only 1 space - no double-dots (".." - probably useless check) - hosts/domains can't start or end with a dot - the two hosts can't be identical (probably useless check) - can't contain ':' or '/' chars (some servers allow URLs) */ host1 = msg; host2 = NULL; prev = '\0'; len = 0; host1_dot = host2_dot = 0; while (*msg != '\0') { if (*msg == ' ') { if (prev == '.' || prev == '\0') { /* domains can't end with '.', space can't be the first character in msg. */ return FALSE; } if (host2 != NULL) return FALSE; /* only one space allowed */ if (!host1_dot) return FALSE; /* host1 didn't have domain */ host2 = msg+1; len = -1; } else if (*msg == '.') { if (prev == '\0' || prev == ' ' || prev == '.') { /* domains can't start with '.' and can't have ".." */ return FALSE; } if (host2 != NULL) host2_dot = TRUE; else host1_dot = TRUE; } else if (*msg == ':' || *msg == '/') return FALSE; prev = *msg; msg++; len++; } if (!host2_dot || prev == '.') return FALSE; if (len == (int) (host2-host1)-1 && g_strncasecmp(host1, host2, len) == 0) return FALSE; /* hosts can't be the same */ /* top-domain1 must be 2+ chars long and contain only alphabets */ p = host2-1; while (p[-1] != '.') { if (!i_isalpha(p[-1])) return FALSE; p--; } if (host2-p-1 < 2) return FALSE; /* top-domain2 must be 2+ chars long and contain only alphabets */ p = host2+strlen(host2); while (p[-1] != '.') { if (!i_isalpha(p[-1])) return FALSE; p--; } if (strlen(p) < 2) return FALSE; return TRUE; }