Fix reseved identifiers, fix problems about signedness and casting and add a few more test cases

This commit is contained in:
Alex D. 2020-09-26 23:22:05 +02:00
parent 8b9a527ace
commit 6cce8c57cc
Signed by: caskd
GPG Key ID: F92BA85F61F4C173
21 changed files with 340 additions and 95 deletions

184
.clang-tidy Normal file
View File

@ -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: ''
...

4
.gitignore vendored
View File

@ -1 +1,3 @@
build
build/
.clangd/
compile_commands.json

View File

@ -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)

View File

@ -19,8 +19,8 @@
#include <stdbool.h>
#include <sys/types.h>
#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

View File

@ -20,8 +20,8 @@
#include <time.h>
#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

View File

@ -15,8 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#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

View File

@ -15,29 +15,17 @@
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#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

View File

@ -25,3 +25,4 @@
#define UIRC_VERSION 0.6
#endif

View File

@ -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;
}

View File

@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#include "../include/types.h"
#include "../include/mappings.h"
#include "misc.h"
@ -22,13 +23,14 @@
#include <string.h>
#include <time.h>
#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

View File

@ -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];
}

View File

@ -24,12 +24,12 @@
#include <string.h>
#include <time.h>
#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

View File

@ -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;
}

View File

@ -15,13 +15,14 @@
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#include "../include/mappings.h"
#include "../include/types.h"
#include <stdio.h>
#include <string.h>
#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

View File

@ -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));
}

View File

@ -16,15 +16,14 @@
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#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

View File

@ -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;
}

View File

@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#include "../include/types.h"
#include "../include/mappings.h"
#include "misc.h"
@ -23,8 +24,8 @@
#include <string.h>
#include <ctype.h>
#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

View File

@ -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;
}

View File

@ -15,12 +15,18 @@
* You should have received a copy of the GNU General Public License
* along with uIRC. If not, see <https://www.gnu.org/licenses/>.
*/
#include "../include/types.h"
#include "../include/mappings.h"
#include <stdio.h>
#include <string.h>
#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

View File

@ -3,18 +3,46 @@
#include <stdlib.h>
#include <string.h>
#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;
}