From 6cce8c57ccf90438d3137937202f172bed8be20a Mon Sep 17 00:00:00 2001 From: Alex Denes Date: Sat, 26 Sep 2020 23:22:05 +0200 Subject: [PATCH] Fix reseved identifiers, fix problems about signedness and casting and add a few more test cases --- .clang-tidy | 184 ++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 4 +- CMakeLists.txt | 2 +- include/functions.h | 5 +- include/helpers.h | 5 +- include/mappings.h | 6 +- include/types.h | 36 +++++---- include/uirc.h | 1 + src/assemblers.c | 65 ++++++++-------- src/assemblers.h | 12 +-- src/helpers.c | 6 +- src/helpers.h | 9 ++- src/misc.c | 9 ++- src/misc.h | 12 +-- src/taghelpers.c | 1 + src/taghelpers.h | 7 +- src/tokenizers.c | 16 ++-- src/tokenizers.h | 6 +- src/validators.c | 5 +- src/validators.h | 6 ++ tests/tokenizer.c | 38 +++++++-- 21 files changed, 340 insertions(+), 95 deletions(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..1edc2d4 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,184 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-readability-isolate-declaration,-readability-else-after-return,-readability-braces-around-statements' +WarningsAsErrors: '' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: none +User: caskd +CheckOptions: + - key: bugprone-argument-comment.CommentBoolLiterals + value: '0' + - key: bugprone-argument-comment.CommentCharacterLiterals + value: '0' + - key: bugprone-argument-comment.CommentFloatLiterals + value: '0' + - key: bugprone-argument-comment.CommentIntegerLiterals + value: '0' + - key: bugprone-argument-comment.CommentNullPtrs + value: '0' + - key: bugprone-argument-comment.CommentStringLiterals + value: '0' + - key: bugprone-argument-comment.CommentUserDefinedLiterals + value: '0' + - key: bugprone-argument-comment.IgnoreSingleArgument + value: '0' + - key: bugprone-argument-comment.StrictMode + value: '0' + - key: bugprone-assert-side-effect.AssertMacros + value: assert + - key: bugprone-assert-side-effect.CheckFunctionCalls + value: '0' + - key: bugprone-dangling-handle.HandleClasses + value: 'std::basic_string_view;std::experimental::basic_string_view' + - key: bugprone-dynamic-static-initializers.HeaderFileExtensions + value: ',h,hh,hpp,hxx' + - key: bugprone-exception-escape.FunctionsThatShouldNotThrow + value: '' + - key: bugprone-exception-escape.IgnoredExceptions + value: '' + - key: bugprone-misplaced-widening-cast.CheckImplicitCasts + value: '0' + - key: bugprone-not-null-terminated-result.WantToUseSafeFunctions + value: '1' + - key: bugprone-signed-char-misuse.CharTypdefsToIgnore + value: '' + - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant + value: '1' + - key: bugprone-sizeof-expression.WarnOnSizeOfConstant + value: '1' + - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression + value: '0' + - key: bugprone-sizeof-expression.WarnOnSizeOfThis + value: '1' + - key: bugprone-string-constructor.LargeLengthThreshold + value: '8388608' + - key: bugprone-string-constructor.WarnOnLargeLength + value: '1' + - key: bugprone-suspicious-enum-usage.StrictMode + value: '0' + - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens + value: '5' + - key: bugprone-suspicious-missing-comma.RatioThreshold + value: '0.200000' + - key: bugprone-suspicious-missing-comma.SizeThreshold + value: '5' + - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions + value: '' + - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison + value: '1' + - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison + value: '0' + - key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit + value: '16' + - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField + value: '1' + - key: bugprone-unused-return-value.CheckedFunctions + value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty' + - key: cert-dcl16-c.NewSuffixes + value: 'L;LL;LU;LLU' + - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField + value: '0' + - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors + value: '1' + - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic + value: '1' + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: misc-definitions-in-headers.HeaderFileExtensions + value: ',h,hh,hpp,hxx' + - key: misc-definitions-in-headers.UseHeaderFileExtension + value: '1' + - key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries + value: '1' + - key: misc-unused-parameters.StrictMode + value: '0' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: modernize-use-nullptr.NullMacros + value: 'NULL' + - key: performance-faster-string-find.StringLikeClasses + value: 'std::basic_string' + - key: performance-for-range-copy.AllowedTypes + value: '' + - key: performance-for-range-copy.WarnOnAllAutoCopies + value: '0' + - key: performance-inefficient-string-concatenation.StrictMode + value: '0' + - key: performance-inefficient-vector-operation.EnableProto + value: '0' + - key: performance-inefficient-vector-operation.VectorLikeClasses + value: '::std::vector' + - key: performance-move-const-arg.CheckTriviallyCopyableMove + value: '1' + - key: performance-move-constructor-init.IncludeStyle + value: llvm + - key: performance-no-automatic-move.AllowedTypes + value: '' + - key: performance-type-promotion-in-math-fn.IncludeStyle + value: llvm + - key: performance-unnecessary-copy-initialization.AllowedTypes + value: '' + - key: performance-unnecessary-value-param.AllowedTypes + value: '' + - key: performance-unnecessary-value-param.IncludeStyle + value: llvm + - key: readability-function-size.BranchThreshold + value: '4294967295' + - key: readability-function-size.LineThreshold + value: '4294967295' + - key: readability-function-size.NestingThreshold + value: '4294967295' + - key: readability-function-size.ParameterThreshold + value: '4294967295' + - key: readability-function-size.StatementThreshold + value: '800' + - key: readability-function-size.VariableThreshold + value: '4294967295' + - key: readability-identifier-naming.IgnoreFailedSplit + value: '0' + - key: readability-implicit-bool-conversion.AllowIntegerConditions + value: '0' + - key: readability-implicit-bool-conversion.AllowPointerConditions + value: '0' + - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros + value: '1' + - key: readability-inconsistent-declaration-parameter-name.Strict + value: '0' + - key: readability-magic-numbers.IgnoredFloatingPointValues + value: '1.0;100.0;' + - key: readability-magic-numbers.IgnoredIntegerValues + value: '1;2;3;4;' + - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors + value: '0' + - key: readability-redundant-smartptr-get.IgnoreMacros + value: '1' + - key: readability-redundant-string-init.StringNames + value: '::std::basic_string' + - key: readability-simplify-boolean-expr.ChainedConditionalAssignment + value: '0' + - key: readability-simplify-boolean-expr.ChainedConditionalReturn + value: '0' + - key: readability-simplify-subscript-expr.Types + value: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array' + - key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold + value: '3' + - key: readability-uppercase-literal-suffix.IgnoreMacros + value: '1' + - key: readability-uppercase-literal-suffix.NewSuffixes + value: '' +... + diff --git a/.gitignore b/.gitignore index 378eac2..455fad6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -build +build/ +.clangd/ +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt index ee94d97..b4810ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(microirc LANGUAGES C) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") add_compile_options(-Wall -Wextra -Werror -Wformat-overflow=2 -Wformat-security -Winit-self -Wstrict-overflow=2 -Wstringop-overflow=2 -Walloc-zero -Wduplicated-branches -Wduplicated-cond -Wtrampolines -Wfloat-equal -Wshadow -Wunsafe-loop-optimizations -Wparentheses -pedantic -fanalyzer -fstack-check) elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - add_compile_options(-Weverything -Wno-padded -pedantic) + add_compile_options(-Weverything -Wno-padded -Wno-disabled-macro-expansion -pedantic) endif() if (NOT CMAKE_BUILD_TYPE) diff --git a/include/functions.h b/include/functions.h index 8534a3a..6359dea 100644 --- a/include/functions.h +++ b/include/functions.h @@ -19,8 +19,8 @@ #include #include -#ifndef _UIRC_INCLUDED_FUNCT -#define _UIRC_INCLUDED_FUNCT +#ifndef UIRC_INCLUDED_FUNCT +#define UIRC_INCLUDED_FUNCT /* Tokenizers: They take a string in and point their struct element pointers at tokens and end tokens with '\0' */ extern signed int Tok_mesg(char* str, IRC_Message* out); extern signed int Tok_user(char* str, IRC_User* out, bool useorig); @@ -45,3 +45,4 @@ extern signed int Val_type_noblcm(char* str); /* Converters: They convert from one format to another */ extern signed int Ircmd_stoi(char* str); #endif + diff --git a/include/helpers.h b/include/helpers.h index f30077d..d6a5259 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -20,8 +20,8 @@ #include #ifdef UIRC_HELPERS -#ifndef _UIRC_INCLUDED_HELPERS -#define _UIRC_INCLUDED_HELPERS +#ifndef UIRC_INCLUDED_HELPERS +#define UIRC_INCLUDED_HELPERS extern IRC_Message* Assm_AUTO(int cmd, bool trailing, char** args, int req); @@ -88,3 +88,4 @@ extern void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg); extern size_t Assm_tag_timestamp(char* buf, size_t len, time_t time); #endif #endif + diff --git a/include/mappings.h b/include/mappings.h index 6cec2f2..7af7d96 100644 --- a/include/mappings.h +++ b/include/mappings.h @@ -15,8 +15,9 @@ * You should have received a copy of the GNU General Public License * along with uIRC. If not, see . */ -#ifndef _UIRC_INCLUDED_ENUMS -#define _UIRC_INCLUDED_ENUMS + +#ifndef UIRC_INCLUDED_ENUMS +#define UIRC_INCLUDED_ENUMS #define ERR_UIRC_GENERIC -1 #define ERR_UIRC_NULL_ARGS -2 @@ -281,3 +282,4 @@ enum commands { #endif #endif + diff --git a/include/types.h b/include/types.h index b8b048b..377b2b4 100644 --- a/include/types.h +++ b/include/types.h @@ -15,29 +15,17 @@ * You should have received a copy of the GNU General Public License * along with uIRC. If not, see . */ + #include -#ifndef _UIRC_INCLUDED_TYPES -#define _UIRC_INCLUDED_TYPES +#ifndef UIRC_INCLUDED_TYPES +#define UIRC_INCLUDED_TYPES #ifdef UIRC_IRCV3 typedef struct { char* value; /* if present, it isn't NULL and if it has no value, it is "" (aka '\0') */ bool clientbound; } IRC_Tag; -#endif -typedef struct { - char* nick; - char* user; - char* host; - char* orig; - char* real; -} IRC_User; -/* This is how a full user source would look like - * NOTE: 'real (Real name)' may only be used in special contexts other than communication. - * nick!user%orig@host */ - -#ifdef UIRC_IRCV3 typedef struct { /* See https://ircv3.net/registry#tags for more information */ IRC_Tag account; @@ -52,13 +40,27 @@ typedef struct { } IRC_Tags; #endif +typedef struct { + char* nick; + char* user; + char* host; + char* orig; + char* real; +} IRC_User; +/* This is how a full user source would look like + * NOTE: 'real (Real name)' may only be used in special contexts other than communication. + * nick!user%orig@host */ + +typedef unsigned short IRC_Command; + typedef struct { #ifdef UIRC_IRCV3 IRC_Tags tags; #endif IRC_User name; - signed short cmd; char* args[16]; /* 0-13 + trailing + NULL */ - bool trailing; /* Tells if the last argument is trailing */ + bool trailing; /* Tells if the last argument is trailing */ + IRC_Command cmd; } IRC_Message; #endif + diff --git a/include/uirc.h b/include/uirc.h index c7c7e19..9f97aa9 100644 --- a/include/uirc.h +++ b/include/uirc.h @@ -25,3 +25,4 @@ #define UIRC_VERSION 0.6 #endif + diff --git a/src/assemblers.c b/src/assemblers.c index 2fa6a74..6bea7f4 100644 --- a/src/assemblers.c +++ b/src/assemblers.c @@ -17,30 +17,29 @@ */ #include "assemblers.h" -signed int Assm_mesg(char* buf, IRC_Message* in, size_t len) +signed long Assm_mesg(char* buf, IRC_Message* in, size_t len) { if (buf == NULL || in == NULL) return ERR_UIRC_BUFFER_ERR; char* pos = buf; - unsigned int cnt; - signed int ret; + signed long cnt, ret; #ifdef UIRC_IRCV3 - if ((ret = Assm_tags(pos, &in->tags, len - (pos - buf))) < 0) + if ((ret = Assm_tags(pos, &in->tags, len - (unsigned long)(pos - buf))) < 0) return ret; else if (ret != 0) { pos += ret; - if (!safe_charcpy(&pos, ' ', len - (pos - buf))) + if (!safe_charcpy(&pos, ' ', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } #endif if (in->name.nick != NULL || in->name.host != NULL) { - if (!safe_charcpy(&pos, ':', len - (pos - buf))) + if (!safe_charcpy(&pos, ':', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; - if ((ret = Assm_user(pos, &in->name, len - (pos - buf), false)) <= 0) + if ((ret = Assm_user(pos, &in->name, len - (unsigned long)(pos - buf), false)) <= 0) return ret; else pos += ret; - if (!safe_charcpy(&pos, ' ', len - (pos - buf))) + if (!safe_charcpy(&pos, ' ', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } if (in->cmd < UIRC_FCMD || in->cmd > UIRC_LCMD) { @@ -49,24 +48,27 @@ signed int Assm_mesg(char* buf, IRC_Message* in, size_t len) else return ERR_UIRC_UNKNOWN_TOKEN; } else { - if (IRC_Cmds[in->cmd] != NULL && len - (pos - buf) > (cnt = strlen(IRC_Cmds[in->cmd])) + 1 && strcpy(pos, IRC_Cmds[in->cmd]) != NULL) - pos += cnt; - else - return ERR_UIRC_UNKNOWN_TOKEN; + if (IRC_Cmds[in->cmd] != NULL) { + size_t cmdlen = strlen(IRC_Cmds[in->cmd]); + if (len - (unsigned long)(pos - buf) > cmdlen && strcpy(pos, IRC_Cmds[in->cmd]) != NULL) + pos += cmdlen; + else + return ERR_UIRC_UNKNOWN_TOKEN; + } } - for (unsigned int i = 0; i < 15 && in->args[i] != NULL; i++) { - if (len - (pos - buf) > strlen(in->args[i]) + 2 && (cnt = snprintf(pos, len - (pos - buf), (in->args[i + 1] == NULL && in->trailing) ? " :%s" : " %s", in->args[i])) > 0) + for (unsigned int i = 0; in->args[i] != NULL; i++) { + if (len - (unsigned long)(pos - buf) > strlen(in->args[i]) + 2 && (cnt = snprintf(pos, len - (unsigned long)(pos - buf), (in->args[i + 1] == NULL && in->trailing) ? " :%s" : " %s", in->args[i])) > 0) pos += cnt; else return ERR_UIRC_BUFFER_ERR; } - if (!safe_strcpy(&pos, "\r\n", len - (pos - buf))) + if (!safe_strcpy(&pos, "\r\n", len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; return pos - buf; } #ifdef UIRC_IRCV3 -signed int Assm_tags(char* buf, IRC_Tags* in, size_t len) +signed long Assm_tags(char* buf, IRC_Tags* in, size_t len) { if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS; @@ -84,22 +86,22 @@ signed int Assm_tags(char* buf, IRC_Tags* in, size_t len) for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) { if ((*tagmps[i].assg).value != NULL) { if (pos == buf) { - if (!safe_charcpy(&pos, '@', len - (pos - buf))) + if (!safe_charcpy(&pos, '@', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } else { - if (!safe_charcpy(&pos, ';', len - (pos - buf))) + if (!safe_charcpy(&pos, ';', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } if ((*tagmps[i].assg).clientbound) { - if (!safe_charcpy(&pos, '+', len - (pos - buf))) + if (!safe_charcpy(&pos, '+', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } - if (!safe_strcpy(&pos, tagmps[i].name, len - (pos - buf))) + if (!safe_strcpy(&pos, tagmps[i].name, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (*(*tagmps[i].assg).value != '\0') { - if (!safe_charcpy(&pos, '=', len - (pos - buf))) + if (!safe_charcpy(&pos, '=', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; - if (!safe_strcpy(&pos, (*tagmps[i].assg).value, len - (pos - buf))) + if (!safe_strcpy(&pos, (*tagmps[i].assg).value, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } } @@ -108,36 +110,37 @@ signed int Assm_tags(char* buf, IRC_Tags* in, size_t len) } #endif -signed int Assm_user(char* buf, IRC_User* in, size_t len, bool useorig) +signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig) { if (buf == NULL || in == NULL) return ERR_UIRC_NULL_ARGS; char* pos = buf; if (in->nick == NULL && in->host != NULL) { - if (!safe_strcpy(&pos, in->host, len - (pos - buf))) + if (!safe_strcpy(&pos, in->host, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } else if (in->nick != NULL) { - if (!safe_strcpy(&pos, in->nick, len - (pos - buf))) + if (!safe_strcpy(&pos, in->nick, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; if (in->user != NULL) { - if (!safe_charcpy(&pos, '!', len - (pos - buf))) + if (!safe_charcpy(&pos, '!', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; - if (!safe_strcpy(&pos, in->user, len - (pos - buf))) + if (!safe_strcpy(&pos, in->user, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } if (useorig && in->orig != NULL) { - if (!safe_charcpy(&pos, '%', len - (pos - buf))) + if (!safe_charcpy(&pos, '%', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; - if (!safe_strcpy(&pos, in->orig, len - (pos - buf))) + if (!safe_strcpy(&pos, in->orig, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } if (in->host != NULL) { - if (!safe_charcpy(&pos, '@', len - (pos - buf))) + if (!safe_charcpy(&pos, '@', len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; - if (!safe_strcpy(&pos, in->host, len - (pos - buf))) + if (!safe_strcpy(&pos, in->host, len - (unsigned long)(pos - buf))) return ERR_UIRC_BUFFER_ERR; } } else return ERR_UIRC_NULL_ARGS; return pos - buf; } + diff --git a/src/assemblers.h b/src/assemblers.h index d2dc3bd..9ad5707 100644 --- a/src/assemblers.h +++ b/src/assemblers.h @@ -15,6 +15,7 @@ * You should have received a copy of the GNU General Public License * along with uIRC. If not, see . */ + #include "../include/types.h" #include "../include/mappings.h" #include "misc.h" @@ -22,13 +23,14 @@ #include #include -#ifndef _UIRC_INCLUDED_ASSM -#define _UIRC_INCLUDED_ASSM -signed int Assm_mesg(char* buf, IRC_Message* in, size_t len); +#ifndef UIRC_INCLUDED_ASSM +#define UIRC_INCLUDED_ASSM +signed long Assm_mesg(char* buf, IRC_Message* in, size_t len); #ifdef UIRC_IRCV3 -signed int Assm_tags(char* buf, IRC_Tags* in, size_t len); +signed long Assm_tags(char* buf, IRC_Tags* in, size_t len); #endif -signed int Assm_user(char* buf, IRC_User* in, size_t len, bool useorig); +signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig); #endif + diff --git a/src/helpers.c b/src/helpers.c index 3e99de6..4446f61 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -24,7 +24,7 @@ void clear_assm(void) { memset((void*)&imassm_mesg, '\0', sizeof(IRC_Message)); } -IRC_Message* Assm_AUTO(int cmd, bool trailing, char** args, int req) +IRC_Message* Assm_AUTO(IRC_Command cmd, bool trailing, char** args, int req) { clear_assm(); int i; @@ -131,9 +131,8 @@ IRC_Message* Assm_cmd_USERHOST(char* users[]) if (users[0] == NULL) return NULL; clear_assm(); - for (unsigned int i = 0; i < 5 && users[i] != NULL; i++) { + for (unsigned int i = 0; i < 5 && users[i] != NULL; i++) imassm_mesg.args[i] = users[i]; - } imassm_mesg.cmd = USERHOST; return &imassm_mesg; } @@ -164,3 +163,4 @@ void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg) *optarg = (mesg->args[1] != NULL) ? mesg->args[0] : NULL; *reqarg = (mesg->args[1] != NULL) ? mesg->args[1] : mesg->args[0]; } + diff --git a/src/helpers.h b/src/helpers.h index 1eab37d..4fc2667 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -24,12 +24,12 @@ #include #include -#ifndef _UIRC_INCLUDED_ASSM -#define _UIRC_INCLUDED_ASSM -char* RESERVED; +#ifndef UIRC_INCLUDED_ASSM +#define UIRC_INCLUDED_ASSM +extern char* RESERVED; void clear_assm(void); -IRC_Message* Assm_AUTO(int cmd, bool trailing, char** args, int req); +IRC_Message* Assm_AUTO(IRC_Command cmd, bool trailing, char** args, int req); #define Assm_cmd_REHASH() Assm_AUTO(REHASH, false, (char*[]){NULL}, 0) #define Assm_cmd_DIE() Assm_AUTO(DIE, false, (char*[]){NULL}, 0) @@ -91,3 +91,4 @@ IRC_Message* Assm_cmd_ISON(char* users[]); void Tok_cmd_PING(IRC_Message* mesg, char** source, char** target); void Tok_FArgOpt(IRC_Message* mesg, char** optarg, char** reqarg); #endif + diff --git a/src/misc.c b/src/misc.c index c35a91e..86ff1dd 100644 --- a/src/misc.c +++ b/src/misc.c @@ -83,18 +83,18 @@ const char* const IRC_Cmds[] = { #endif }; -signed int Ircmd_stoi(char* str) +signed short Ircmd_stoi(char* str) { if (str == NULL) return ERR_UIRC_NULL_ARGS; - for (unsigned short i = UIRC_FCMD; i <= UIRC_LCMD; i++) { + for (signed short i = UIRC_FCMD; i <= (signed short) UIRC_LCMD; i++) { if (IRC_Cmds[i] != NULL && strcmp(IRC_Cmds[i], str) == 0) return i; } return ERR_UIRC_UNKNOWN_TOKEN; } -int safe_strcpy(char** dest, const char* src, size_t lef) +size_t safe_strcpy(char** dest, const char* src, size_t lef) { size_t cnt; if (lef > (cnt = strlen(src)) + 1) { @@ -105,7 +105,7 @@ int safe_strcpy(char** dest, const char* src, size_t lef) return 0; } -int safe_charcpy(char** dest, const char c, size_t lef) +bool safe_charcpy(char** dest, const char c, size_t lef) { if (lef > 1) { *(*dest)++ = c; @@ -139,3 +139,4 @@ char* strtok_mr(char** addr, const char* tokens) } while (*(*addr)++); return save; } + diff --git a/src/misc.h b/src/misc.h index e1fb804..12987a0 100644 --- a/src/misc.h +++ b/src/misc.h @@ -15,13 +15,14 @@ * You should have received a copy of the GNU General Public License * along with uIRC. If not, see . */ + #include "../include/mappings.h" #include "../include/types.h" #include #include -#ifndef _UIRC_INCLUDED_MISC -#define _UIRC_INCLUDED_MISC +#ifndef UIRC_INCLUDED_MISC +#define UIRC_INCLUDED_MISC #ifdef UIRC_IRCV3 struct tagmapping { @@ -30,9 +31,10 @@ struct tagmapping { }; #endif -signed int Ircmd_stoi(char* str); -int safe_strcpy(char** dest, const char* src, size_t lef); -int safe_charcpy(char** dest, const char c, size_t lef); +signed short Ircmd_stoi(char* str); +size_t safe_strcpy(char** dest, const char* src, size_t lef); +bool safe_charcpy(char** dest, char c, size_t lef); void skip_spaces(char** addr); char* strtok_mr(char** addr, const char* tokens); #endif + diff --git a/src/taghelpers.c b/src/taghelpers.c index 410afcc..7a14b1d 100644 --- a/src/taghelpers.c +++ b/src/taghelpers.c @@ -22,3 +22,4 @@ size_t Assm_tag_timestamp(char* buf, size_t len, time_t time) { return strftime(buf, len, "%Y-%m-%dT%H:%M:%S.000Z", gmtime(&time)); } + diff --git a/src/taghelpers.h b/src/taghelpers.h index d33ac9e..7f86b9d 100644 --- a/src/taghelpers.h +++ b/src/taghelpers.h @@ -16,15 +16,14 @@ * along with uIRC. If not, see . */ -#define _XOPEN_SOURCE #include #include #include #include #include -#ifndef _UIRC_INCLUDED_TAGASSM -#define _UIRC_INCLUDED_TAGASSM +#ifndef UIRC_INCLUDED_TAGASSM +#define UIRC_INCLUDED_TAGASSM size_t Assm_tag_timestamp(char* buf, size_t len, time_t time); -int Tok_tag_timestamp(char* timestamp, time_t* time); #endif + diff --git a/src/tokenizers.c b/src/tokenizers.c index ec1c936..01234fd 100644 --- a/src/tokenizers.c +++ b/src/tokenizers.c @@ -46,15 +46,20 @@ signed int Tok_mesg(char* str, IRC_Message* out) skip_spaces(&progr); if ((command = strtok_mr(&progr, " ")) != NULL) { - if (!(out->cmd = (isalpha(*command)) ? Ircmd_stoi(command) : atoi(command))) - return ERR_UIRC_UNKNOWN_TOKEN; - } else { + signed short temp; + if (isalpha(*command)) { + if ((temp = Ircmd_stoi(command)) < UIRC_FCMD || temp > UIRC_LCMD) + return ERR_UIRC_UNKNOWN_TOKEN; + out->cmd = (IRC_Command)temp; + } else { + out->cmd = (IRC_Command)atoi(command); + } + } else return ERR_UIRC_INVALID_FORMAT; - } skip_spaces(&progr); - int i; + short i; for (i = 0; i < 15 && *progr;) { if (i == 14 || *progr == ':') { out->args[i++] = (*progr == ':') ? progr + 1 : progr; @@ -134,3 +139,4 @@ signed int Tok_user(char* str, IRC_User* out, bool useorig) } return 1; } + diff --git a/src/tokenizers.h b/src/tokenizers.h index 7d5a584..794d1cb 100644 --- a/src/tokenizers.h +++ b/src/tokenizers.h @@ -15,6 +15,7 @@ * You should have received a copy of the GNU General Public License * along with uIRC. If not, see . */ + #include "../include/types.h" #include "../include/mappings.h" #include "misc.h" @@ -23,8 +24,8 @@ #include #include -#ifndef _UIRC_INCLUDED_TKNIZ -#define _UIRC_INCLUDED_TKNIZ +#ifndef UIRC_INCLUDED_TKNIZ +#define UIRC_INCLUDED_TKNIZ signed int Tok_mesg(char* str, IRC_Message* out); #ifdef UIRC_IRCV3 @@ -33,3 +34,4 @@ signed int Tok_tags(char* str, IRC_Tags* out); signed int Tok_user(char* str, IRC_User* out, bool useorig); #endif + diff --git a/src/validators.c b/src/validators.c index d0d4846..bd43f28 100644 --- a/src/validators.c +++ b/src/validators.c @@ -22,7 +22,7 @@ signed int Val_mesg(IRC_Message* mesg) { if (mesg == NULL) return ERR_UIRC_NULL_ARGS; - for (unsigned int i = 0; i < 15 && mesg->args[i] != NULL; i++) { + for (unsigned int i = 0; mesg->args[i] != NULL; i++) { if (Val_type_nocrlf(mesg->args[i]) != 1) return ERR_UIRC_VAL_FAILED; if (!(mesg->args[i + 1] == NULL && mesg->trailing)) { @@ -70,7 +70,7 @@ signed int Val_channame(char* chan) { if (chan == NULL) return ERR_UIRC_NULL_ARGS; - if (*chan != '#' || *chan != '+' || *chan != '!' || *chan != '&') + if (*chan != '#' && *chan != '+' && *chan != '!' && *chan != '&') return 0; char* clps = ++chan; if ((clps = strchr(chan, ':')) != NULL) { @@ -86,3 +86,4 @@ signed int Val_channame(char* chan) return 0; return 1; } + diff --git a/src/validators.h b/src/validators.h index 77ee137..06b2b37 100644 --- a/src/validators.h +++ b/src/validators.h @@ -15,12 +15,18 @@ * You should have received a copy of the GNU General Public License * along with uIRC. If not, see . */ + #include "../include/types.h" #include "../include/mappings.h" #include #include + +#ifndef UIRC_INCLUDED_VALIDATORS +#define UIRC_INCLUDED_VALIDATORS signed int Val_mesg(IRC_Message* mesg); signed int Val_type_nocrlf(char* str); signed int Val_type_nospcl(char* str); signed int Val_type_noblcm(char* str); signed int Val_channame(char* chan); +#endif + diff --git a/tests/tokenizer.c b/tests/tokenizer.c index 77b209f..b678c2a 100644 --- a/tests/tokenizer.c +++ b/tests/tokenizer.c @@ -3,18 +3,46 @@ #include #include +#define nickname "nick" +#define username "user" +#define hostname "host" +#define arg2 "Finished!" + int main(void) { - char mesg[513] = + char mesg[2][513] = { #ifdef UIRC_IRCV3 - "@+msgid=1s32;time;+reply;account=x" + "@+msgid=1s32;time;+reply;account=x " #endif - ":nick!user@host QUIT arg1 :Finished!"; - IRC_Message parseout; + ":" nickname "!" username "@" hostname " QUIT arg1 :" arg2, + "001 hell :sup cj" + }; + IRC_Message parseout = {0}; int res = 0; - if ((res = Tok_mesg(mesg, &parseout)) <= 0) { + if ((res = Tok_mesg(mesg[0], &parseout)) <= 0) { printf("String could not be tokenized. %i\n", res); return EXIT_FAILURE; } + if (parseout.args[1] == NULL || strcmp(parseout.args[1], arg2)) { + printf("Unexpected result. Got %s instead of %s\n", parseout.args[1], arg2); + return EXIT_FAILURE; + } + if (parseout.name.user == NULL || strcmp(parseout.name.user, username)) { + printf("Unexpected result. Got %s instead of %s\n", parseout.name.user, username); + return EXIT_FAILURE; + } + if (parseout.cmd != QUIT) { + printf("Unexpected command result. Got %i instead of %i\n", parseout.cmd, QUIT); + return EXIT_FAILURE; + } + if ((res = Tok_mesg(mesg[1], &parseout)) <= 0) { + printf("String could not be tokenized. %i\n", res); + return EXIT_FAILURE; + } + if (parseout.cmd != 1) { + printf("Unexpected command result. Got %i instead of %i\n", parseout.cmd, 1); + return EXIT_FAILURE; + } return EXIT_SUCCESS; } +