Add a few token validation functions

This commit is contained in:
Přemysl Eric Janouch 2014-07-13 03:26:33 +02:00
parent ccb2e4006d
commit 4904128c98
1 changed files with 87 additions and 0 deletions

View File

@ -89,6 +89,93 @@ setup_signal_handlers (void)
}
}
// --- IRC token validation ----------------------------------------------------
enum validation_result
{
VALIDATION_OK,
VALIDATION_ERROR_EMPTY,
VALIDATION_ERROR_TOO_LONG,
VALIDATION_ERROR_INVALID
};
// Everything as per RFC 2812
#define IRC_NICKNAME_MAX 9
#define IRC_HOSTNAME_MAX 63
// Anything to keep it as short as possible
#define SN "[0-9A-Za-z][-0-9A-Za-z]*[0-9A-Za-z]*"
#define N4 "[0-9]{1,3}"
#define N6 "[0-9ABCDEFabcdef]{1,}"
#define LE "A-Za-z"
#define SP "\\[\\]\\\\`_^{|}"
static const char *
irc_validate_to_str (enum validation_result result)
{
switch (result)
{
case VALIDATION_OK: return "success";
case VALIDATION_ERROR_EMPTY: return "the value is empty";
case VALIDATION_ERROR_INVALID: return "invalid format";
case VALIDATION_ERROR_TOO_LONG: return "the value is too long";
default: abort ();
}
}
// TODO: at least cache the resulting `regex_t' in a `struct str_map'
static enum validation_result
irc_validate_hostname (const char *hostname)
{
if (!*hostname)
return VALIDATION_ERROR_EMPTY;
if (!regex_match ("^" SN "(\\." SN ")*$", hostname, NULL))
return VALIDATION_ERROR_INVALID;
if (strlen (hostname) > IRC_HOSTNAME_MAX)
return VALIDATION_ERROR_TOO_LONG;
return VALIDATION_OK;
}
static bool
irc_is_valid_hostaddr (const char *hostaddr)
{
if (regex_match ("^" N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr, NULL)
|| regex_match ("^" N6 ":" N6 ":" N6 ":" N6 ":"
N6 ":" N6 ":" N6 ":" N6 "$", hostaddr, NULL)
|| regex_match ("^0:0:0:0:0:(0|[Ff]{4}):"
N4 "\\." N4 "\\." N4 "\\." N4 "$", hostaddr, NULL))
return true;
return false;
}
static bool
irc_is_valid_host (const char *host)
{
return irc_validate_hostname (host) == VALIDATION_OK
|| irc_is_valid_hostaddr (host);
}
static bool
irc_validate_nickname (const char *nickname)
{
if (!*nickname)
return VALIDATION_ERROR_EMPTY;
if (!regex_match ("^[" LE SP "][-0-9" LE SP "]*$", nickname, NULL))
return VALIDATION_ERROR_INVALID;
if (strlen (nickname) > IRC_NICKNAME_MAX)
return VALIDATION_ERROR_TOO_LONG;
return VALIDATION_OK;
}
#undef SN
#undef N4
#undef N6
#undef LE
#undef SP
// --- Application data --------------------------------------------------------
enum