diff --git a/centrallix-lib/include/mtlexer.h b/centrallix-lib/include/mtlexer.h index bd6ee2f3d..6f8fc7400 100644 --- a/centrallix-lib/include/mtlexer.h +++ b/centrallix-lib/include/mtlexer.h @@ -55,6 +55,8 @@ typedef struct _LX char** ReservedWords; /* reserved words */ int LineNumber; int (*ReadFn)(); + int (*ValidateFn)(char *); /* pointer to a validate function */ + int (*CharFit)(char, int, int); /* pointer to see if a multibyte char will be split */ void* ReadArg; } LxSession, *pLxSession; @@ -143,6 +145,8 @@ int mlxSetOffset(pLxSession this, unsigned long new_offset); #define MLX_F_SSTRING (1<<22) /* Differentiate "" and '' strings */ #define MLX_F_PROCLINE (1<<23) /* (int) Line has been processed. */ #define MLX_F_ALLOWNUL (1<<24) /* Allow nul (\0) bytes in input. */ +#define MLX_F_ENFORCEUTF8 (1<<25) /* validate all strings as UTF-8. Incompatable with MLX_F_ENFORCEASCII */ +#define MLX_F_ENFORCEASCII (1<<26) /* validate all strings as ASCII. Incompatable with MLX_F_ENFORCEUTF8 */ #define MLX_F_PUBLIC (MLX_F_ICASE | MLX_F_POUNDCOMM | MLX_F_CCOMM | MLX_F_CPPCOMM | MLX_F_SEMICOMM | MLX_F_DASHCOMM | MLX_F_EOL | MLX_F_EOF | MLX_F_IFSONLY | MLX_F_DASHKW | MLX_F_NODISCARD | MLX_F_FILENAMES | MLX_F_DBLBRACE | MLX_F_LINEONLY | MLX_F_SYMBOLMODE | MLX_F_TOKCOMM | MLX_F_NOUNESC | MLX_F_SSTRING | MLX_F_ALLOWNUL) #define MLX_F_PRIVATE (MLX_F_INSTRING | MLX_F_NOFILE | MLX_F_FOUNDEOL | MLX_F_INCOMM | MLX_F_PROCLINE) diff --git a/centrallix-lib/include/qprintf.h b/centrallix-lib/include/qprintf.h index d638ef684..298a8e6cc 100644 --- a/centrallix-lib/include/qprintf.h +++ b/centrallix-lib/include/qprintf.h @@ -37,9 +37,13 @@ typedef int (*qpf_grow_fn_t)(char**, size_t*, size_t, void*, size_t); typedef struct _QPS { unsigned int Errors; /* QPF_ERR_T_xxx */ + unsigned int Flags; } QPSession, *pQPSession; + +#define QPF_F_ENFORCE_UTF8 1 /* use UTF-8 validation */ + #define QPF_ERR_T_NOTIMPL 1 /* unimplemented feature */ #define QPF_ERR_T_BUFOVERFLOW 2 /* dest buffer too small */ #define QPF_ERR_T_INSOVERFLOW 4 /* NLEN or *LEN restriction occurred */ @@ -54,11 +58,15 @@ typedef struct _QPS #define QPF_ERR_T_BADFILE 2048 /* Bad filename for &FILE filter */ #define QPF_ERR_T_BADPATH 4096 /* Bad pathname for &PATH filter */ #define QPF_ERR_T_BADCHAR 8192 /* Bad character for filter (e.g. an octothorpe for &DB64) */ +#define QPF_ERR_T_TRUNC 16384 /* To avoid splitting a utf-8 char, not all of the space was used */ #define QPERR(x) (s->Errors |= (x)) + /*** QPrintf methods ***/ +void qpfInitializeDefaultFlags(int isUTF8); pQPSession qpfOpenSession(); +pQPSession qpfOpenSessionFlags(unsigned int flags); int qpfCloseSession(pQPSession s); int qpfClearErrors(pQPSession s); unsigned int qpfErrors(pQPSession s); diff --git a/centrallix-lib/include/util.h b/centrallix-lib/include/util.h index df4ba0d58..60cdc348d 100644 --- a/centrallix-lib/include/util.h +++ b/centrallix-lib/include/util.h @@ -32,3 +32,42 @@ extern "C" { #endif /* UTILITY_H */ +#define UTIL_VALID_CHAR (size_t)-1 /** for use with verifyUTF8 **/ +#define UTIL_INVALID_CHAR (size_t)-2 +#define UTIL_INVALID_ARGUMENT (size_t)-3 +/** states for validate **/ +#define UTIL_STATE_START 0 +#define UTIL_STATE_3_BYTE 1 /** 3 bytes left; was 4 total **/ +#define UTIL_STATE_2_BYTE 2 /** 2 bytes left; a leats 3 total **/ +#define UTIL_STATE_1_BYTE 3 /** 1 byte left; was at least 2 total **/ +#define UTIL_STATE_ERROR 4 +#define UTIL_STATE_E_SURROGATE 5 +#define UTIL_STATE_E_OVERLONG 6 /** starts with E0, check for overlong **/ +#define UTIL_STATE_F_OVERLONG 7 /** starts with F0, check for overlong **/ +#define UTIL_STATE_TOO_LARGE 8 /** starts with F4, check for too long **/ + +/** \brief This function ensures that a string contains valid UTF-8. + \param string The string to verify. + \return The index of the first byte of the first invald char, or a + code if not applicable */ +int verifyUTF8(char* str); + +/** \brief This function ensures that all of the bytes of a string are + valid ASCII. + \param string The string to verify. + \return returns index of the first invalid string, or a code if not + applicable */ +int verifyASCII(char * str); + +/** \brief This function ensures that all of the bytes of a string are + valid ASCII. Does not require a NULL terminator. + \param str The string to verify. + \param len the length of the suplied string + \return returns index of the first invalid string, or a code if not + applicable */ +int nVerifyUTF8(char* str, int len); + +/** \brief Computes the number of bytes in a utf-8 char based on the first byte. + * \param byte the character to be checked + * \return the number of bytes in the character, or -1 on error. */ + int numBytesInChar(char byte); \ No newline at end of file diff --git a/centrallix-lib/include/xstring.h b/centrallix-lib/include/xstring.h index 683b0e05d..6e0a79932 100644 --- a/centrallix-lib/include/xstring.h +++ b/centrallix-lib/include/xstring.h @@ -26,7 +26,7 @@ /* realloc'ing string data structure. */ /************************************************************************/ - +#include #include #define XS_BLK_SIZ 256 @@ -61,10 +61,15 @@ int xsRTrim(pXString this); int xsLTrim(pXString this); int xsTrim(pXString this); int xsFind(pXString this,char* find,int findlen, int offset); +int xsFindWithCharOffset(pXString this, char* find, int findlen, int offset); int xsFindRev(pXString this,char* find,int findlen, int offset); +int xsFindRevWithCharOffset(pXString this, char* find, int findlen, int offset); int xsSubst(pXString this, int offset, int len, char* rep, int replen); +int xsSubstWithCharOffset(pXString this, int offset, int len, char* rep, int replen); int xsReplace(pXString this, char* find, int findlen, int offset, char* rep, int replen); +int xsReplaceWithCharOffset(pXString this, char* find, int findlen, int offset, char* rep, int replen); int xsInsertAfter(pXString this, char* ins, int inslen, int offset); +int xsInsertAfterWithCharOffset(pXString this, char* ins, int inslen, int offset); int xsGenPrintf(int (*write_fn)(), void* write_arg, char** buf, int* buf_size, const char* fmt, ...); int xsGenPrintf_va(int (*write_fn)(), void* write_arg, char** buf, int* buf_size, const char* fmt, va_list va); int xsQPrintf(pXString this, char* fmt, ...); @@ -73,6 +78,9 @@ int xsConcatQPrintf(pXString this, char* fmt, ...); pXString xsNew(); void xsFree(pXString this); +/** Needed utiliy function **/ +size_t chrCharLength(char* string); + #define XS_U_SEEK 2 #endif /* _XSTRING_H */ diff --git a/centrallix-lib/src/mtlexer.c b/centrallix-lib/src/mtlexer.c index e92ea49ff..86bb29355 100644 --- a/centrallix-lib/src/mtlexer.c +++ b/centrallix-lib/src/mtlexer.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "newmalloc.h" #include "mtask.h" #include "mtlexer.h" @@ -43,6 +44,7 @@ int mlxReadLine(pLxSession s, char* buf, int maxlen); int mlxSkipChars(pLxSession s, int n_chars); int mlxPeekChar(pLxSession s, int offset); +int mlx_internal_willCharFitUTF8(char c, int ind, int max); /*** mlxOpenSession - start a new lexer session on a given file @@ -53,6 +55,9 @@ mlxOpenSession(pFile fd, int flags) { pLxSession this; + /** ensure flags are valid **/ + if((MLX_F_ENFORCEUTF8 & flags) && (MLX_F_ENFORCEASCII & flags)) return NULL; + /** Allocate the session **/ this = (pLxSession)nmMalloc(sizeof(LxSession)); if (!this) return NULL; @@ -66,6 +71,22 @@ mlxOpenSession(pFile fd, int flags) this->InpPtr = this->InpBuf; this->ReservedWords = NULL; this->Flags = flags & MLX_F_PUBLIC; + /* determine which validate to set */ + if(MLX_F_ENFORCEUTF8 & flags) + { + this->ValidateFn = verifyUTF8; + this->CharFit = mlx_internal_willCharFitUTF8; + } + else if(MLX_F_ENFORCEASCII & flags) + { + this->ValidateFn = verifyASCII; + this->CharFit = NULL; + } + else + { + this->ValidateFn = NULL; + this->CharFit = NULL; + } /** Preload the buffer with the first line **/ this->Buffer[0] = 0; @@ -89,6 +110,9 @@ mlxStringSession(char* str, int flags) { pLxSession this; + /** ensure flags are valid **/ + if((MLX_F_ENFORCEUTF8 & flags) && (MLX_F_ENFORCEASCII & flags)) return NULL; + /** Allocate the session **/ this = (pLxSession)nmMalloc(sizeof(LxSession)); if (!this) return NULL; @@ -105,6 +129,23 @@ mlxStringSession(char* str, int flags) this->Flags = (flags & MLX_F_PUBLIC) & ~MLX_F_NODISCARD; this->Flags |= MLX_F_NOFILE; this->Magic = MGK_LXSESSION; + /* determine which validate to set */ + char * locale = setlocale(LC_CTYPE, NULL); + if(MLX_F_ENFORCEUTF8 & flags) + { + this->ValidateFn = verifyUTF8; + this->CharFit = mlx_internal_willCharFitUTF8; + } + else if(MLX_F_ENFORCEASCII & flags) + { + this->ValidateFn = verifyASCII; + this->CharFit = NULL; + } + else + { + this->ValidateFn = NULL; + this->CharFit = NULL; + } /** Read the first line. **/ this->BufPtr = this->Buffer; @@ -125,6 +166,9 @@ mlxGenericSession(void* src, int (*read_fn)(), int flags) { pLxSession this; + /** ensure flags are valid **/ + if((MLX_F_ENFORCEUTF8 & flags) && (MLX_F_ENFORCEASCII & flags)) return NULL; + /** Allocate the session **/ this = (pLxSession)nmMalloc(sizeof(LxSession)); if (!this) return NULL; @@ -138,6 +182,23 @@ mlxGenericSession(void* src, int (*read_fn)(), int flags) this->InpPtr = this->InpBuf; this->ReservedWords = NULL; this->Flags = (flags & MLX_F_PUBLIC) & ~MLX_F_NODISCARD; + /* determine which validate to set */ + char * locale = setlocale(LC_CTYPE, NULL); + if(MLX_F_ENFORCEUTF8 & flags) + { + this->ValidateFn = verifyUTF8; + this->CharFit = mlx_internal_willCharFitUTF8; + } + else if(MLX_F_ENFORCEASCII & flags) + { + this->ValidateFn = verifyASCII; + this->CharFit = NULL; + } + else + { + this->ValidateFn = NULL; + this->CharFit = NULL; + } /** Preload the buffer with the first line **/ this->Buffer[0] = 0; @@ -282,7 +343,6 @@ int mlxPeekChar(pLxSession s, int offset) { int v, ch; - v = mlx_internal_CheckBuffer(s, offset); if (__builtin_expect(v < 0, 0)) return MLX_ERROR; if (__builtin_expect(v <= offset, 0)) return MLX_EOF; @@ -382,6 +442,12 @@ mlx_internal_Copy(pLxSession this, char* buf, int bufsize, int* found_end) *found_end = 0; while(ch >= 0 && len < bufsize-1) { + if(this->CharFit != NULL && !this->CharFit(ch, len, bufsize-1)) + { + *found_end = 0; + break; + } + buf[len++] = ch; if (ch == '\n') { @@ -399,7 +465,7 @@ mlx_internal_Copy(pLxSession this, char* buf, int bufsize, int* found_end) *found_end = 1; while(ch >= 0 && ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') { - if (len >= bufsize-1) + if (len >= bufsize-1 || (this->CharFit && !this->CharFit(ch, len, bufsize-1))) { *found_end = 0; break; @@ -416,7 +482,7 @@ mlx_internal_Copy(pLxSession this, char* buf, int bufsize, int* found_end) *found_end = 1; while((ch = mlxPeekChar(this,0)) >= 0 && ch != this->Delimiter) { - if (len >= bufsize-1) + if (len >= bufsize-1 || (this->CharFit && !this->CharFit(ch, len, bufsize-1))) { *found_end = 0; break; @@ -461,7 +527,7 @@ mlx_internal_Copy(pLxSession this, char* buf, int bufsize, int* found_end) *found_end = 1; while(ch >= 0 && ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n' && ch != ':') { - if (len >= bufsize-1) + if (len >= bufsize-1 || (this->CharFit && !this->CharFit(ch, len, bufsize-1))) { *found_end = 0; break; @@ -552,6 +618,7 @@ mlxNextToken(pLxSession this) { while((ch = mlxNextChar(this)) >= 0 && ch != '\n') ; this->Flags &= ~MLX_F_INSTRING; + this->Flags &= ~MLX_F_PROCLINE; /* treat as new line */ } else if ((this->Flags & MLX_F_INSTRING) && ((this->Flags & MLX_F_IFSONLY) || this->Delimiter == ' ')) { @@ -769,7 +836,7 @@ mlxNextToken(pLxSession this) this->TokString[this->TokStrCnt] = '\0'; break; } - else if (ch >= 0 && ch <= 255 && (ptr = strchr(s_tokens, (char)((unsigned char)ch))) != NULL && *ptr) + else if (ch >= 0 && ch <= 255 && (ptr = strchr(s_tokens, (char)((unsigned char)ch))) != NULL) { /** single-char token that isn't dependent on what the next character is **/ this->TokString[0] = ch; @@ -834,7 +901,7 @@ mlxNextToken(pLxSession this) this->TokString[this->TokStrCnt] = '\0'; break; } - else if (ch == '-' && !strchr("0123456789.",mlxPeekChar(this,1))) + else if (ch == '-' && !strchr("0123456789.",mlxPeekChar(this,1))) { /** only a MLX_TOK_PLUS if the next char is not a digit or period (that would make it part of a number) **/ this->TokString[0] = ch; @@ -843,7 +910,7 @@ mlxNextToken(pLxSession this) mlxSkipChars(this,1); break; } - else if (strchr("0123456789+-.",ch)) + else if (strchr("0123456789+-.",ch)) { got_dot = (ch == '.')?1:0; this->TokType = MLX_TOK_INTEGER; @@ -851,7 +918,7 @@ mlxNextToken(pLxSession this) this->TokString[0] = ch; mlxSkipChars(this,1); found_end=1; - while((ch = mlxPeekChar(this,0)) >= 0 && (strchr("0123456789xabcdefABCDEF",ch) || (!got_dot && ch == '.'))) + while((ch = mlxPeekChar(this,0)) >= 0 && (strchr("0123456789xabcdefABCDEF",ch) && ch != '\0' || (!got_dot && ch == '.'))) { if (this->TokStrCnt >= 255) { @@ -946,6 +1013,17 @@ mlxNextToken(pLxSession this) } } + /** check string is valid, if applicable **/ + if(this->ValidateFn != NULL && (this->TokType == MLX_TOK_SSTRING || + this->TokType == MLX_TOK_STRING || this->TokType == MLX_TOK_FILENAME)) + { + if(this->ValidateFn(this->TokString) != UTIL_VALID_CHAR) + { + mssError(1,"MLX","String token contained invalid characters"); + this->TokType = MLX_TOK_ERROR; + } + } + return this->TokType; } @@ -960,7 +1038,7 @@ char* mlxStringVal(pLxSession this, int* alloc) { char* ptr; - int len,cnt,ccnt; + int len,cnt,ccnt,ind; char* nptr; ASSERTMAGIC(this,MGK_LXSESSION); @@ -1027,6 +1105,17 @@ mlxStringVal(pLxSession this, int* alloc) ptr = this->TokString; } + /** validate again; could have more copied from buffer **/ + if(this->ValidateFn != NULL && (ind = this->ValidateFn(ptr)) != UTIL_VALID_CHAR + || this->TokType == MLX_TOK_ERROR) /** mlxCopyToken would set TokType **/ + { + mssError(1,"MLX","String token contained invalid characters"); + this->TokType = MLX_TOK_ERROR; + *alloc = 0; + nmSysFree(ptr); + return NULL; + } + return ptr; } @@ -1077,6 +1166,7 @@ mlxCopyToken(pLxSession this, char* buffer, int maxlen) int cnt; int len; int found_end; + int ind; ASSERTMAGIC(this,MGK_LXSESSION); @@ -1112,6 +1202,15 @@ mlxCopyToken(pLxSession this, char* buffer, int maxlen) mssError(1,"MLX","Unterminated string value"); this->TokType = MLX_TOK_ERROR; } + + /** validate buffer; could have copied more from input, thereby avoiding next token's check **/ + if(this->ValidateFn && (ind = this->ValidateFn(buffer)) != UTIL_VALID_CHAR) + { + buffer[ind] = '\0'; /** end string just before bad character **/ + len = ind; + mssError(1,"MLX","Invalid characters in string"); + this->TokType = MLX_TOK_ERROR; + } return len; } @@ -1177,7 +1276,7 @@ mlxSetReservedWords(pLxSession this, char** res_words) { ASSERTMAGIC(this,MGK_LXSESSION); - + /** Set the words **/ this->ReservedWords = res_words; @@ -1306,3 +1405,21 @@ mlxSetOffset(pLxSession this, unsigned long new_offset) return 0; } + +/*** mlx_internal_willCharFitUTF8() - Given the current character, index (next open slot), + *** and maximum length, returns 1 if all bytes of a UTF-8 char will fit in a buffer, and + *** returns 0 in all other cases. Index refers to the next slot to be filled + *** + *** NOTE: a 0 is returned even on an error; getting a char which is NOT a utf-8 + *** header indicates the decision was made in a previous step. + ***/ +int +mlx_internal_willCharFitUTF8(char c, int ind, int len) + { + int bytes = numBytesInChar(c); + if(bytes < 0 ) bytes = 1; /* treat as a single byte */ + + if(ind >= len) return 0; /* buf is full */ + else if(ind > len - bytes) return 0; /* cuts off char*/ + else return 1; /* fits */ + } \ No newline at end of file diff --git a/centrallix-lib/src/mtsession.c b/centrallix-lib/src/mtsession.c index ca517d71f..be645cee9 100644 --- a/centrallix-lib/src/mtsession.c +++ b/centrallix-lib/src/mtsession.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "mtask.h" #include "mtlexer.h" #include "newmalloc.h" @@ -263,6 +264,8 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) int found_user; gid_t grps[16]; int n_grps; + int mlxFlags; + char * locale; /** Allocate a new session structure. **/ s = (pMtSession)nmMalloc(sizeof(MtSession)); @@ -332,7 +335,11 @@ mssAuthenticate(char* username, char* password, int bypass_crypt) nmFree(s,sizeof(MtSession)); return -1; } - altpass_lxs = mlxOpenSession(altpass_fd, MLX_F_LINEONLY | MLX_F_EOF); + mlxFlags = MLX_F_LINEONLY | MLX_F_EOF; + locale = setlocale(LC_CTYPE, NULL); + if(strstr(locale, "UTF-8") || strstr(locale, "UTF8") || strstr(locale, "utf-8") || strstr(locale, "utf8")) + mlxFlags |= MLX_F_ENFORCEUTF8; + altpass_lxs = mlxOpenSession(altpass_fd, mlxFlags); /** Scan it for the user name **/ found_user = 0; diff --git a/centrallix-lib/src/qprintf.c b/centrallix-lib/src/qprintf.c index 25964ba23..d67e9db5c 100644 --- a/centrallix-lib/src/qprintf.c +++ b/centrallix-lib/src/qprintf.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "qprintf.h" #include "mtask.h" #include "newmalloc.h" @@ -182,11 +183,13 @@ typedef struct QPConvTable cssurl_matrix; QPConvTable dsyb_matrix; QPConvTable ssyb_matrix; + int default_flags; } QPF_t; static QPF_t QPF = { n_ext:0, is_init:0 }; + int qpf_internal_FindStr(const char* haystack, size_t haystacklen, const char* needle, size_t needlelen) { @@ -230,6 +233,8 @@ qpf_internal_SetupTable(pQPConvTable table) /*** qpfInitialize() - inits the QPF suite. + *** The parameter determines if the global default is to assume UTF-8 + *** or not. This can be overwritten with a session. ***/ int qpfInitialize() @@ -237,6 +242,20 @@ qpfInitialize() int i; char buf[4]; char hex[] = "0123456789abcdef"; + char * locale; + int isUTF8; + + /** set up default flags **/ + QPF.default_flags = 0; + + /** init UTF-8 flag **/ + locale = setlocale(LC_CTYPE, NULL); + isUTF8 = (locale != NULL && (strstr(locale, "utf8") || strstr(locale, "UTF8") || strstr(locale, "utf-8") + || strstr(locale, "UTF-8"))); + if(isUTF8) QPF.default_flags |= QPF_F_ENFORCE_UTF8; + + + /** init tables */ memset(&QPF.quote_matrix, 0, sizeof(QPF.quote_matrix)); QPF.quote_matrix.Matrix['\''] = "\\'"; @@ -253,7 +272,7 @@ qpfInitialize() QPF.quote_ws_matrix.Matrix['\r'] = "\\r"; qpf_internal_SetupTable(&QPF.quote_ws_matrix); - memset(&QPF.jsstr_matrix, 0, sizeof(QPF.jsstr_matrix)); + memset(&QPF.jsstr_matrix, 0, sizeof(QPF.jsstr_matrix)); /* javascript */ QPF.jsstr_matrix.Matrix['\''] = "\\'"; QPF.jsstr_matrix.Matrix['"'] = "\\\""; QPF.jsstr_matrix.Matrix['\\'] = "\\\\"; @@ -420,6 +439,8 @@ qpfInitialize() /*** qpfOpenSession() - open a new qprintf session. The session is used for *** storing cumulative error information, to make error handling much cleaner *** for any caller that wants to do so. + *** + *** Assumes default values for all flags based on global context (currently just the one flag) ***/ pQPSession qpfOpenSession() @@ -434,6 +455,27 @@ qpfOpenSession() s = (pQPSession)nmMalloc(sizeof(QPSession)); if (!s) return NULL; s->Errors = 0; + s->Flags = QPF.default_flags; + return s; + } + +/*** qpfOpenSessionFlags() - Same as qpfOpenSession, but enables session flags to be set directly, + *** trumping global flags + ***/ +pQPSession +qpfOpenSessionFlags(unsigned int flags) + { + pQPSession s = NULL; + + if (!QPF.is_init) + { + if (qpfInitialize() < 0) return NULL; + } + + s = (pQPSession)nmMalloc(sizeof(QPSession)); + if (!s) return NULL; + s->Errors = 0; + s->Flags = flags; return s; } @@ -506,8 +548,8 @@ qpf_internal_itoa(char* dst, size_t dstlen, int i) return rval; } - /*** qpf_internal_base64encode() - convert string to base 64 representation + *** returns the number of characters added to destination, and modifies dst_offset ***/ int qpf_internal_base64encode(pQPSession s, const char* src, size_t src_size, char** dst, size_t* dst_size, size_t* dst_offset, qpf_grow_fn_t grow_fn, void* grow_arg) @@ -516,7 +558,8 @@ qpf_internal_base64encode(pQPSession s, const char* src, size_t src_size, char** const unsigned char* srcptr = (const unsigned char*)src; const unsigned char* origsrc = (const unsigned char*)src; char* dstptr; - int req_size = ((src_size+2) / 3) * 4 + *dst_offset; + int req_size = ((src_size+2) / 3) * 4 + *dst_offset + 1; /* make sure to leave room for null */ + int oldOff = *dst_offset; /** Grow dstbuf if necessary and possible, otherwise return error **/ if (req_size > *dst_size) @@ -531,7 +574,7 @@ qpf_internal_base64encode(pQPSession s, const char* src, size_t src_size, char** dstptr = *dst + *dst_offset; /** Step through src 3 bytes at a time, generating 4 dst bytes for each 3 src **/ - while(srcptr < origsrc + src_size) + while(srcptr < origsrc + src_size) { /** First 6 bits of source[0] --> first byte dst. **/ dstptr[0] = b64[srcptr[0]>>2]; @@ -567,9 +610,9 @@ qpf_internal_base64encode(pQPSession s, const char* src, size_t src_size, char** srcptr += 3; } - *dst_offset = *dst_offset + (dstptr - *dst); + *dst_offset = (dstptr - *dst); - return dstptr - *dst; + return dstptr - *dst - oldOff; } @@ -582,7 +625,20 @@ qpf_internal_base64decode(pQPSession s, const char* src, size_t src_size, char** char* ptr; char* cursor; int ix; - int req_size = (.75 * src_size) + *dst_offset + 1; /** fmul could truncate when cast to int hence +1 **/ + int bytes_left; + int req_size = (.75 * src_size) + *dst_offset + 1; /** +1 for null. Valid B64 must be a multiple of 4, so no truncation **/ + int oldOffset = *dst_offset; + char * oldSrc = src; + + /* adjust esitmate; only accurate to nearest 3 bytes otherwise */ + if(src[src_size - 2] == '=' && src[src_size - 1] == '=') req_size -= 2; + else if(src[src_size - 1] == '=') req_size -= 1; + + if(src_size % 4 != 0) /* confirm assumption above is correct. */ + { + QPERR(QPF_ERR_T_BADCHAR); + return -1; + } /** Verify source data is correct length for base 64 **/ if (src_size % 4 != 0) @@ -604,10 +660,11 @@ qpf_internal_base64decode(pQPSession s, const char* src, size_t src_size, char** cursor = *dst + *dst_offset; /** Step through src 4 bytes at a time. **/ - while(*src) + while(*src && src - oldSrc < src_size) { /** First 6 bits. **/ ptr = strchr(b64,src[0]); + if (!ptr || !*ptr) { QPERR(QPF_ERR_T_BADCHAR); @@ -627,6 +684,11 @@ qpf_internal_base64decode(pQPSession s, const char* src, size_t src_size, char** cursor[0] |= ix>>4; cursor[1] = (ix<<4)&0xF0; + /** make sure have enough room for the full character just started. **/ + bytes_left = src_size - (int) (src + 4 - oldSrc); /* source bytes after this iteration */ + /** only 4 byte chars could be a problem here **/ + if(s->Flags & QPF_F_ENFORCE_UTF8 && numBytesInChar((char)(cursor[0])) >= 4 && bytes_left < 4 ) break; + /** Third six bits are nonmandatory and split between cursor[1] and [2] **/ if (src[2] == '=' && src[3] == '=') { @@ -643,6 +705,13 @@ qpf_internal_base64decode(pQPSession s, const char* src, size_t src_size, char** cursor[1] |= ix>>2; cursor[2] = (ix<<6)&0xC0; + /** a 3 or 4 byte char could be a problem **/ + if(s->Flags & QPF_F_ENFORCE_UTF8 && numBytesInChar((char)(cursor[1])) >= 3 && bytes_left < 4 ) + { + cursor += 1; + break; + } + /** Fourth six bits are nonmandatory and a part of cursor[2]. **/ if (src[3] == '=') { @@ -657,17 +726,32 @@ qpf_internal_base64decode(pQPSession s, const char* src, size_t src_size, char** } ix = ptr-b64; cursor[2] |= ix; + + /** a 2, 3, or 4 byte char could be a problem **/ + if(s->Flags & QPF_F_ENFORCE_UTF8 && numBytesInChar((char)(cursor[2])) >= 2 && bytes_left < 4 ) + { + cursor += 2; + break; + } + src += 4; cursor += 3; } - *dst_offset = *dst_offset + cursor - *dst; + /* make sure data decoded is valid, if applicable */ + *cursor = 0; /* only check what just added */ + if(s->Flags & QPF_F_ENFORCE_UTF8 && verifyUTF8((*dst + oldOffset)) != UTIL_VALID_CHAR) + { + QPERR(QPF_ERR_T_BADCHAR); + return -1; + } - return cursor - *dst; + *dst_offset = cursor - *dst; + return *dst_offset - oldOffset; } -/*** qpf_internal_hexdecode() - convert base 64 to a string representation +/*** qpf_internal_hexdecode() - convert base 16 to a string representation ***/ static inline int qpf_internal_hexdecode(pQPSession s, const char* src, size_t src_size, char** dst, size_t* dst_size, size_t* dst_offset, qpf_grow_fn_t grow_fn, void* grow_arg) @@ -677,7 +761,9 @@ qpf_internal_hexdecode(pQPSession s, const char* src, size_t src_size, char** ds char* ptr; char* cursor; int ix; - int req_size; + int req_size, bytes_left; + int oldOffset = *dst_offset; + char* oldSrc = src; /** Required size **/ if (src_size%2 == 1) @@ -685,10 +771,10 @@ qpf_internal_hexdecode(pQPSession s, const char* src, size_t src_size, char** ds QPERR(QPF_ERR_T_BADLENGTH); return -1; } - req_size = src_size/2; + req_size = src_size/2 + *dst_offset + 1; /* need to fit decoded data and null */ /** Grow dstbuf if necessary and possible, otherwise return error **/ - if (req_size > *dst_size) + if (req_size > *dst_size) { if(grow_fn == NULL || !grow_fn(dst, dst_size, 0, grow_arg, req_size)) { @@ -700,11 +786,11 @@ qpf_internal_hexdecode(pQPSession s, const char* src, size_t src_size, char** ds cursor = *dst + *dst_offset; /** Step through src 2 bytes at a time. **/ - while(*src) + while(*src && src - oldSrc < src_size) { /** First 4 bits. **/ ptr = strchr(hex, src[0]); - if (!ptr) + if (!ptr || !*ptr) /* make sure null's are not counted */ { QPERR(QPF_ERR_T_BADCHAR); return -1; @@ -714,7 +800,7 @@ qpf_internal_hexdecode(pQPSession s, const char* src, size_t src_size, char** ds /** Second four bits **/ ptr = strchr(hex, src[1]); - if (!ptr) + if (!ptr || !*ptr) { QPERR(QPF_ERR_T_BADCHAR); return -1; @@ -722,13 +808,24 @@ qpf_internal_hexdecode(pQPSession s, const char* src, size_t src_size, char** ds ix = conv[ptr-hex]; cursor[0] |= ix; + /** make sure have enough room for the full character just started. **/ + bytes_left = src_size - (int) (src + 2 - oldSrc); /* source bytes after this iteration */ + if(s->Flags & QPF_F_ENFORCE_UTF8 && (numBytesInChar((char)*(cursor)) - 1)*2 > bytes_left ) break; + src += 2; cursor += 1; } - *dst_offset = *dst_offset + cursor - *dst; + *cursor = 0; /* only check what just added */ + if(s->Flags & QPF_F_ENFORCE_UTF8 && verifyUTF8((*dst + oldOffset)) != UTIL_VALID_CHAR) + { + QPERR(QPF_ERR_T_BADCHAR); + return -1; + } + + *dst_offset = cursor - *dst; - return cursor - *dst; + return *dst_offset - oldOffset; } @@ -786,9 +883,10 @@ qpf_internal_Translate(pQPSession s, const char* srcbuf, size_t srcsize, char** { int rval = 0; unsigned int tlen; - int i; + int i, j; char* trans; int nogrow = (grow_fn == NULL); + int charBytes, totalBytes; if (srcsize >= SIZE_MAX/2/table->MaxExpand) return -1; @@ -821,14 +919,28 @@ qpf_internal_Translate(pQPSession s, const char* srcbuf, size_t srcsize, char** if (__builtin_expect(((trans = table->Matrix[(unsigned char)(srcbuf[i])]) != NULL), 0)) { tlen = table->MatrixLen[(unsigned char)(srcbuf[i])]; - if (__builtin_expect(limit >= tlen, 1)) + /** if enforcing utf-8, then must make sure full byte will fit. **/ + /* Determine if full char will fit. If is 1 byte, stays tlen. If middle byte (i.e. 10XX XXXX) was checked before */ + charBytes = numBytesInChar(srcbuf[i]); + totalBytes = tlen; + if(s->Flags & QPF_F_ENFORCE_UTF8 && charBytes >= 2) + { + for(j = 1 ; j < charBytes ; j++ ) + { + /** if will sub, need to count on larger size. If not, just needs 1 byte. **/ + totalBytes += ((table->Matrix[(unsigned char)(srcbuf[i+j])]) != NULL)? + table->MatrixLen[(unsigned char)(srcbuf[i+j])] : 1; + } + } + + if (__builtin_expect(limit >= totalBytes, 1)) { rval += (tlen-1); - if (__builtin_expect(!nogrow,1) && (__builtin_expect((*dstoffs)+tlen+min_room <= (*dstsize), 1) || - (grow_fn(dstbuf, dstsize, *dstoffs, grow_arg, (*dstoffs)+tlen+min_room)))) + if (__builtin_expect(!nogrow,1) && (__builtin_expect((*dstoffs)+totalBytes+min_room <= (*dstsize), 1) || + (grow_fn(dstbuf, dstsize, *dstoffs, grow_arg, (*dstoffs)+totalBytes+min_room)))) { while(*trans) (*dstbuf)[(*dstoffs)++] = *(trans++); - limit -= tlen; + limit -= tlen; /* although room is ensured for totalBytes, only used up tlen so far */ } else { @@ -840,22 +952,49 @@ qpf_internal_Translate(pQPSession s, const char* srcbuf, size_t srcsize, char** { QPERR(QPF_ERR_T_INSOVERFLOW); rval--; + limit = 0; } } else { - if (__builtin_expect(limit > 0, 1)) + if (__builtin_expect(limit > 0, 1)) { - if (__builtin_expect(!nogrow,1) && (__builtin_expect((*dstoffs)+1+min_room <= (*dstsize), 1) || - (grow_fn(dstbuf, dstsize, *dstoffs, grow_arg, (*dstoffs)+1+min_room)))) + /** check for UTF-8 **/ + if(s->Flags & QPF_F_ENFORCE_UTF8) + { + charBytes = numBytesInChar(srcbuf[i]); + if(charBytes == -1) + { + QPERR(QPF_ERR_T_BADCHAR); /* let caller handle */ + charBytes = 1; + } + } + else charBytes = 1; + + if ((__builtin_expect(!nogrow,1) && (__builtin_expect((*dstoffs)+charBytes+min_room <= (*dstsize), 1)) || + (grow_fn(dstbuf, dstsize, *dstoffs, grow_arg, (*dstoffs)+charBytes+min_room)))) { - (*dstbuf)[(*dstoffs)++] = srcbuf[i]; - limit--; + /** make sure the whole chracter fits **/ + if(charBytes > limit) + { + QPERR(QPF_ERR_T_TRUNC); + limit = 0; /* prevent any other chars from filling in the space */ + rval--; + continue; + } + + /* copy over all bytes of char at once */ + for(j = 0 ; j < charBytes ; j++) + { + (*dstbuf)[(*dstoffs)++] = srcbuf[i+j]; + } + i+=j-1; + limit -= charBytes; } else { QPERR(QPF_ERR_T_BUFOVERFLOW); - nogrow = 1; + break; } } else @@ -921,6 +1060,7 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow if (!s) { null_session.Errors = 0; + null_session.Flags = QPF.default_flags; s=&null_session; } @@ -1177,7 +1317,8 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow (cplen == 2 && strval[0] == '.' && strval[1] == '.') || memchr(strval, '/', cplen) || memchr(strval, '\0', cplen) || - cplen == 0) + cplen == 0 || + (s->Flags & QPF_F_ENFORCE_UTF8 && verifyUTF8(strval) != UTIL_VALID_CHAR)) { rval = -EINVAL; QPERR(QPF_ERR_T_BADFILE); goto error; } break; @@ -1189,7 +1330,8 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow memchr(strval, '\0', cplen) || cplen == 0 || (cplen > 2 && strval[cplen-1] == '.' && strval[cplen-2] == '.' && strval[cplen-3] == '/') || - qpf_internal_FindStr(strval, cplen, "/../", 4) >= 0) + qpf_internal_FindStr(strval, cplen, "/../", 4) >= 0 || + (s->Flags & QPF_F_ENFORCE_UTF8 && verifyUTF8(strval) != UTIL_VALID_CHAR)) { rval = -EINVAL; QPERR(QPF_ERR_T_BADPATH); goto error; } break; @@ -1402,6 +1544,22 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow cplen = (*size) - cpoffset - 1; nogrow = 1; } + /** adjust bounds to ensure no utf-8 characters are chopped **/ + if(s->Flags & QPF_F_ENFORCE_UTF8) + { + if((unsigned char)strval[cplen-1] >= (unsigned char) 0xC0 && cplen >= 1) /* check for any header */ + { + cplen -= 1; + } + else if((unsigned char)strval[cplen-2] >= (unsigned char) 0xE0 && cplen >= 2) /* check for cut off 3/4 byte */ + { + cplen -= 2; + } + else if((unsigned char)strval[cplen-3] >= (unsigned char) 0xF0 && cplen >= 3) /* check for cut off 4 byte */ + { + cplen -= 3; + } + } memcpy((*str)+cpoffset, strval, cplen); } @@ -1415,7 +1573,27 @@ qpfPrintf_va_internal(pQPSession s, char** str, size_t* size, qpf_grow_fn_t grow rval = copied; - error: + + /** check for possible utf-8 characters split at end. Only a possible problem if in last 3 chracters **/ + if(s->Flags & QPF_F_ENFORCE_UTF8) + { + if((unsigned char)(*str)[cpoffset-1] >= (unsigned char) 0xC0 && cpoffset >= 1) /* check for any header */ + { + cpoffset -= 1; + } + else if((unsigned char)(*str)[cpoffset-2] >= (unsigned char) 0xE0 && cpoffset >= 2) /* check for cut off 3/4 byte */ + { + cpoffset -= 2; + } + else if((unsigned char)(*str)[cpoffset-3] >= (unsigned char) 0xF0 && cpoffset >= 3) /* check for cut off 4 byte */ + { + cpoffset -= 3; + } + } + + /* if 3rd to last character is header for 4 bytes (>= 0xF0) then is truncated or invalid byte */ + + error: /** Null terminate. Only case where this does not happen is ** if size == 0 on the initial call. Terminator is not counted ** in the return value. @@ -1447,5 +1625,3 @@ qpfRegisterExt(char* ext_spec, int (*ext_fn)(), int is_source) return; } - - diff --git a/centrallix-lib/src/stparse.c b/centrallix-lib/src/stparse.c index 02cc81484..9ebcccd2e 100644 --- a/centrallix-lib/src/stparse.c +++ b/centrallix-lib/src/stparse.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "mtask.h" #include "mtlexer.h" #include "exception.h" @@ -566,9 +567,15 @@ stParseMsg(pFile inp_fd, int flags) { pStructInf info; pLxSession s; + char * locale; + int mlxFlags; /** Open a session with the lexical analyzer **/ - s = mlxOpenSession(inp_fd, MLX_F_CPPCOMM | MLX_F_DBLBRACE); + mlxFlags = MLX_F_CPPCOMM | MLX_F_DBLBRACE; + locale = setlocale(LC_ALL, NULL); + if(strstr(locale, "UTF-8") || strstr(locale, "UTF8") || strstr(locale, "utf-8") || strstr(locale, "utf8")) + mlxFlags |= MLX_F_ENFORCEUTF8; + s = mlxOpenSession(inp_fd, mlxFlags); if (!s) { mssError(0,"ST","Could not begin analysis of structure file"); @@ -593,9 +600,14 @@ stParseMsgGeneric(void* src, int (*read_fn)(), int flags) { pStructInf info; pLxSession s; - + char * locale; + int mlxFlags; /** Open a session with the lexical analyzer **/ - s = mlxGenericSession(src,read_fn, MLX_F_CPPCOMM | MLX_F_DBLBRACE); + mlxFlags = MLX_F_CPPCOMM | MLX_F_DBLBRACE; + locale = setlocale(LC_ALL, NULL); + if(strstr(locale, "UTF-8") || strstr(locale, "UTF8") || strstr(locale, "utf-8") || strstr(locale, "utf8")) + mlxFlags |= MLX_F_ENFORCEUTF8; + s = mlxGenericSession(src,read_fn, mlxFlags); if (!s) { mssError(0,"ST","Could not begin analysis of structure file"); diff --git a/centrallix-lib/src/util.c b/centrallix-lib/src/util.c index 629b59c79..a8b84adff 100644 --- a/centrallix-lib/src/util.c +++ b/centrallix-lib/src/util.c @@ -77,3 +77,146 @@ unsigned int strtoui(const char *nptr, char **endptr, int base){ //return as tmp; return (unsigned int)tmp; } + +/** + * Validates a utf8 string and ensures no invalid characters are present. + * @param str the string to be verified + * @return the index of first byte of the first invalid character, or + * UTIL_VALID_CHAR or UTIL_INVALID_ARGUMENT when applicable + * NOTE: This only works with null terminated strings + */ +int verifyUTF8(char* str) + { + return nVerifyUTF8(str, strlen(str)); + } + +/** + * Validates a utf8 string and ensures no invalid characters are present. + * @param str the string to be verified + * @param len the length of the string to be verified + * @return the index of first byte of the first invalid character, or + * UTIL_VALID_CHAR or UTIL_INVALID_ARGUMENT when applicable + */ +int nVerifyUTF8(char* str, int len) + { + typedef unsigned char CHAR; + int state = UTIL_STATE_START; + int off = 0; + int lastStart = -1; /** need start of invalid chars **/ + /** Check arguments **/ + if(!str) + return UTIL_INVALID_ARGUMENT; + + while(off < len) + { + switch(state) + { + case UTIL_STATE_START: + if((CHAR) str[off] <= (CHAR) 0x7F) state = UTIL_STATE_START; /** of the form 0XXX XXXX **/ + else if ((CHAR) str[off] <= (CHAR) 0xBF) state = UTIL_STATE_ERROR; /** not a header **/ + else if ((CHAR) str[off] <= (CHAR) 0xC1) state = UTIL_STATE_ERROR; /** overlong form **/ + else if ((CHAR) str[off] <= (CHAR) 0xDF) state = UTIL_STATE_1_BYTE; /** of the form 110X XXXX **/ + else if ((CHAR) str[off] == (CHAR) 0xE0) state = UTIL_STATE_E_OVERLONG; /** check for overlong **/ + else if ((CHAR) str[off] == (CHAR) 0xED) state = UTIL_STATE_E_SURROGATE; + else if ((CHAR) str[off] <= (CHAR) 0xEF) state = UTIL_STATE_2_BYTE; /** of the form 1110 XXXX **/ + else if ((CHAR) str[off] == (CHAR) 0xF0) state = UTIL_STATE_F_OVERLONG; /** check for overlong **/ + else if ((CHAR) str[off] <= (CHAR) 0xF3) state = UTIL_STATE_3_BYTE; + else if ((CHAR) str[off] == (CHAR) 0xF4) state = UTIL_STATE_TOO_LARGE; + else state = UTIL_STATE_ERROR; /** header must be too big **/ + + lastStart = off; + if(state != UTIL_STATE_ERROR) off++; + break; + + case UTIL_STATE_3_BYTE: + if((CHAR) str[off] > (CHAR) 0xBF || (CHAR) str[off] < (CHAR) 0x80) state = UTIL_STATE_ERROR; + else state = UTIL_STATE_2_BYTE; + + if(state != UTIL_STATE_ERROR) off++; + break; + + case UTIL_STATE_2_BYTE: + if((CHAR) str[off] > (CHAR) 0xBF || (CHAR) str[off] < (CHAR) 0x80) state = UTIL_STATE_ERROR; + else state = UTIL_STATE_1_BYTE; + + if(state != UTIL_STATE_ERROR) off++; + break; + + case UTIL_STATE_1_BYTE: + if((CHAR) str[off] > (CHAR) 0xBF || (CHAR) str[off] < (CHAR) 0x80) state = UTIL_STATE_ERROR; + else state = UTIL_STATE_START; + if(state != UTIL_STATE_ERROR) off++; + break; + + case UTIL_STATE_E_OVERLONG: + if((CHAR) str[off] <= (CHAR) 0x9F ) state = UTIL_STATE_ERROR; + else state = UTIL_STATE_2_BYTE; /** jump back in **/ + break; + + case UTIL_STATE_E_SURROGATE: + if((CHAR) str[off] >= (CHAR) 0xA0 ) state = UTIL_STATE_ERROR; + else state = UTIL_STATE_2_BYTE; /** jump back in **/ + break; + + case UTIL_STATE_F_OVERLONG: + if((CHAR) str[off] <= (CHAR) 0x8F ) state = UTIL_STATE_ERROR; + else state = UTIL_STATE_3_BYTE; /** jump back in **/ + break; + + case UTIL_STATE_TOO_LARGE: + if((CHAR) str[off] > (CHAR) 0x8F) state = UTIL_STATE_ERROR; + else state = UTIL_STATE_3_BYTE; /** jump back in **/ + break; + + case UTIL_STATE_ERROR: + return lastStart; + break; + } + } + if(state != UTIL_STATE_START) return lastStart; /** end of string splits char **/ + + return UTIL_VALID_CHAR; +} + +/** + * Validates an ASCII string and ensures no invalid characters are present. + * @param str the string to be verified + * @return the index of first invalid character, or UTIL_VALID_CHAR or + * UTIL_INVALID_ARGUMENT when applicable + */ +int +verifyASCII(char * str) + { + typedef unsigned char CHAR; + int off = 0; + if(!str) return UTIL_INVALID_ARGUMENT; + + while(str[off] != '\0') + { + if((unsigned) str[off] > 127) return off; + off++; + } + return UTIL_VALID_CHAR; + } + +/** + * Computes the number of bytes in a utf-8 char based on + * the first byte of the character. Returns -1 for a byte which does not indicate the + * legth of the byte (i.e., anything of the form 10XX XXXX or 1111 10XX would be invalid) + * @param byte the character to be checked + * @return the number of bytes in the character, or -1 on error. + * + * NOTE: this should NOT be used to validate characters; overlong forms, UTF-16 surrogate + * halves, and overly large characters starting with 0xF4-0xF7 are not handled + */ +int +numBytesInChar(char byte) + { + if (!(byte&0x80)) return 1; /* of the form 0XXX XXXX */ + else if (!(byte&0x40)) return -1; /* of the form 10XX XXXX */ + else if (!(byte&0x20)) return 2; /* of the form 110X XXXX */ + else if (!(byte&0x10)) return 3; /* of the form 1110 XXXX */ + else if (!(byte&0x08)) return 4; /* of the form 1111 0XXX */ + else return -1; /* of the form 1111 1XXX */ + } + diff --git a/centrallix-lib/src/xstring.c b/centrallix-lib/src/xstring.c index 51df377c2..777a2bc66 100644 --- a/centrallix-lib/src/xstring.c +++ b/centrallix-lib/src/xstring.c @@ -596,7 +596,7 @@ xsTrim(pXString this) return 0; } -/*** xsFind - searches an xString for a string from an offset and returns the offset it was found at +/*** xsFind - searches an xString for a string from a byte offset and returns the byte offset it was found at *** returns -1 if not found ***/ int @@ -605,7 +605,10 @@ xsFind(pXString this,char* find,int findlen, int offset) CXSEC_ENTRY(XS_FN_KEY); ASSERTMAGIC(this, MGK_XSTRING); CXSEC_VERIFY(*this); - if(findlen==-1) findlen=strlen(find); + if ((this == NULL) || (find == NULL)) + return -1; + if(offset<0) offset = 0; + if(findlen==-1) findlen = strlen(find); for(;offsetLength;offset++) { if(this->String[offset]==find[0]) @@ -627,6 +630,53 @@ xsFind(pXString this,char* find,int findlen, int offset) return -1; } +/*** xsFindWithCharOffset - searches an xString for a string from a char offset and returns the char offset it was found at + *** findlen is length in bytes + *** returns -1 if not found + ***/ +int +xsFindWithCharOffset(pXString this, char* find, int findlen, int offset) + { + CXSEC_ENTRY(XS_FN_KEY); + ASSERTMAGIC(this, MGK_XSTRING); + CXSEC_VERIFY(*this); + if ((this == NULL) || (find == NULL)) + return -1; + int chars, byte, i; + if (offset < 0) offset = 0; + if (findlen == -1) findlen = strlen(find); + byte = -1; + chars = -1; + while (chars < offset) + { + byte++; + if ((this->String[byte] & 0xC0) != 0x80) + chars++; + } + if (byte == -1) byte = 0; + if (chars == offset) chars--; + for (; byte < this->Length; byte ++) + { + if ((this->String[byte] & 0xC0) != 0x80) + chars++; + if (this->String[byte]==find[0]) + { + for(i=1;iString[byte+i]!=find[i]) + break; + if(i==findlen) + { + CXSEC_EXIT(XS_FN_KEY); + return chars; + } + } + } + CXSEC_EXIT(XS_FN_KEY); + return -1; + } + + + /*** xsFindReverse - searches an xString for a string from an offset (from the end) and returns the offset it was found at *** returns -1 if not found ***/ @@ -636,7 +686,9 @@ xsFindRev(pXString this,char* find,int findlen, int offset) CXSEC_ENTRY(XS_FN_KEY); ASSERTMAGIC(this, MGK_XSTRING); CXSEC_VERIFY(*this); - if(findlen==-1) findlen=strlen(find); + if ((this == NULL) || (find == NULL)) + return -1; + if(findlen==-1) findlen = strlen(find); offset=this->Length-offset-1; for(;offset>=0;offset--) { @@ -659,6 +711,58 @@ xsFindRev(pXString this,char* find,int findlen, int offset) return -1; } +/*** xsFindRevWithCharOffset - searches an xString for a string from a char offset (from the end) and returns the char offset it was found at + * *** findlen is length in bytes + * *** returns -1 if not found + * ***/ +int +xsFindRevWithCharOffset(pXString this, char* find, int findlen, int offset) + { + CXSEC_ENTRY(XS_FN_KEY); + ASSERTMAGIC(this, MGK_XSTRING); + CXSEC_VERIFY(*this); + if ((this == NULL) || (find == NULL)) + return -1; + int chars, byte, i, cnt; + if (offset < 0) offset = 0; + if (findlen == -1) findlen = strlen(find); + byte = this->Length - 1; + chars = (int) chrCharLength(this->String); + if ((chars == -1) || (offset > chars)) + { + CXSEC_EXIT(XS_FN_KEY); return -1; + } + cnt = 0; + while ((cnt < offset) && (offset != 0)) + { + if ((this->String[byte] & 0xC0) != 0x80) + { + chars--; + cnt++; + } + byte--; + } + + for (; byte >= 0; byte--) + { + if ((this->String[byte] & 0xC0) != 0x80) + chars--; + if (this->String[byte]==find[0]) + { + for(i=1;iString[byte+i]!=find[i]) + break; + if(i==findlen) + { + CXSEC_EXIT(XS_FN_KEY); + return chars; + } + } + } + CXSEC_EXIT(XS_FN_KEY); + return -1; + } + /*** xsSubst - substitutes a string in a given position in an xstring. does not *** search for matches like xsreplace does - you have to tell it the position @@ -666,12 +770,16 @@ xsFindRev(pXString this,char* find,int findlen, int offset) ***/ int xsSubst(pXString this, int offset, int len, char* rep, int replen) - { - CXSEC_ENTRY(XS_FN_KEY); - + { + CXSEC_ENTRY(XS_FN_KEY); ASSERTMAGIC(this, MGK_XSTRING); CXSEC_VERIFY(*this); + + if ((this == NULL) || (rep == NULL)) + return -1; + int i; + /** Figure some default lengths **/ if (offset > this->Length || offset < 0) { @@ -680,10 +788,24 @@ xsSubst(pXString this, int offset, int len, char* rep, int replen) } if (len == -1) len = strlen(this->String + offset); if (replen == -1) replen = strlen(rep); - + /** Make sure we have enough room **/ if (len < replen) xsCheckAlloc(this, replen - len); - + + /** Make sure we do not end up with a partial UTF-8 character **/ + for (i = 0; i < 4; i++) { + if((this->String[offset + i] & 0xC0) != 0x80) + break; + } + offset += i; + + for (i = 0; i < 4; i++) + { + if((this->String[offset + len + i] & 0xC0) != 0x80) + break; + } + len += i; + /** Move the tail of the string, and plop the replacement in there **/ memmove(this->String+offset+replen, this->String+offset+len, this->Length + 1 - (offset+len)); memcpy(this->String+offset, rep, replen); @@ -694,6 +816,74 @@ xsSubst(pXString this, int offset, int len, char* rep, int replen) return 0; } +/*** xsSubstWithCharOffset - substitutes a string in a given position in an xstring. + *** does not search for matches like xsreplace does - you have to tell it the + *** position and length to replace. Length of -1 indicates length is unknown. + ***/ +int +xsSubstWithCharOffset(pXString this, int offsetChars, int lenChars, char* rep, int replen) + { + CXSEC_ENTRY(XS_FN_KEY); + ASSERTMAGIC(this, MGK_XSTRING); + CXSEC_VERIFY(*this); + + if ((this == NULL) || (rep == NULL)) return -1; + + int i, cnt, len, offset; + + /** Figure some default lengths **/ + if (offsetChars > chrCharLength(this->String) || offsetChars < 0) + { + CXSEC_EXIT(XS_FN_KEY); + return -1; + } + + if (replen == -1) replen = strlen(rep); + + offset = 0; + cnt = 0; + while (cnt < offsetChars) + { + if ((this->String[offset] & 0xC0) != 0x80) + cnt++; + offset++; + } + for (i = 0; i < 4; i++) { + if((this->String[offset + i] & 0xC0) != 0x80) + break; + } + offset += i; + + if (lenChars == -1) lenChars = chrCharLength(this->String + offset); + + len = 0; + cnt = 0; + while (cnt < lenChars) + { + if ((this->String[offset+len] & 0xC0) != 0x80) + cnt++; + len++; + } + for (i = 0; i < 4; i++) { + if((this->String[offset + len + i] & 0xC0) != 0x80) + break; + } + len += i; + + /** Make sure we have enough room **/ + if (len < replen) xsCheckAlloc(this, replen - len); + + /** Move the tail of the string, and plop the replacement in there **/ + memmove(this->String+offset+replen, this->String+offset+len, this->Length + 1 - (offset+len)); + memcpy(this->String+offset, rep, replen); + this->Length += (replen - len); + CXSEC_UPDATE(*this); + + CXSEC_EXIT(XS_FN_KEY); + return 0; + } + + /*** xsReplace - searches an xString for a string and replaces that string with another *** returns the starting offset of the replace if successful, and -1 if not found @@ -704,8 +894,8 @@ xsReplace(pXString this, char* find, int findlen, int offset, char* rep, int rep CXSEC_ENTRY(XS_FN_KEY); ASSERTMAGIC(this, MGK_XSTRING); CXSEC_VERIFY(*this); - if(findlen==-1) findlen=strlen(find); - if(replen==-1) replen=strlen(rep); + if(findlen==-1) findlen = strlen(find); + if(replen==-1) replen = strlen(rep); offset=xsFind(this,find,findlen,offset); if(offset < 0) { @@ -735,6 +925,57 @@ xsReplace(pXString this, char* find, int findlen, int offset, char* rep, int rep return offset; } +/*** xsReplace - searches an xString for a string from a character offset and + *** replaces that string with another returns the starting character offset of + *** the replace if successful, and -1 if not found + ***/ +int +xsReplaceWithCharOffset(pXString this, char* find, int findlen, int offset, char* rep, int replen) + { + CXSEC_ENTRY(XS_FN_KEY); + ASSERTMAGIC(this, MGK_XSTRING); + CXSEC_VERIFY(*this); + int offsetBytes = 0, cnt = 0; + if(findlen==-1) findlen = strlen(find); + if(replen==-1) replen = strlen(rep); + offset=xsFindWithCharOffset(this,find,findlen,offset); + if(offset < 0) + { + CXSEC_EXIT(XS_FN_KEY); + return -1; + } + while(cnt<=offset) + { + if ((this->String[offsetBytes] & 0xC0) != 0x80) + cnt++; + offsetBytes++; + } + if(offsetBytes!=0) + offsetBytes--; + + if(findlen>=replen) + { + memcpy(&(this->String[offsetBytes]),rep,replen); + if(replen!=findlen) + { + memmove(this->String+offsetBytes+replen,this->String+offsetBytes+findlen,this->Length-offsetBytes-findlen+1); + this->Length-=findlen-replen; + } + } + else + { + /** warning: untested code :) **/ + xsCheckAlloc(this,replen-findlen); + memmove(this->String+offsetBytes+replen,this->String+offsetBytes+findlen,this->Length-offsetBytes-findlen+1); + memcpy(&(this->String[offsetBytes]),rep,replen); + this->Length+=replen-findlen; + } + this->String[this->Length] = '\0'; + CXSEC_UPDATE(*this); + CXSEC_EXIT(XS_FN_KEY); + return offset; + } + /*** xsInsertAfter - inserts the supplied string at offset -- returns new offset ***/ int @@ -743,7 +984,7 @@ xsInsertAfter(pXString this, char* ins, int inslen, int offset) CXSEC_ENTRY(XS_FN_KEY); ASSERTMAGIC(this, MGK_XSTRING); CXSEC_VERIFY(*this); - if(inslen==-1) inslen=strlen(ins); + if(inslen==-1) inslen = strlen(ins); if(xsCheckAlloc(this,inslen)==-1) { CXSEC_EXIT(XS_FN_KEY); @@ -757,6 +998,37 @@ xsInsertAfter(pXString this, char* ins, int inslen, int offset) return offset+inslen; } +/*** xsInsertAfterWithCharOffset - inserts the supplied string at character offset -- returns new character offset + ***/ +int +xsInsertAfterWithCharOffset(pXString this, char* ins, int inslen, int offset) + { + CXSEC_ENTRY(XS_FN_KEY); + ASSERTMAGIC(this, MGK_XSTRING); + CXSEC_VERIFY(*this); + int cnt = 0, offsetBytes = 0; + if(inslen==-1) inslen = strlen(ins); + if(xsCheckAlloc(this,inslen)==-1) + { + CXSEC_EXIT(XS_FN_KEY); + return -1; + } + + while(cnt<=offset) + { + if ((this->String[offsetBytes] & 0xC0) != 0x80) + cnt++; + offsetBytes++; } if(offsetBytes!=0) offsetBytes--; + + memmove(this->String+offsetBytes+inslen,this->String+offsetBytes,this->Length-offsetBytes+1); + memcpy(this->String+offsetBytes,ins,inslen); + this->Length+=inslen; + CXSEC_UPDATE(*this); + CXSEC_EXIT(XS_FN_KEY); + return offset+chrCharLength(ins); + } + + /*** xsGenPrintf - generic printf() operation to a xxxWrite() style function. *** This routine isn't really all that closely tied to the XString module, @@ -971,3 +1243,14 @@ xsConcatQPrintf(pXString this, char* fmt, ...) return rval; } +/*** chrCharLength - get number of characters in string + *** returns -1 if string is NULL or mbstowcs fails + ***/ +size_t chrCharLength(char* string) + { + size_t length; + if(!string) + return -1; + length = mbstowcs(NULL, string, 0); + return length; + } diff --git a/centrallix-lib/tests/test_foreign_00.c b/centrallix-lib/tests/test_foreign_00.c new file mode 100644 index 000000000..8fd8ae879 --- /dev/null +++ b/centrallix-lib/tests/test_foreign_00.c @@ -0,0 +1,26 @@ +#include +#include +#include +#include +#include +#include + +long long +test(char** tname) + { + int i; + int iter; + + char* str1 = "Glück"; + char* str2 = "Χαίρετε"; + char* str3 = "\u0393"; + char* str4 = "\xce\x93"; + printf("%s\n%s\n%s\n%s\n", str1, str2, str3, str4); + + *tname = "Printing foreign characters"; + iter = 10000000; + for(i=0;i +#include +#include +#include +#include +#include +#include +#include + +long long +test(char** tname) + { + int i; + int iter; + + setlocale(LC_CTYPE, ""); + wchar_t str[] = L"ﺎﻟﺮﺧﺎﻣ"; + //int bytes = (int)strlen(str); + //printf("bytes: %d\n", bytes); + wprintf(str); + //fflush(stdout); + wprintf(L"\n"); + wchar_t ch1 = L'ﺍ'; + wchar_t ch2 = L'ﻝ'; + wchar_t ch3 = L'ﺭ'; + wchar_t ch4 = L'ﺥ'; + wchar_t ch5 = L'ﺍ'; + wchar_t ch6 = L'ﻡ'; + wchar_t word[13]; + word[0] = ch1; + word[1] = ch2; + word[2] = ch3; + word[3] = ch4; + word[4] = ch5; + word[5] = ch6; + word[6] = '\0'; + wchar_t rev[7]; + rev[0] = ch6; + rev[1] = ch5; + rev[2] = ch4; + rev[3] = ch3; + rev[4] = ch2; + rev[5] = ch1; + rev[6] = '\0'; + + //wprintf("str: %ls\n", str); + wprintf(word); + wprintf(L"\n"); + wprintf(rev); + wprintf(L"\n"); + + + + + *tname = "Printing Arabic"; + iter = 10000000; + for(i=0;i 0 && tokens[n_tokens-1] <= MLX_TOK_MAX); + } + assert(t == MLX_TOK_EOL); + for(j=0;j 0 && tokens[n_tokens-1] <= MLX_TOK_MAX); + } + assert(t == MLX_TOK_EOL); + for(j=0;j : ( ) / . + * reserved /file/name 12.345 $ - {{ }} ; 'string' "string" 12345 = { } keyword , <> : ( ) / . + * reserved /file/name 12.345 $ - {{ }} ; 'string' "string"12345={}keyword,<>:()/ .+*reserved /file/name 12.345$-{{}};'string' +"आदि में' 'परमेश्वर ने" 12345 = { } keyword , <> : ( ) / . + * reserved /आदि में' 'परमेश्वर ने/name 12.345 $ - {{ }} ; 'आदि में' 'परमेश्वर ने' diff --git a/centrallix-lib/tests/test_mtlexer_08.c b/centrallix-lib/tests/test_mtlexer_08.c index 315912840..4322085a7 100644 --- a/centrallix-lib/tests/test_mtlexer_08.c +++ b/centrallix-lib/tests/test_mtlexer_08.c @@ -28,6 +28,8 @@ test(char** tname) for(i=0;i +#include long long test(char** tname) @@ -44,6 +45,8 @@ test(char** tname) tokstr[0][i+1] = '\n'; str[i+20] = '\n'; tokstr[0][i+19] = '\n'; + + /** normal **/ lxs = mlxStringSession(str, MLX_F_EOL | MLX_F_EOF); assert(lxs != NULL); strcnt = 0; @@ -63,6 +66,51 @@ test(char** tname) } } mlxCloseSession(lxs); + + /** utf8 **/ + lxs = mlxStringSession(str, MLX_F_EOL | MLX_F_EOF | MLX_F_ENFORCEUTF8); + assert(lxs != NULL); + strcnt = 0; + for(j=0;j +#include long long test(char** tname) @@ -31,6 +32,8 @@ test(char** tname) str[i+2] = '2'; str[i+3] = '\0'; iv = iv*10 + 1; + + /** normal **/ lxs = mlxStringSession(str, 0); assert(lxs != NULL); if ((i+1) <= 10) @@ -48,6 +51,44 @@ test(char** tname) assert(mlxNextToken(lxs) == MLX_TOK_ERROR); /* integer too big */ } mlxCloseSession(lxs); + + /** utf-8 **/ + lxs = mlxStringSession(str, MLX_F_ENFORCEUTF8); + assert(lxs != NULL); + if ((i+1) <= 10) + { + assert(mlxNextToken(lxs) == MLX_TOK_INTEGER); + n = mlxIntVal(lxs); + assert(n == iv); + assert(mlxNextToken(lxs) == MLX_TOK_INTEGER); + n = mlxIntVal(lxs); + assert(n == 2); + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); + } + else + { + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); /* integer too big */ + } + mlxCloseSession(lxs); + + /** normal **/ + lxs = mlxStringSession(str, MLX_F_ENFORCEASCII); + assert(lxs != NULL); + if ((i+1) <= 10) + { + assert(mlxNextToken(lxs) == MLX_TOK_INTEGER); + n = mlxIntVal(lxs); + assert(n == iv); + assert(mlxNextToken(lxs) == MLX_TOK_INTEGER); + n = mlxIntVal(lxs); + assert(n == 2); + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); + } + else + { + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); /* integer too big */ + } + mlxCloseSession(lxs); } return iter; diff --git a/centrallix-lib/tests/test_mtlexer_14.c b/centrallix-lib/tests/test_mtlexer_14.c index e1db1a723..84a4bbf52 100644 --- a/centrallix-lib/tests/test_mtlexer_14.c +++ b/centrallix-lib/tests/test_mtlexer_14.c @@ -32,6 +32,8 @@ test(char** tname) str[i+5] = '.'; str[i+6] = '2'; str[i+7] = '\0'; + + /** normal **/ lxs = mlxStringSession(str, 0); assert(lxs != NULL); if ((i+1) <= 253) @@ -48,6 +50,42 @@ test(char** tname) assert(mlxNextToken(lxs) == MLX_TOK_ERROR); /* number too big */ } mlxCloseSession(lxs); + + /** utf-8 **/ + lxs = mlxStringSession(str, MLX_F_ENFORCEUTF8); + assert(lxs != NULL); + if ((i+1) <= 253) + { + assert(mlxNextToken(lxs) == MLX_TOK_DOUBLE); + d = mlxDoubleVal(lxs); + assert(mlxNextToken(lxs) == MLX_TOK_DOUBLE); + d = mlxDoubleVal(lxs); + assert(d == 2.2); + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); + } + else + { + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); /* number too big */ + } + mlxCloseSession(lxs); + + /** ascii **/ + lxs = mlxStringSession(str, MLX_F_ENFORCEASCII); + assert(lxs != NULL); + if ((i+1) <= 253) + { + assert(mlxNextToken(lxs) == MLX_TOK_DOUBLE); + d = mlxDoubleVal(lxs); + assert(mlxNextToken(lxs) == MLX_TOK_DOUBLE); + d = mlxDoubleVal(lxs); + assert(d == 2.2); + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); + } + else + { + assert(mlxNextToken(lxs) == MLX_TOK_ERROR); /* number too big */ + } + mlxCloseSession(lxs); } return iter; diff --git a/centrallix-lib/tests/test_mtlexer_15.c b/centrallix-lib/tests/test_mtlexer_15.c index a9410bc63..937d973cd 100644 --- a/centrallix-lib/tests/test_mtlexer_15.c +++ b/centrallix-lib/tests/test_mtlexer_15.c @@ -35,6 +35,7 @@ test(char** tname) for(i=0;i + long long test(char** tname) { @@ -35,6 +36,7 @@ test(char** tname) for(i=0;i= 0); + buf[n] = '\0'; + assert(strcmp(buf, "This is some text.\n") == 0); + fdClose(fd, 0); + + /** ascii **/ + fd = fdOpen("tests/test_mtlexer_20.txt", O_RDONLY, 0600); + assert(fd != NULL); + lxs = mlxOpenSession(fd, MLX_F_EOL | MLX_F_EOF | MLX_F_NODISCARD | MLX_F_ENFORCEASCII); + assert(lxs != NULL); + for(j=1;j<=3;j++) + { + t = mlxNextToken(lxs); + assert(t == MLX_TOK_KEYWORD); + t = mlxNextToken(lxs); + assert(t == MLX_TOK_COLON); + t = mlxNextToken(lxs); + assert(t == MLX_TOK_KEYWORD); + t = mlxNextToken(lxs); + assert(t == MLX_TOK_EOL); + } + t = mlxNextToken(lxs); + assert(t == MLX_TOK_EOL); + mlxCloseSession(lxs); + n = fdRead(fd, buf, sizeof(buf) - 1, 0, 0); + assert(n >= 0); + buf[n] = '\0'; + assert(strcmp(buf, "This is some text.\n") == 0); + fdClose(fd, 0); } return iter; diff --git a/centrallix-lib/tests/test_mtlexer_21.c b/centrallix-lib/tests/test_mtlexer_21.c index 59e4281fa..3102e0bc1 100644 --- a/centrallix-lib/tests/test_mtlexer_21.c +++ b/centrallix-lib/tests/test_mtlexer_21.c @@ -28,6 +28,7 @@ test(char** tname) for(i=0;i= 0); + buf[n] = '\0'; + assert(strcmp(buf, "This is some text.\n") == 0); + fdClose(fd, 0); + + /** ascii **/ + fd = fdOpen("tests/test_mtlexer_21.txt", O_RDONLY, 0600); + assert(fd != NULL); + lxs = mlxOpenSession(fd, MLX_F_EOF | MLX_F_LINEONLY | MLX_F_NODISCARD | MLX_F_ENFORCEASCII); + assert(lxs != NULL); + for(j=1;j<=3;j++) + { + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + } + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + mlxCloseSession(lxs); + n = fdRead(fd, buf, sizeof(buf) - 1, 0, 0); + assert(n >= 0); + buf[n] = '\0'; + assert(strcmp(buf, "This is some text.\n") == 0); + fdClose(fd, 0); } return iter; diff --git a/centrallix-lib/tests/test_mtlexer_22.c b/centrallix-lib/tests/test_mtlexer_22.c new file mode 100644 index 000000000..7eaca7db3 --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_22.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include + +long long +test(char** tname) + { + int i; + int iter; + int flags; + pLxSession lxs; + int t; + char* strval; + int j; + int strcnt; + char str[65536] = "'하나님이' '세상을' '무척' '사랑하셔서' '하나밖에' '\xFF없는' '외아들마저' '보내'"; + int n_tok = 8; + char* tokstr[8] = {"하나님이", "세상을", "무척", "사랑하셔서", "하나밖에", "\xFF없는", "외아들마저", "보내"}; + int toktype[8] = {MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_ERROR, MLX_TOK_ERROR, MLX_TOK_ERROR}; + + *tname = "mtlexer-22 test strings with invalid utf-8 characters"; + + mssInitialize("system", "", "", 0, "test"); + iter = 200000; + for(i=0;i +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include +#include +#include "util.h" + +long long +test(char** tname) + { + int i, j; + int iter; + int flags; + int result; + pLxSession lxs; + char* fileNames = {"./実に神は、 /ひとり子/を/さ.え ./惜しまず与える /ほどに、 /この世界を愛して /くださいま/した.。 " + "/それは、 /神の御子を信じる者が、 /だれ\xFF一人滅びず、 /永遠のいのち/を得るた/めで.す。"}; + char* valid_fileNames = {"./実に神は、 /ひとり子/を/さ.え ./惜しまず与える /ほどに、 /この世界を愛して /くださいま/した.。 " + "/それは、 /神の御子を信じる者が、 /だれ一人滅びず、 " + "/永遠のいのち/を得るた/めで.す。/永遠のいのち/を得るた/めで.す。/永遠のいのち/を得るた/めで.す。/永遠のいのち/を得る" /* extra long file test */ + "た/めで.す。/永遠のいのち/を得るた/めで.す。/永遠のいのち/を得るた/めで.す。/永遠のいのち/を得るた/めで.す。"}; + *tname = "mtlexer-23 Test valid and invalid UTF-8 file names"; + + mssInitialize("system", "", "", 0, "test"); + iter = 20000; + for(i=0;iTokType == MLX_TOK_FILENAME); + assert(memcmp(valid_fileNames+offset, lxs->TokString, strlen(lxs->TokString)) == 0); + assert(verifyUTF8(lxs->TokString) == UTIL_VALID_CHAR); + offset += strlen(lxs->TokString) + 1; /* move past the space as well */ + } + result = mlxNextToken(lxs); + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + + /** invalid set should locate invalid **/ + flags = MLX_F_FILENAMES; + lxs = mlxStringSession(fileNames, flags | MLX_F_ENFORCEUTF8); + assert(lxs != NULL); + offset = 0; + for(j = 0 ; j < 8 ; j++) + { + result = mlxNextToken(lxs); + assert(result == MLX_TOK_FILENAME); + assert(lxs->TokType == MLX_TOK_FILENAME); + assert(memcmp(valid_fileNames+offset, lxs->TokString, strlen(lxs->TokString)) == 0); + offset += strlen(lxs->TokString) + 1; /* move past the space as well */ + } + result = mlxNextToken(lxs); + assert(lxs->TokType == MLX_TOK_ERROR); + assert(strcmp(lxs->TokString, "/だれ\xFF一人滅びず、") == 0); + mlxCloseSession(lxs); + + + /** test without utf-8 flag (and therefore without a validate); should pass all junk **/ + flags = MLX_F_FILENAMES; + lxs = mlxStringSession(fileNames, flags); + assert(lxs != NULL); + offset = 0; + for(j = 0 ; j < 10 ; j++) + { + result = mlxNextToken(lxs); + assert(result == MLX_TOK_FILENAME); + assert(lxs->TokType == MLX_TOK_FILENAME); + } + result = mlxNextToken(lxs); + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + } + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_24.c b/centrallix-lib/tests/test_mtlexer_24.c new file mode 100644 index 000000000..feeeb91bc --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_24.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include + +long long +test(char** tname) + { + int BUF_SIZE = 2000; + int i; + int iter; + int flags; + pLxSession lxs; + int t; + char* strval; + char str[65536] = "'นปฐมกาล พระเจ้าทรงสร้างทุกสิ่งในฟ้าสวรรค์และโลก ขณะนั้นโลกยังไม่มีรูปทรงและว่างเปล่า " /* one really long line (398 UTF-8 chars). Each one is 3 bytes (but not the spaces)*/ + "ความมืดปกคลุมอยู่เหนือพื้นผิวของห้วงน้ำ \xFFพระวิญญาณของพระเจ้าทรงเคลื่อนไหวอยู่เหนือน้ำนั้น " /* contains 1168 btes (including NULL) */ + "และพระเจ้าตรัสว่า “จงเกิดความสว่าง” ความสว่างก็เกิดขึ้น พระเจ้าทรงเห็นว่าความสว่างนั้นดี " + "และทรงแยกความสว่างออกจากความมืด พระเจ้าทรงเรียกความสว่างว่า “วัน” และเรียกความมืดว่า " + "“คืน” เวลาเย็นและเวลาเช้าผ่านไป นี่เป็นวันที่หนึ่ง'"; + char tokstr[MLX_STRVAL]; + memcpy(tokstr, str+1, MLX_STRVAL-1); + tokstr[MLX_STRVAL-1] = '\0'; + char buf[BUF_SIZE]; + + *tname = "mtlexer-24 test Copy Token with invalid utf-8 characters"; + + mssInitialize("system", "", "", 0, "test"); + iter = 50000; + for(i=0;iTokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now peform a copy into a buffer twice the size. Should enable invalid UTF8 to bypass the + * checks in next token, but should be caught by the check at the end of copy + */ + int result = mlxCopyToken(lxs, buf, BUF_SIZE); + str[367+1] = '\0'; /* change for test. Index of bad byte */ + assert(result == strlen(str)-1); /* -1 since ' is not included */ + assert(strcmp(buf, str+1) == 0); + str[367+1] = '\xFF'; /* revert back */ + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + + + /** trying again without utf8 flag results in a normal token **/ + flags = 0; + lxs = mlxStringSession(str, flags); + assert(lxs != NULL); + /* read in the first token. This should read the first 256 bytes */ + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + strval = lxs->TokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now test again */ + result = mlxCopyToken(lxs, buf, BUF_SIZE); + str[strlen(str)-1] = '\0'; /* change for test */ + assert(strcmp(buf, str+1) == 0); + str[strlen(str)] = '\''; /* revert back */ + assert(lxs->TokType == MLX_TOK_STRING); + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_25.c b/centrallix-lib/tests/test_mtlexer_25.c new file mode 100644 index 000000000..11e6ba278 --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_25.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include + +long long +test(char** tname) + { + int i; + int iter; + int flags; + pLxSession lxs; + int alloc = 0; + int t; + char* strval; + char str[65536] = "'นปฐมกาล พระเจ้าทรงสร้างทุกสิ่งในฟ้าสวรรค์และโลก ขณะนั้นโลกยังไม่มีรูปทรงและว่างเปล่า " /* one really long line (398 UTF-8 chars). Each one is 3 bytes (but not the spaces)*/ + "ความมืดปกคลุมอยู่เหนือพื้นผิวของห้วงน้ำ \xFFพระวิญญาณของพระเจ้าทรงเคลื่อนไหวอยู่เหนือน้ำนั้น " /* contains 1165 btes */ + "และพระเจ้าตรัสว่า “จงเกิดความสว่าง” ความสว่างก็เกิดขึ้น พระเจ้าทรงเห็นว่าความสว่างนั้นดี " + "และทรงแยกความสว่างออกจากความมืด พระเจ้าทรงเรียกความสว่างว่า “วัน” และเรียกความมืดว่า " + "“คืน” เวลาเย็นและเวลาเช้าผ่านไป นี่เป็นวันที่หนึ่ง'"; + char tokstr[MLX_STRVAL]; + memcpy(tokstr, str+1, MLX_STRVAL-1); + tokstr[MLX_STRVAL-1] = '\0'; + char* buf; + + *tname = "mtlexer-25 test String Val with invalid utf-8 characters"; + + mssInitialize("system", "", "", 0, "test"); + iter = 20000; + for(i=0;iTokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now peform a copy into a buffer twice the size. Should enable invalid UTF8 to bypass the + * checks in next token, but should be caught by the check at the end of copy + */ + buf = mlxStringVal(lxs, &alloc); + assert(buf == NULL); + assert(alloc == 0); + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + + + /** trying again without utf8 flags results in a normal token **/ + flags = 0; + lxs = mlxStringSession(str, flags); + assert(lxs != NULL); + /* read in the first token. This should read the first 256 bytes */ + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + strval = lxs->TokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now test again */ + buf = mlxStringVal(lxs, &alloc); + assert(buf != NULL); + assert(alloc); + str[strlen(str)-1] = '\0'; /* change for test */ + assert(strcmp(buf, str+1) == 0); + str[strlen(str)] = '\''; /* revert back */ + assert(lxs->TokType == MLX_TOK_STRING); + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_26.c b/centrallix-lib/tests/test_mtlexer_26.c new file mode 100644 index 000000000..7d88e5a29 --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_26.c @@ -0,0 +1,167 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include +#include "util.h" + +void runTest(char** inputs, int ind, char* in, char* buf, pLxSession* plxs); +void runNoUTF8Test(char** inputs, int ind, char* in, char* buf, pLxSession* plxs); + +long long +test(char** tname) + { + int i; + int iter; + + pLxSession lxs; + char * padding = "'12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890" + "12345678901234567890123456789012345678901234567890"; /* 250 bytes (ignore the starting ' and NULL), 5 left*/ +/* bytes in TokString */ /* none */ /* 1 byte */ /* 2 byte */ /* 3 byte */ /* all */ + char* twoByte[] = {"12345рас'", "1234рас'", "", "", "123рас'"}; /* splits the 'р' */ + char* threeByte[] = {"12345分裂'", "1234分裂'", "123分裂'", "", "12分裂'"}; /* splits the '分' */ + char* fourByte[] = {"12345𝄞𝅘𝅥𝅘𝅥𝅮'", "1234𝄞𝅘𝅥𝅘𝅥𝅮'", "123𝄞𝅘𝅥𝅘𝅥𝅮'", "12𝄞𝅘𝅥𝅘𝅥𝅮'", "1𝄞𝅘𝅥𝅘𝅥𝅮'"}; /* splits the '𝄞' */ + char in[300]; + char buf[300]; + memcpy(in, padding, 251); + + *tname = "mtlexer-26 test internal buffers splitting utf-8"; + + mssInitialize("system", "", "", 0, "test"); + iter = 20000; + for(i=0;iFlags & MLX_F_INSTRING); + assert((*plxs)->TokString != NULL); + assert(memcmp((*plxs)->TokString, in+1, 255-(ind%4)) == 0); + assert((*plxs)->ValidateFn((*plxs)->TokString) == UTIL_VALID_CHAR); + + /* now copy to buffer */ + len = mlxCopyToken((*plxs), buf, 300); + assert(len == (250+strlen(inputs[ind])-1)); + assert(memcmp(in+1, buf, 250+strlen(inputs[ind]-2)) == 0); + assert((*plxs)->TokType == MLX_TOK_STRING); + assert(!((*plxs)->Flags & MLX_F_INSTRING)); + + switch(ind) + { + case 0: + case 4: + assert((*plxs)->TokString[255] == '\0'); + break; + case 1: + assert((*plxs)->TokString[254] == '\0'); + break; + case 2: + assert((*plxs)->TokString[253] == '\0'); + break; + case 3: + assert((*plxs)->TokString[252] == '\0'); + break; + default: + assert(0); + break; + } + + mlxCloseSession(*plxs); + return; + } + +void +runNoUTF8Test(char** inputs, int ind, char* in, char* buf, pLxSession* plxs) + { + int flags; + int t; + /** setup **/ + flags = 0; + memcpy(in+251, inputs[ind], strlen(inputs[ind])); + *plxs = mlxStringSession(in, flags); + assert(*plxs != NULL); + /* read in the first token. This should read the first 255 bytes */ + t = mlxNextToken(*plxs); + assert(t == MLX_TOK_STRING); + assert((*plxs)->Flags & MLX_F_INSTRING); + assert((*plxs)->TokString != NULL); + assert(memcmp((*plxs)->TokString, in+1, 255) == 0); /* leaves partial */ + if(ind%4 != 0) assert(verifyUTF8((*plxs)->TokString) != UTIL_VALID_CHAR); + + /* now copy to buffer */ + int len = mlxCopyToken((*plxs), buf, 300); + assert(len == (250+strlen(inputs[ind])-1)); + assert(memcmp(in+1, buf, 250+strlen(inputs[ind]-2)) == 0); + assert((*plxs)->TokType == MLX_TOK_STRING); + assert(!((*plxs)->Flags & MLX_F_INSTRING)); + assert((*plxs)->TokString[255] == '\0'); + + mlxCloseSession(*plxs); + return; + } diff --git a/centrallix-lib/tests/test_mtlexer_27.c b/centrallix-lib/tests/test_mtlexer_27.c new file mode 100644 index 000000000..e7f1b8bbb --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_27.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include +#include +#include + +long long +test(char** tname) + { + int i; + int iter; + int ind, max; + char cur; + + srand(time(NULL)); + + *tname = "mtlexer-27 test internal utf-8 character split detection"; + + iter = 50000; + for(i=0;i +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include +#include +#include + +long long +test(char** tname) + { + int i, j, iter; + int flags, result; + char* strings [] = {":", "(", ")", "/", "$", "*", ",", "#", ";", "\0", "-", + "-12", "+234", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; + int tokenTypes[] = {MLX_TOK_COLON, MLX_TOK_OPENPAREN, MLX_TOK_CLOSEPAREN, + MLX_TOK_SLASH, MLX_TOK_DOLLAR, MLX_TOK_ASTERISK, + MLX_TOK_COMMA, MLX_TOK_POUND, MLX_TOK_SEMICOLON, + MLX_TOK_ERROR, MLX_TOK_MINUS, MLX_TOK_INTEGER, + MLX_TOK_INTEGER, MLX_TOK_INTEGER, MLX_TOK_INTEGER, + MLX_TOK_INTEGER, MLX_TOK_INTEGER, MLX_TOK_INTEGER, + MLX_TOK_INTEGER, MLX_TOK_INTEGER, MLX_TOK_INTEGER, + MLX_TOK_INTEGER, MLX_TOK_INTEGER, MLX_TOK_INTEGER}; + int numTok = 23; + pLxSession lxs; + srand(time(NULL)); + + *tname = "mtlexer-28 test interactions between strchr and NULL"; + + iter = 5000; + for(i=0;iTokType == tokenTypes[j]); + assert(strcmp(lxs->TokString, strings[j]) == 0); + mlxCloseSession(lxs); + } + + /** utf-8 **/ + for(j = 0 ; j < numTok ; j++) + { + flags = MLX_F_ALLOWNUL; + lxs = mlxStringSession(strings[j], flags | MLX_F_ENFORCEUTF8); + assert(lxs != NULL); + + result = mlxNextToken(lxs); + assert(result == tokenTypes[j]); + assert(lxs->TokType == tokenTypes[j]); + assert(strcmp(lxs->TokString, strings[j]) == 0); + mlxCloseSession(lxs); + } + + /** ascii **/ + for(j = 0 ; j < numTok ; j++) + { + /** normal **/ + flags = MLX_F_ALLOWNUL; + lxs = mlxStringSession(strings[j], flags | MLX_F_ENFORCEASCII); + assert(lxs != NULL); + + result = mlxNextToken(lxs); + assert(result == tokenTypes[j]); + assert(lxs->TokType == tokenTypes[j]); + assert(strcmp(lxs->TokString, strings[j]) == 0); + mlxCloseSession(lxs); + } + + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_29.c b/centrallix-lib/tests/test_mtlexer_29.c new file mode 100644 index 000000000..f0774934d --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_29.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include + +long long +test(char** tname) + { + int i; + int iter; + int flags; + pLxSession lxs; + int t; + char* strval; + int j; + int strcnt; + char str[65536] = "'these' 'are' 'some' 'mostly' 'valid' '\xFFwords' 'for' 'testing'"; + int n_tok = 8; + char* tokstr[8] = {"these", "are", "some", "mostly", "valid", "\xFFwords", "for", "testing"}; + int toktype[8] = {MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_STRING, MLX_TOK_ERROR, MLX_TOK_ERROR, MLX_TOK_ERROR}; + + *tname = "mtlexer-29 test strings with invalid ascii characters"; + + mssInitialize("system", "", "", 0, "test"); + iter = 200000; + for(i=0;i +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include +#include +#include "util.h" + +long long +test(char** tname) + { + int i, j; + int iter; + int flags; + int result; + pLxSession lxs; + char* fileNames = {"./file /folder/another/file.ext ./localFile /anotherOne /yetStillMore /short/path.c " + "/test /aConsiderablyLongerFileName /invalid\xFFFileName /an/extra/path"}; + char* valid_fileNames = {"./file /folder/another/file.ext ./localFile /anotherOne /yetStillMore /short/path.c " + "/test /aConsiderablyLongerFileName /validFileName /an/extra/path"}; + *tname = "mtlexer-30 Test valid and invalid ASCII file names"; + + mssInitialize("system", "", "", 0, "test"); + iter = 20000; + for(i=0;iTokType == MLX_TOK_FILENAME); + assert(memcmp(valid_fileNames+offset, lxs->TokString, strlen(lxs->TokString)) == 0); + assert(verifyASCII(lxs->TokString) == UTIL_VALID_CHAR); + offset += strlen(lxs->TokString) + 1; /* move past the space as well */ + } + result = mlxNextToken(lxs); + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + + /** invalid set should locate invalid **/ + flags = MLX_F_FILENAMES; + lxs = mlxStringSession(fileNames, flags | MLX_F_ENFORCEASCII); + assert(lxs != NULL); + offset = 0; + for(j = 0 ; j < 8 ; j++) + { + result = mlxNextToken(lxs); + assert(result == MLX_TOK_FILENAME); + assert(lxs->TokType == MLX_TOK_FILENAME); + assert(memcmp(valid_fileNames+offset, lxs->TokString, strlen(lxs->TokString)) == 0); + offset += strlen(lxs->TokString) + 1; /* move past the space as well */ + } + + result = mlxNextToken(lxs); + assert(lxs->TokType == MLX_TOK_ERROR); + assert(strcmp(lxs->TokString, "/invalid\xFFFileName") == 0); + mlxCloseSession(lxs); + + + /** test without ascii flag (and therefore without a validate); should pass all junk **/ + flags = MLX_F_FILENAMES; + lxs = mlxStringSession(fileNames, flags); + assert(lxs != NULL); + offset = 0; + for(j = 0 ; j < 10 ; j++) + { + result = mlxNextToken(lxs); + assert(result == MLX_TOK_FILENAME); + assert(lxs->TokType == MLX_TOK_FILENAME); + } + result = mlxNextToken(lxs); + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + } + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_31.c b/centrallix-lib/tests/test_mtlexer_31.c new file mode 100644 index 000000000..ded9ebe4b --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_31.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include + +long long +test(char** tname) + { + int BUF_SIZE = 2000; + int i; + int iter; + int flags; + pLxSession lxs; + int t; + char* strval; + /* one really long line (1165 btyes). */ + char str[65536] = "'orem ipsum dolor sit amet, consectetur adipiscing elit. " + "Morbi ac vestibulum lectus. Quisque at felis sit amet augue " + "luctus dictum eget eu justo. Nulla facilisi. In gravida, " + "mauris quis ullamcorper pulvinar, leo turpis gravida diam, " + "quis dapibus nisl dui ac libero. Cras a accumsan odi\xFF. " + "Maecenas pharetra turpis egestas lectus efficitur fringilla. " + "Nunc quis interdum odio, non rutrum magna. Maecenas nisi " + "odio, rutrum vel sem non, blandit ultrices dolor. Proin et " + "pharetra justo. Vestibulum risus nunc, fermentum a ex eu, " + "tristique posuere erat. Phasellus semper tempus lobortis. " + "Suspendisse rhoncus, turpis in cursus finibus, lectus quam " + "ornare ante, sed scelerisque elit nisl eget elit. Integer id " + "molestie leo. Ut in tortor risus. Suspendisse nec elit erat. " + "Praesent sapien dui, venenatis at dignissim et, finibus vel " + "enim. Quisque aliquam ultricies metus, id consectetur lorem. " + "Pellentesque habitant morbi tristique senectus et netus et " + "malesuada fames ac turpis egestas. Nam commodo faucibus massa, " + "id mollis nisl feugiat fringilla. Maecenas pretium tristique " + "ligula, aliquet dignissim orci laoreet ac. Quisque turpis tortor," + "pretium in sem eu, sagittis morbi. '"; + char tokstr[MLX_STRVAL]; + memcpy(tokstr, str+1, MLX_STRVAL-1); + tokstr[MLX_STRVAL-1] = '\0'; + char buf[BUF_SIZE]; + + *tname = "mtlexer-31 test Copy Token with invalid ascii characters"; + + mssInitialize("system", "", "", 0, "test"); + iter = 50000; + for(i=0;iTokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now peform a copy into a buffer twice the size. Should enable invalid ascii to bypass the + * checks in next token, but should be caught by the check at the end of copy + */ + int result = mlxCopyToken(lxs, buf, BUF_SIZE); + str[result+1] = '\0'; /* change for test */ + assert(result == strlen(str)-1); /* -1 since ' is not included */ + assert(strcmp(buf, str+1) == 0); + str[result+1] = '\xFF'; /* revert back */ + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + + + /** trying again without ascii flag results in a normal token **/ + flags = 0; + lxs = mlxStringSession(str, flags); + assert(lxs != NULL); + /* read in the first token. This should read the first 256 bytes */ + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + strval = lxs->TokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now test again */ + result = mlxCopyToken(lxs, buf, BUF_SIZE); + str[strlen(str)-1] = '\0'; /* change for test */ + assert(strcmp(buf, str+1) == 0); + str[strlen(str)] = '\''; /* revert back */ + assert(lxs->TokType == MLX_TOK_STRING); + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_32.c b/centrallix-lib/tests/test_mtlexer_32.c new file mode 100644 index 000000000..c8bb9e55f --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_32.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include "mtsession.h" +#include "mtlexer.h" +#include + +long long +test(char** tname) + { + int i; + int iter; + int flags; + pLxSession lxs; + int alloc = 0; + int t; + char* strval; + /* one really long line (1165 btyes). */ + char str[65536] = "'orem ipsum dolor sit amet, consectetur adipiscing elit. " + "Morbi ac vestibulum lectus. Quisque at felis sit amet augue " + "luctus dictum eget eu justo. Nulla facilisi. In gravida, " + "mauris quis ullamcorper pulvinar, leo turpis gravida diam, " + "quis dapibus nisl dui ac libero. Cras a accumsan odi\xFF. " + "Maecenas pharetra turpis egestas lectus efficitur fringilla. " + "Nunc quis interdum odio, non rutrum magna. Maecenas nisi " + "odio, rutrum vel sem non, blandit ultrices dolor. Proin et " + "pharetra justo. Vestibulum risus nunc, fermentum a ex eu, " + "tristique posuere erat. Phasellus semper tempus lobortis. " + "Suspendisse rhoncus, turpis in cursus finibus, lectus quam " + "ornare ante, sed scelerisque elit nisl eget elit. Integer id " + "molestie leo. Ut in tortor risus. Suspendisse nec elit erat. " + "Praesent sapien dui, venenatis at dignissim et, finibus vel " + "enim. Quisque aliquam ultricies metus, id consectetur lorem. " + "Pellentesque habitant morbi tristique senectus et netus et " + "malesuada fames ac turpis egestas. Nam commodo faucibus massa, " + "id mollis nisl feugiat fringilla. Maecenas pretium tristique " + "ligula, aliquet dignissim orci laoreet ac. Quisque turpis tortor," + "pretium in sem eu, sagittis morbi. '"; + char tokstr[MLX_STRVAL]; + memcpy(tokstr, str+1, MLX_STRVAL-1); + tokstr[MLX_STRVAL-1] = '\0'; + char* buf; + + *tname = "mtlexer-32 test String Val with invalid ascii characters"; + + mssInitialize("system", "", "", 0, "test"); + iter = 20000; + for(i=0;iTokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now peform a copy into a buffer twice the size. Should enable invalid ascii to bypass the + * checks in next token, but should be caught by the check at the end of copy + */ + buf = mlxStringVal(lxs, &alloc); + assert(buf == NULL); + assert(alloc == 0); + assert(lxs->TokType == MLX_TOK_ERROR); + mlxCloseSession(lxs); + + + /** trying again without ascii flags results in a normal token **/ + flags = 0; + lxs = mlxStringSession(str, flags); + assert(lxs != NULL); + /* read in the first token. This should read the first 256 bytes */ + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + strval = lxs->TokString; + assert(strval != NULL); + assert(strcmp(strval,tokstr) == 0); + /* now test again */ + buf = mlxStringVal(lxs, &alloc); + assert(buf != NULL); + assert(alloc); + str[strlen(str)-1] = '\0'; /* change for test */ + assert(strcmp(buf, str+1) == 0); + str[strlen(str)] = '\''; /* revert back */ + assert(lxs->TokType == MLX_TOK_STRING); + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_33.c b/centrallix-lib/tests/test_mtlexer_33.c new file mode 100644 index 000000000..7380758be --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_33.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include "newmalloc.h" +#include "mtsession.h" +#include "mtlexer.h" +#include + +long long +test(char** tname) + { + const int NUM_TOK = 4; + int i; + int j; + int t; + int n; + int iter; + pLxSession lxs; + pFile fd; + char buf[256]; + char* aBuf; + int alloc; + + *tname = "mtlexer-33 Read long utf-8 tokens from a file"; + + mssInitialize("system", "", "", 0, "test"); + + iter = 60000; + + for(i=0;iTokString, "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾\xF0\x93\x80") == 0); + aBuf = mlxStringVal(lxs, &alloc); + assert(strcmp(aBuf, "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿" + "𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿") == 0); + nmSysFree(aBuf); + + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + mlxCloseSession(lxs); + assert(n >= 0); + buf[n] = '\0'; + fdClose(fd, 0); + + /** utf-8 **/ + fd = fdOpen("tests/test_mtlexer_33.txt", O_RDONLY, 0600); + assert(fd != NULL); + lxs = mlxOpenSession(fd, MLX_F_EOF | MLX_F_LINEONLY | MLX_F_NODISCARD | MLX_F_ENFORCEUTF8); + assert(lxs != NULL); + for(j=0 ; j < NUM_TOK ; j++) + { + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + } + assert(strcmp(lxs->TokString, "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾") == 0); + aBuf = mlxStringVal(lxs, &alloc); + assert(strcmp(aBuf, "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿" + "𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿") == 0); + nmSysFree(aBuf); + + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + mlxCloseSession(lxs); + n = fdRead(fd, buf, sizeof(buf) - 1, 0, 0); + assert(n >= 0); + buf[n] = '\0'; + fdClose(fd, 0); + + /** ascii **/ + fd = fdOpen("tests/test_mtlexer_33_ASCII.txt", O_RDONLY, 0600); + assert(fd != NULL); + lxs = mlxOpenSession(fd, MLX_F_EOF | MLX_F_LINEONLY | MLX_F_NODISCARD | MLX_F_ENFORCEASCII); + assert(lxs != NULL); + for(j=0 ; j < NUM_TOK ; j++) + { + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + } + + assert(strcmp(lxs->TokString, "hid in mine heart, that I might not sin against thee. 119:12 Blessed art thou," + " O LORD: teach me thy statutes. 119:13 With my lips have I declared all the judgments of thy mouth. 119:" + "14 I have rejoiced in the way of thy testimonies, as much as in all riche") == 0); + aBuf = mlxStringVal(lxs, &alloc); + assert(strcmp(aBuf, "hid in mine heart, that I might not sin against thee. 119:12 Blessed art thou, O LORD: " + "teach me thy statutes. 119:13 With my lips have I declared all the judgments of thy mouth. 119:14 I " + "have rejoiced in the way of thy testimonies, as much as in all riches. 119:15 I will meditate in thy " + "precepts, and have respect unto thy ways. 119:16 I will delight myself in thy statutes: I will not forget" + " thy word. 119:17 Deal bountifully with thy servant, that I may live, and keep thy word. 119:18 Open thou" + " mine eyes, that I may behold wondrous things out of thy law.") == 0); + nmSysFree(aBuf); + + t = mlxNextToken(lxs); + assert(t == MLX_TOK_STRING); + mlxCloseSession(lxs); + n = fdRead(fd, buf, sizeof(buf) - 1, 0, 0); + assert(n >= 0); + buf[n] = '\0'; + fdClose(fd, 0); + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_mtlexer_33.txt b/centrallix-lib/tests/test_mtlexer_33.txt new file mode 100644 index 000000000..1afd297ae --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_33.txt @@ -0,0 +1,4 @@ +query select :name, * from object /tests/test4.json/実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +query select :name, * from object /tests/test4.json/実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 \ No newline at end of file diff --git a/centrallix-lib/tests/test_mtlexer_33_ASCII.txt b/centrallix-lib/tests/test_mtlexer_33_ASCII.txt new file mode 100644 index 000000000..09204c0d5 --- /dev/null +++ b/centrallix-lib/tests/test_mtlexer_33_ASCII.txt @@ -0,0 +1,4 @@ +119:1 Blessed are the undefiled in the way, who walk in the law of the LORD. 119:2 Blessed are they that keep his testimonies, and that seek him with the whole heart. 119:3 They also do no iniquity: they walk in his ways. 119:4 Thou hast commanded us to keep thy precepts diligently. +119:5 O that my ways were directed to keep thy statutes! 119:6 Then shall I not be ashamed, when I have respect unto all thy commandments. 119:7 I will praise thee with uprightness of heart, when I shall have learned thy righteous judgments. 119:8 I will keep thy statutes: O forsake me not utterly. +119:9 Wherewithal shall a young man cleanse his way? by taking heed thereto according to thy word. 119:10 With my whole heart have I sought thee: O let me not wander from thy commandments. 119:11 Thy word have I +hid in mine heart, that I might not sin against thee. 119:12 Blessed art thou, O LORD: teach me thy statutes. 119:13 With my lips have I declared all the judgments of thy mouth. 119:14 I have rejoiced in the way of thy testimonies, as much as in all riches. 119:15 I will meditate in thy precepts, and have respect unto thy ways. 119:16 I will delight myself in thy statutes: I will not forget thy word. 119:17 Deal bountifully with thy servant, that I may live, and keep thy word. 119:18 Open thou mine eyes, that I may behold wondrous things out of thy law. \ No newline at end of file diff --git a/centrallix-lib/tests/test_qprintf_00.c b/centrallix-lib/tests/test_qprintf_00.c index 939a6e9fb..ba2d41fc8 100644 --- a/centrallix-lib/tests/test_qprintf_00.c +++ b/centrallix-lib/tests/test_qprintf_00.c @@ -5,16 +5,24 @@ #include #include "qprintf.h" #include +#include long long test(char** tname) { int i; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = QPF_F_ENFORCE_UTF8; unsigned char buf[44]; - + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-00 constant string using snprintf()"; - iter = 200000; + setlocale(0, "en_US.UTF-8"); + iter = 2000000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,15 @@ test(char** tname) int i; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-01 constant string using qpfPrintf()"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,15 @@ test(char** tname) int i; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-02 constant string with truncation, qpfPrintf()"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,16 @@ test(char** tname) int i; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); *tname = "qprintf-03 constant string, 1char overflow, using qpfPrintf()"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,15 @@ test(char** tname) int i; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-04 empty string using qpfPrintf()"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include #include +#include #include "qprintf.h" #include +#include long long test(char** tname) { int i; int iter; + int rval; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-05 constant string into 0-sized buf using qpfPrintf()"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,15 @@ test(char** tname) int i; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-06 constant string into 1-sized buf using qpfPrintf()"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,15 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-07 %STR insertion in middle without overflow"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,15 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-08 %STR insertion at end without overflow"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,15 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); *tname = "qprintf-09 %STR insertion at beginning without overflow"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -14,6 +16,7 @@ test(char** tname) unsigned char buf[44]; *tname = "qprintf-10 compare with snprintf(), %s inserted"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include "util.h" +#include long long test(char** tname) @@ -12,8 +15,15 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-11 %STR insertion in middle with overflow after STR"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) @@ -12,8 +13,15 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-12 %STR insertion in middle with overflow in STR"; + setlocale(0, "en_US.UTF-8"); iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,14 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-13 %STR insertion in middle with overflow before STR"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,6 +14,7 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); *tname = "qprintf-14 %INT insertion in middle without overflow"; iter = 200000; @@ -39,6 +42,11 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 test not required; no characters involved */ + } return iter*4; diff --git a/centrallix-lib/tests/test_qprintf_15.c b/centrallix-lib/tests/test_qprintf_15.c index 49328270f..e40ff3507 100644 --- a/centrallix-lib/tests/test_qprintf_15.c +++ b/centrallix-lib/tests/test_qprintf_15.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,6 +14,7 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); *tname = "qprintf-15 %POS insertion in middle without overflow"; iter = 200000; @@ -39,6 +42,11 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 test not required for number insertion */ + } return iter*4; diff --git a/centrallix-lib/tests/test_qprintf_16.c b/centrallix-lib/tests/test_qprintf_16.c index 8b596b621..806d6a1bb 100644 --- a/centrallix-lib/tests/test_qprintf_16.c +++ b/centrallix-lib/tests/test_qprintf_16.c @@ -6,6 +6,8 @@ #include "qprintf.h" #include #include +#include "util.h" +#include long long test(char** tname) @@ -13,6 +15,7 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); *tname = "qprintf-16 %POS insertion without overflow, negative"; iter = 200000; @@ -26,20 +29,25 @@ test(char** tname) buf[2] = '\0'; buf[1] = 0xff; buf[0] = '\0'; - qpfPrintf(NULL, buf+4, 36, "Here is the integer: %POS...", -12345); - qpfPrintf(NULL, buf+4, 36, "Here is the integer: %POS...", -12345); - qpfPrintf(NULL, buf+4, 36, "Here is the integer: %POS...", -12345); - rval = qpfPrintf(NULL, buf+4, 36, "Here is the integer: %POS...", -12345); - assert(strlen(buf+4) <= 30); + qpfPrintf(NULL, (char *) buf+4, 36, "Here is the integer: %POS...", -12345); + qpfPrintf(NULL, (char *) buf+4, 36, "Here is the integer: %POS...", -12345); + qpfPrintf(NULL, (char *) buf+4, 36, "Here is the integer: %POS...", -12345); + rval = qpfPrintf(NULL, (char *) buf+4, 36, "Here is the integer: %POS...", -12345); + assert(strlen((char *) buf+4) <= 30); assert(rval == -EINVAL); assert(buf[43] == '\n'); - assert(buf[42] == '\0'); + assert(buf[42] == '\0'); assert(buf[41] == 0xff); assert(buf[40] == '\0'); assert(buf[3] == '\n'); assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8((char *) buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 test not required for number insertion */ + } return iter*4; diff --git a/centrallix-lib/tests/test_qprintf_17.c b/centrallix-lib/tests/test_qprintf_17.c index ae2f71248..e40663984 100644 --- a/centrallix-lib/tests/test_qprintf_17.c +++ b/centrallix-lib/tests/test_qprintf_17.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-17 %NSTR insertion in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-18 %NSTR insertion in middle with insert overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-19 %*STR insertion in middle with insert overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-20 %CHR insertion in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,6 +14,7 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); *tname = "qprintf-21 %DBL insertion in middle without overflow"; iter = 200000; @@ -39,6 +42,11 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 test not required; no characters involved */ + } return iter*4; diff --git a/centrallix-lib/tests/test_qprintf_22.c b/centrallix-lib/tests/test_qprintf_22.c index 9572ff44f..d5fc9773e 100644 --- a/centrallix-lib/tests/test_qprintf_22.c +++ b/centrallix-lib/tests/test_qprintf_22.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-22 %STR&NLEN in middle with insert overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-23 %STR&NLEN in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = QPF_F_ENFORCE_UTF8; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-24 %STR&*LEN in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-25 %STR&SYM in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) @@ -12,7 +13,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-26 %STR&SYM in middle with illegal symbol"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-27 %STR&ESCQ in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-28 %STR&ESCQ in middle with overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-29 %STR&ESCQ in middle with overflow of insert"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-30 %STR&ESCQ in middle with 2-overflow of insert"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-31 %STR&ESCQ&NLEN in middle less than LEN"; iter = 100000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-32 %STR&ESCQ&NLEN in middle eq to LEN"; iter = 100000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-33 %STR&ESCQ&NLEN in middle 1 greater than LEN"; iter = 100000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,8 +14,14 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; - + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; *tname = "qprintf-34 %STR&ESCQ&NLEN in middle 2 greater than LEN"; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + iter = 100000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-35 %STR&HTE in middle, no overflows"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE'.", ""); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE'.", ""); - rval = qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE'.", ""); + rval = qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE'.", ""); assert(!strcmp(buf+4, "HTML: '<b c="w">'.")); assert(rval == 34); assert(buf[43] == '\n'); @@ -39,8 +47,25 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 */ + rval = qpfPrintf(NULL, buf+4, 36, "超: '%STR&HTE'.", ""); + assert(strcmp(buf+4, "超: '<b c="€">'.") == 0); + assert(rval == 35); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_36.c b/centrallix-lib/tests/test_qprintf_36.c index 918605b62..ba9c700fb 100644 --- a/centrallix-lib/tests/test_qprintf_36.c +++ b/centrallix-lib/tests/test_qprintf_36.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-36 %STR&HTE in middle, overflow 1 char"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 36, "The HTML: '%STR&HTE'.", ""); - qpfPrintf(NULL, buf+4, 36, "The HTML: '%STR&HTE'.", ""); - rval = qpfPrintf(NULL, buf+4, 36, "The HTML: '%STR&HTE'.", ""); + qpfPrintf(session, buf+4, 36, "The HTML: '%STR&HTE'.", ""); + qpfPrintf(session, buf+4, 36, "The HTML: '%STR&HTE'.", ""); + qpfPrintf(session, buf+4, 36, "The HTML: '%STR&HTE'.", ""); + rval = qpfPrintf(session, buf+4, 36, "The HTML: '%STR&HTE'.", ""); assert(!strcmp(buf+4, "The HTML: '<b c="w"")); assert(rval == 38); assert(buf[39] == '\n'); @@ -41,8 +49,31 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 */ + rval = qpfPrintf(NULL, buf+4, 36, "超文: '%STR&HTE'.", ""); /* no split */ + assert(strcmp(buf+4, "超文: '<b c="€"") == 0); + assert(rval == 38); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[39] == '\n'); + assert(buf[38] == '\0'); + assert(buf[37] == 0xff); + assert(buf[36] == '\0'); + assert(buf[35] != '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + rval = qpfPrintf(NULL, buf+4, 36, "超文: '%STR&HTE'.", ""); /* split */ + assert(strcmp(buf+4, "超文: '<b c="€".") == 0); + assert(rval == 39); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_37.c b/centrallix-lib/tests/test_qprintf_37.c index 9ed221c07..747b27e4b 100644 --- a/centrallix-lib/tests/test_qprintf_37.c +++ b/centrallix-lib/tests/test_qprintf_37.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-37 %STR&HTE&NLEN in middle, len 1 greater"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&26LEN'.", ""); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&26LEN'.", ""); - rval = qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&26LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&26LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&26LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&26LEN'.", ""); + rval = qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&26LEN'.", ""); assert(!strcmp(buf+4, "HTML: '<b c="w">'.")); assert(rval == 34); assert(buf[43] == '\n'); @@ -39,8 +47,25 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 */ + rval = qpfPrintf(NULL, buf+4, 36, "超: '%STR&HTE&28LEN'.", ""); + assert(strcmp(buf+4, "超: '<b c="€">'.") == 0); + assert(rval == 35); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_38.c b/centrallix-lib/tests/test_qprintf_38.c index dcd9a679a..41579b587 100644 --- a/centrallix-lib/tests/test_qprintf_38.c +++ b/centrallix-lib/tests/test_qprintf_38.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-38 %STR&HTE&NLEN in middle, len equal"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&25LEN'.", ""); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&25LEN'.", ""); - rval = qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&25LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&25LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&25LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&25LEN'.", ""); + rval = qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&25LEN'.", ""); assert(!strcmp(buf+4, "HTML: '<b c="w">'.")); assert(rval == 34); assert(buf[43] == '\n'); @@ -39,8 +47,25 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 */ + rval = qpfPrintf(NULL, buf+4, 36, "超: '%STR&HTE&27LEN'.", ""); + assert(strcmp(buf+4, "超: '<b c="€">'.") == 0); + assert(rval == 35); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_39.c b/centrallix-lib/tests/test_qprintf_39.c index 796833f38..fa540bcde 100644 --- a/centrallix-lib/tests/test_qprintf_39.c +++ b/centrallix-lib/tests/test_qprintf_39.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-39 %STR&HTE&NLEN in middle, len 1 less"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&24LEN'.", ""); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&24LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&24LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&24LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&24LEN'.", ""); rval = qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&24LEN'.", ""); assert(!strcmp(buf+4, "HTML: '<b c="w"'.")); assert(rval == 30); + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 */ + rval = qpfPrintf(NULL, buf+4, 36, "超: '%STR&HTE&26LEN'.", ""); /* no char split */ + assert(strcmp(buf+4, "超: '<b c="€"'.") == 0); + assert(rval == 31); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(NULL, buf+4, 36, "超: '%STR&HTE&26LEN'.", ""); /* char split */ + assert(strcmp(buf+4, "超: '<b c="€".'.") == 0); + assert(rval == 32); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[43] == '\n'); assert(buf[42] == '\0'); assert(buf[41] == 0xff); @@ -41,6 +70,7 @@ test(char** tname) assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_40.c b/centrallix-lib/tests/test_qprintf_40.c index 8e5d47906..5cf17d858 100644 --- a/centrallix-lib/tests/test_qprintf_40.c +++ b/centrallix-lib/tests/test_qprintf_40.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-40 %STR&HTE&NLEN in middle, len 2 less"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&23LEN'.", ""); - qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&23LEN'.", ""); - rval = qpfPrintf(NULL, buf+4, 36, "HTML: '%STR&HTE&23LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&23LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&23LEN'.", ""); + qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&23LEN'.", ""); + rval = qpfPrintf(session, buf+4, 36, "HTML: '%STR&HTE&23LEN'.", ""); assert(!strcmp(buf+4, "HTML: '<b c="w"'.")); assert(rval == 30); assert(buf[43] == '\n'); @@ -39,8 +47,29 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 */ + rval = qpfPrintf(NULL, buf+4, 36, "超: '%STR&HTE&25LEN'.", ""); + assert(strcmp(buf+4, "超: '<b c="€"'.") == 0); /* no char split */ + assert(rval == 31); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(NULL, buf+4, 36, "超: '%STR&HTE&25LEN'.", ""); + assert(strcmp(buf+4, "超: '<b c="€"'.") == 0); /* char split */ + assert(rval == 31); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_41.c b/centrallix-lib/tests/test_qprintf_41.c index 4725bad1a..93b6e89b1 100644 --- a/centrallix-lib/tests/test_qprintf_41.c +++ b/centrallix-lib/tests/test_qprintf_41.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-41 %STR&HEX in middle, no overflows"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 36, "Encode: '%STR&HEX'.", ""); - qpfPrintf(NULL, buf+4, 36, "Encode: '%STR&HEX'.", ""); - rval = qpfPrintf(NULL, buf+4, 36, "Encode: '%STR&HEX'.", ""); + qpfPrintf(session, buf+4, 36, "Encode: '%STR&HEX'.", ""); + qpfPrintf(session, buf+4, 36, "Encode: '%STR&HEX'.", ""); + qpfPrintf(session, buf+4, 36, "Encode: '%STR&HEX'.", ""); + rval = qpfPrintf(session, buf+4, 36, "Encode: '%STR&HEX'.", ""); assert(!strcmp(buf+4, "Encode: '3c6220633d2277223e'.")); assert(rval == 29); assert(buf[36] == '\n'); @@ -39,8 +47,25 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /* UTF-8 */ + rval = qpfPrintf(NULL, buf+4, 36, "编码 %STR&HEX.", "<编=\"w\">"); // € + assert(strcmp(buf+4, "编码 3ce7bc963d2277223e.") == 0); // 3c62205c22e282ac5c223e + assert(rval == 26); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[36] == '\n'); + assert(buf[35] == '\0'); + assert(buf[34] == 0xff); + assert(buf[33] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_42.c b/centrallix-lib/tests/test_qprintf_42.c index 8fd6528f5..1eb82b99e 100644 --- a/centrallix-lib/tests/test_qprintf_42.c +++ b/centrallix-lib/tests/test_qprintf_42.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,15 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession asciiSes, utf8Ses; + utf8Ses = nmSysMalloc(sizeof(QPSession)); + utf8Ses->Flags = QPF_F_ENFORCE_UTF8; + asciiSes = nmSysMalloc(sizeof(QPSession)); + asciiSes->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-42 %STR&HEX at end, overflow(1) in insert"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 26, "Encode: %STR&HEX", ""); - qpfPrintf(NULL, buf+4, 26, "Encode: %STR&HEX", ""); - rval = qpfPrintf(NULL, buf+4, 26, "Encode: %STR&HEX", ""); + qpfPrintf(asciiSes, buf+4, 26, "Encode: %STR&HEX", ""); + qpfPrintf(asciiSes, buf+4, 26, "Encode: %STR&HEX", ""); + qpfPrintf(asciiSes, buf+4, 26, "Encode: %STR&HEX", ""); + rval = qpfPrintf(asciiSes, buf+4, 26, "Encode: %STR&HEX", ""); assert(!strcmp(buf+4, "Encode: 3c6220633d227722")); assert(rval == 26); assert(buf[32] == '\n'); @@ -43,8 +53,91 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); - } + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** UTF-8 **/ + buf[43] = '\n'; + buf[42] = '\0'; + buf[41] = 0xff; + buf[40] = '\0'; + + /** should chop off last full char despite being able to fit the first byte **/ + /** 2 byte chars **/ + rval = qpfPrintf(NULL, buf+4, 36, "код: %STR&HEX", "Test тест"); /* fits */ + assert(strcmp(buf+4, "код: 5465737420d182d0b5d181d182") == 0); + assert(rval == 34); + assert(utf8Ses->Errors == 0); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(utf8Ses, buf+4, 36, "код: %STR&HEX", "Test: тест"); /* 1 byte over */ + assert(strcmp(buf+4, "код: 546573743a20d182d0b5d181") == 0); + assert(rval == 36); + assert(utf8Ses->Errors == QPF_ERR_T_BUFOVERFLOW); + utf8Ses->Errors = 0; + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** 3 byte chars **/ + rval = qpfPrintf(utf8Ses, buf+4, 36, "编码: %STR&HEX", "Testing测试"); /* fits */ + assert(strcmp(buf+4, "编码: 54657374696e67e6b58be8af95") == 0); + assert(rval == 34); + assert(utf8Ses->Errors == 0); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(utf8Ses, buf+4, 36, "编码: %STR&HEX", "Testing:测试"); /* 1 byte over */ + assert(strcmp(buf+4, "编码: 54657374696e673ae6b58b") == 0); + assert(rval == 36); + assert(utf8Ses->Errors == QPF_ERR_T_BUFOVERFLOW); + utf8Ses->Errors = 0; + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(utf8Ses, buf+4, 36, "编码: %STR&HEX", "Testing: 测试"); /* 2 bytes over */ + assert(strcmp(buf+4, "编码: 54657374696e673a20e6b58b") == 0); + assert(rval == 38); + assert(utf8Ses->Errors == QPF_ERR_T_BUFOVERFLOW); + utf8Ses->Errors = 0; + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** 4 byte chars **/ + rval = qpfPrintf(utf8Ses, buf+4, 36, "𓅅𓂀 %STR&HEX", "Test 𓁳𓀒"); /* fits */ + assert(strcmp(buf+4, "𓅅𓂀 5465737420f09381b3f0938092") == 0); + assert(rval == 35); + assert(utf8Ses->Errors == 0); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(utf8Ses, buf+4, 36, "𓅅𓂀: %STR&HEX", "Test 𓁳𓀒"); /* 1 byte over */ + assert(strcmp(buf+4, "𓅅𓂀: 5465737420f09381b3") == 0); + assert(rval == 36); + assert(utf8Ses->Errors == QPF_ERR_T_BUFOVERFLOW); + utf8Ses->Errors = 0; + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(utf8Ses, buf+4, 36, "𓅅𓂀 %STR&HEX", "Test: 𓁳𓀒"); /* 2 bytes over */ + assert(strcmp(buf+4, "𓅅𓂀 546573743a20f09381b3") == 0); + assert(rval == 37); + assert(utf8Ses->Errors == QPF_ERR_T_BUFOVERFLOW); + utf8Ses->Errors = 0; + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + rval = qpfPrintf(utf8Ses, buf+4, 36, "𓅅𓂀: %STR&HEX", "Test: 𓁳𓀒"); /* 3 bytes over */ + assert(strcmp(buf+4, "𓅅𓂀: 546573743a20f09381b3") == 0); + assert(rval == 38); + assert(utf8Ses->Errors == QPF_ERR_T_BUFOVERFLOW); + utf8Ses->Errors = 0; + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** can split if no enforce **/ + rval = qpfPrintf(asciiSes, buf+4, 36, "код: %STR&HEX", "Test: тест"); /* cuts off 1 byte */ + assert(strcmp(buf+4, "код: 546573743a20d182d0b5d181d1") == 0); + assert(rval == 36); + assert(asciiSes->Errors == QPF_ERR_T_BUFOVERFLOW); /* detects overflow, but allows split */ + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); /* invalid char is hex encoded, so passes */ + + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + } + nmSysFree(asciiSes); + nmSysFree(utf8Ses); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_43.c b/centrallix-lib/tests/test_qprintf_43.c index 5446ea559..273cef07e 100644 --- a/centrallix-lib/tests/test_qprintf_43.c +++ b/centrallix-lib/tests/test_qprintf_43.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-43 %STR&HEX at end, overflow(2) in insert"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 25, "Encode: %STR&HEX", ""); - qpfPrintf(NULL, buf+4, 25, "Encode: %STR&HEX", ""); - rval = qpfPrintf(NULL, buf+4, 25, "Encode: %STR&HEX", ""); + qpfPrintf(session, buf+4, 25, "Encode: %STR&HEX", ""); + qpfPrintf(session, buf+4, 25, "Encode: %STR&HEX", ""); + qpfPrintf(session, buf+4, 25, "Encode: %STR&HEX", ""); + rval = qpfPrintf(session, buf+4, 25, "Encode: %STR&HEX", ""); assert(!strcmp(buf+4, "Encode: 3c6220633d227722")); assert(rval == 26); assert(buf[32] == '\n'); @@ -43,8 +51,27 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** UTF-8 **/ + rval = qpfPrintf(NULL, buf+4, 25, "编码: %STR&HEX", ""); + assert(strcmp(buf+4, "编码: ")); + assert(rval == 26); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[32] == '\n'); + assert(buf[31] == '\0'); + assert(buf[30] == 0xff); + assert(buf[29] == '\0'); + assert(buf[28] == '\0'); + assert(buf[27] != '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_44.c b/centrallix-lib/tests/test_qprintf_44.c index e5170f58e..01ad28c18 100644 --- a/centrallix-lib/tests/test_qprintf_44.c +++ b/centrallix-lib/tests/test_qprintf_44.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-44 %STR&HEX in middle, overflow(1) post-insert"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 26, "Enc: %STR&HEX...", ""); - qpfPrintf(NULL, buf+4, 26, "Enc: %STR&HEX...", ""); - rval = qpfPrintf(NULL, buf+4, 26, "Enc: %STR&HEX...", ""); + qpfPrintf(session, buf+4, 26, "Enc: %STR&HEX...", ""); + qpfPrintf(session, buf+4, 26, "Enc: %STR&HEX...", ""); + qpfPrintf(session, buf+4, 26, "Enc: %STR&HEX...", ""); + rval = qpfPrintf(session, buf+4, 26, "Enc: %STR&HEX...", ""); assert(!strcmp(buf+4, "Enc: 3c6220633d2277223e..")); assert(rval == 26); assert(buf[32] == '\n'); @@ -43,8 +51,28 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); - } + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + /* UTF-8 */ + + rval = qpfPrintf(NULL, buf+4, 26, "编: %STR&HEX...", ""); + assert(strcmp(buf+4, "编: 3c6220633d2277223e..") == 0); + assert(rval == 26); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + assert(buf[32] == '\n'); + assert(buf[31] == '\0'); + assert(buf[30] == 0xff); + assert(buf[29] == '\0'); + assert(buf[28] != '\0'); + assert(buf[27] != '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + } + + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_45.c b/centrallix-lib/tests/test_qprintf_45.c index f9ee5fa85..2394ebb5a 100644 --- a/centrallix-lib/tests/test_qprintf_45.c +++ b/centrallix-lib/tests/test_qprintf_45.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-45 %STR&HEX&NLEN in middle, no overflow"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&18LEN...", ""); - qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&18LEN...", ""); - rval = qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&18LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&18LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&18LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&18LEN...", ""); + rval = qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&18LEN...", ""); assert(!strcmp(buf+4, "Enc: 3c6220633d2277223e...")); assert(rval == 26); assert(buf[33] == '\n'); @@ -43,8 +51,28 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** UTF-8 **/ + qpfPrintf(NULL, buf+4, 27, "编: %STR&HEX&18LEN...", ""); + rval = qpfPrintf(NULL, buf+4, 27, "编: %STR&HEX&18LEN...", ""); + assert(strcmp(buf+4, "编: 3c6220633d2277223e...") == 0); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(rval == 26); + assert(buf[33] == '\n'); + assert(buf[32] == '\0'); + assert(buf[31] == 0xff); + assert(buf[30] == '\0'); + assert(buf[29] != '\0'); + assert(buf[28] != '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_46.c b/centrallix-lib/tests/test_qprintf_46.c index 4d4739ca6..204bafa67 100644 --- a/centrallix-lib/tests/test_qprintf_46.c +++ b/centrallix-lib/tests/test_qprintf_46.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-46 %STR&HEX&NLEN in middle, insert overflow(1)"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&17LEN...", ""); - qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&17LEN...", ""); - rval = qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&17LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&17LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&17LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&17LEN...", ""); + rval = qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&17LEN...", ""); assert(!strcmp(buf+4, "Enc: 3c6220633d227722...")); assert(rval == 24); + assert(buf[31] == '\n'); + assert(buf[30] == '\0'); + assert(buf[29] == 0xff); + assert(buf[28] == '\0'); + assert(buf[27] != '\0'); + assert(buf[26] != '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** UTF-8 **/ + + qpfPrintf(NULL, buf+4, 27, "编: %STR&HEX&17LEN...", ""); + rval = qpfPrintf(NULL, buf+4, 27, "编: %STR&HEX&17LEN...", ""); + assert(strcmp(buf+4, "编: 3c6220633d227722...") == 0); + assert(rval == 24); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[31] == '\n'); assert(buf[30] == '\0'); assert(buf[29] == 0xff); @@ -45,6 +75,7 @@ test(char** tname) assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_47.c b/centrallix-lib/tests/test_qprintf_47.c index 21e4b5278..b2d7766e7 100644 --- a/centrallix-lib/tests/test_qprintf_47.c +++ b/centrallix-lib/tests/test_qprintf_47.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-47 %STR&HEX&NLEN in middle, insert overflow(2)"; iter = 100000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&16LEN...", ""); - qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&16LEN...", ""); - rval = qpfPrintf(NULL, buf+4, 27, "Enc: %STR&HEX&16LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&16LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&16LEN...", ""); + qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&16LEN...", ""); + rval = qpfPrintf(session, buf+4, 27, "Enc: %STR&HEX&16LEN...", ""); assert(!strcmp(buf+4, "Enc: 3c6220633d227722...")); assert(rval == 24); + assert(buf[31] == '\n'); + assert(buf[30] == '\0'); + assert(buf[29] == 0xff); + assert(buf[28] == '\0'); + assert(buf[27] != '\0'); + assert(buf[26] != '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** UTF-8 **/ + + qpfPrintf(NULL, buf+4, 27, "编: %STR&HEX&16LEN...", ""); + + rval = qpfPrintf(NULL, buf+4, 27, "编: %STR&HEX&16LEN...", ""); + assert(strcmp(buf+4, "编: 3c6220633d227722...") == 0); + assert(rval == 24); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[31] == '\n'); assert(buf[30] == '\0'); assert(buf[29] == 0xff); @@ -45,6 +76,7 @@ test(char** tname) assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_48.c b/centrallix-lib/tests/test_qprintf_48.c index 93c55728a..f8f999b9d 100644 --- a/centrallix-lib/tests/test_qprintf_48.c +++ b/centrallix-lib/tests/test_qprintf_48.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-48 %STR" in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-49 %STR&DQUOT in middle without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = QPF_F_ENFORCE_UTF8; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-50 %STR" at end without overflow"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) @@ -12,6 +13,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-51 %STR" at end with overflow(1)"; iter = 200000; @@ -27,10 +35,10 @@ test(char** tname) buf[2] = '\0'; buf[1] = 0xff; buf[0] = '\0'; - qpfPrintf(NULL, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); - qpfPrintf(NULL, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); - qpfPrintf(NULL, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); - rval = qpfPrintf(NULL, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); + qpfPrintf(session, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); + qpfPrintf(session, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); + qpfPrintf(session, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); + rval = qpfPrintf(session, buf+4, 32, "Here is the str...: %STR"", "\"ain't\""); assert(!strcmp(buf+4, "Here is the str...: '\\\"ain\\'t'")); assert(rval == 32); assert(buf[39] == '\n'); @@ -43,8 +51,31 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + /** UTF-8 **/ + rval = qpfPrintf(NULL, buf+4, 32, "Str...: %STR"", "\"சோத.சோத.\""); + assert(strcmp(buf+4, "Str...: '\\\"சோத.சோத'") == 0); + assert(rval == 33); + assert(strlen(buf+4) == 31); + + rval = qpfPrintf(NULL, buf+4, 32, "Str...: %STR"", "\"சோத..சோத\""); + assert(strcmp(buf+4, "Str...: '\\\"சோத..சோ'") == 0); + assert(rval == 33); + assert(strlen(buf+4) == 29); /*added 1 char, which cut off 3 bytes (to not split char) so 2 shorter */ + + assert(buf[39] == '\n'); + assert(buf[38] == '\0'); + assert(buf[37] == 0xff); + assert(buf[36] == '\0'); + assert(buf[35] == '\0'); + assert(buf[34] != '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_52.c b/centrallix-lib/tests/test_qprintf_52.c index 16cbbd6bc..29170a8c7 100644 --- a/centrallix-lib/tests/test_qprintf_52.c +++ b/centrallix-lib/tests/test_qprintf_52.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,6 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-52 %STR" at end with overflow(2)"; iter = 200000; @@ -27,12 +36,31 @@ test(char** tname) buf[2] = '\0'; buf[1] = 0xff; buf[0] = '\0'; - qpfPrintf(NULL, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); - qpfPrintf(NULL, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); - qpfPrintf(NULL, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); - rval = qpfPrintf(NULL, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); + qpfPrintf(session, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); + qpfPrintf(session, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); + qpfPrintf(session, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); + rval = qpfPrintf(session, buf+4, 31, "Here is the str...: %STR"", "\"ain't\""); assert(!strcmp(buf+4, "Here is the str...: '\\\"ain\\'t'")); - assert(rval == 32); + assert(rval == 32); + assert(buf[39] == '\n'); + assert(buf[38] == '\0'); + assert(buf[37] == 0xff); + assert(buf[36] == '\0'); + assert(buf[35] == '\0'); + assert(buf[34] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + qpfPrintf(NULL, buf+4, 31, "Str...: %STR"", "சோத"); + rval = qpfPrintf(NULL, buf+4, 31, "Str...: %STR"", "............コード"); + assert(strcmp(buf+4, "Str...: '............コー'") == 0); + assert(rval == 31); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[39] == '\n'); assert(buf[38] == '\0'); assert(buf[37] == 0xff); @@ -45,6 +73,7 @@ test(char** tname) assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_53.c b/centrallix-lib/tests/test_qprintf_53.c index d94c0b110..9b9d0be4d 100644 --- a/centrallix-lib/tests/test_qprintf_53.c +++ b/centrallix-lib/tests/test_qprintf_53.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-53 Bugtest:   following %STR&HTE"; iter = 200000; for(i=0;i"); - qpfPrintf(NULL, buf+4, 35, "Here is the str: %STR&HTE ", ""); - qpfPrintf(NULL, buf+4, 35, "Here is the str: %STR&HTE ", ""); - rval = qpfPrintf(NULL, buf+4, 35, "Here is the str: %STR&HTE ", ""); + qpfPrintf(session, buf+4, 35, "Here is the str: %STR&HTE ", ""); + qpfPrintf(session, buf+4, 35, "Here is the str: %STR&HTE ", ""); + qpfPrintf(session, buf+4, 35, "Here is the str: %STR&HTE ", ""); + rval = qpfPrintf(session, buf+4, 35, "Here is the str: %STR&HTE ", ""); assert(!strcmp(buf+4, "Here is the str: <tag> ")); assert(rval == 34); + assert(buf[41] == '\n'); + assert(buf[40] == '\0'); + assert(buf[39] == 0xff); + assert(buf[38] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + /** UTF-8 **/ + qpfPrintf(NULL, buf+4, 35, "Str: %STR&HTE ", "<சோத>"); + rval = qpfPrintf(NULL, buf+4, 35, "Str: %STR&HTE ", "<சோத>"); + assert(strcmp(buf+4, "Str: <சோத> ") == 0); + assert(rval == 28); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[41] == '\n'); assert(buf[40] == '\0'); assert(buf[39] == 0xff); @@ -41,6 +68,7 @@ test(char** tname) assert(buf[0] == '\0'); } + nmSysFree(session); return iter*4; } diff --git a/centrallix-lib/tests/test_qprintf_54.c b/centrallix-lib/tests/test_qprintf_54.c index 3e6cc7e79..f05cb8172 100644 --- a/centrallix-lib/tests/test_qprintf_54.c +++ b/centrallix-lib/tests/test_qprintf_54.c @@ -5,14 +5,22 @@ #include #include "qprintf.h" #include +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-54 Bugtest: %[ %] with static data"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-55 %STR&FILE valid filename"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-56 %STR&FILE various invalid filenames"; iter = 100000; for(i=0;i 0); + + assert(buf[35] == '\n'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + } return iter*7; diff --git a/centrallix-lib/tests/test_qprintf_57.c b/centrallix-lib/tests/test_qprintf_57.c index bf57ff87b..9335fa627 100644 --- a/centrallix-lib/tests/test_qprintf_57.c +++ b/centrallix-lib/tests/test_qprintf_57.c @@ -5,14 +5,23 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-57 %nSTR&FILE tests with fixed length insert"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-58 %STR&PATH valid pathname"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-59 %STR&PATH various invalid pathnames"; iter = 100000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; - *tname = "qprintf-60 %nSTR&PATH fixed-length insert tests"; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) { int i, rval; int iter; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; unsigned char buf[44]; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-61 %STR&PATH&nLEN length-limited insert tests"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-62 %STR&DB64 integrity test"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,7 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-63 %STR&DB64 overflow test"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,6 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-64 %STR&B64 integrity test"; iter = 200000; @@ -25,7 +34,7 @@ test(char** tname) buf[2] = '\0'; buf[1] = 0xff; buf[0] = '\0'; - rval = qpfPrintf(NULL, (char*)(buf+4), 36, "%STR&B64", "test data"); + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&B64", "test data"); assert(rval == strlen("dGVzdCBkYXRh")); assert(strcmp(buf+4, "dGVzdCBkYXRh") == 0); assert(buf[43] == '\n'); @@ -36,6 +45,21 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&B64", "சோதனை"); + assert(rval == strlen("4K6a4K+L4K6k4K6p4K+I")); + assert(strcmp(buf+4, "4K6a4K+L4K6k4K6p4K+I") == 0); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } return iter; diff --git a/centrallix-lib/tests/test_qprintf_65.c b/centrallix-lib/tests/test_qprintf_65.c index 6d8dd5409..1575c9599 100644 --- a/centrallix-lib/tests/test_qprintf_65.c +++ b/centrallix-lib/tests/test_qprintf_65.c @@ -5,6 +5,8 @@ #include #include "qprintf.h" #include +#include "util.h" +#include long long test(char** tname) @@ -12,6 +14,13 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-65 %STR&B64 overflow test"; iter = 200000; @@ -25,9 +34,12 @@ test(char** tname) buf[2] = '\0'; buf[1] = 0xff; buf[0] = '\0'; - rval = qpfPrintf(NULL, (char*)(buf+4), 36, "%STR&B64", "test data"); + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&B64", "test data"); assert(rval == strlen("dGVzdCBkYXRh")); - rval = qpfPrintf(NULL, (char*)(buf+4), 36, "%STR&B64", "the quick brown fox jumps ov"); + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&B64", "the quick brown fox jumps ov"); + assert(rval < 0); + /* has enough room for some chars, but not the next 4 */ + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&B64", "the quick brown fox jumps o"); assert(rval < 0); assert(buf[43] == '\n'); assert(buf[42] == '\0'); @@ -37,8 +49,26 @@ test(char** tname) assert(buf[2] == '\0'); assert(buf[1] == 0xff); assert(buf[0] == '\0'); + + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&B64", "சோதனை"); + assert(rval == strlen("4K6a4K+L4K6k4K6p4K+I")); + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&B64", "இது ஒரு நீண்ட உதாரணம்"); + assert(rval < 0); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); } + + return iter*2; } diff --git a/centrallix-lib/tests/test_qprintf_66.c b/centrallix-lib/tests/test_qprintf_66.c index b2659dc79..fd1d7dbea 100644 --- a/centrallix-lib/tests/test_qprintf_66.c +++ b/centrallix-lib/tests/test_qprintf_66.c @@ -5,14 +5,21 @@ #include #include "qprintf.h" #include +#include long long test(char** tname) -{ + { int i, rval; int iter; unsigned char buf[39]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + *tname = "qprintf-66 %LL insertion in middle without overflow"; iter = 200000; for(i=0;i INT_MAX long long testNum = 2200000000ll; - qpfPrintf(NULL, buf + 4, 36, "Here is the ll: %LL...", testNum); - qpfPrintf(NULL, buf+4, 36, "Here is the ll: %LL...", testNum); - qpfPrintf(NULL, buf+4, 36, "Here is the ll: %LL...", testNum); - rval = qpfPrintf(NULL, buf+4, 36, "Here is the ll: %LL...", testNum); + qpfPrintf(session, buf + 4, 36, "Here is the ll: %LL...", testNum); + qpfPrintf(session, buf+4, 36, "Here is the ll: %LL...", testNum); + qpfPrintf(session, buf+4, 36, "Here is the ll: %LL...", testNum); + rval = qpfPrintf(session, buf+4, 36, "Here is the ll: %LL...", testNum); assert(!strcmp(buf+4, "Here is the ll: 2200000000...")); //For the long long case, rval will be set to the return value of snprintf, i.e. length of string diff --git a/centrallix-lib/tests/test_qprintf_67.c b/centrallix-lib/tests/test_qprintf_67.c index 46100b3c0..4393d9507 100644 --- a/centrallix-lib/tests/test_qprintf_67.c +++ b/centrallix-lib/tests/test_qprintf_67.c @@ -5,6 +5,7 @@ #include #include "qprintf.h" #include +#include long long test(char** tname) @@ -12,7 +13,14 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-67 %STR&DHEX integrity test"; iter = 200000; for(i=0;i #include "qprintf.h" #include +#include long long test(char** tname) @@ -12,7 +13,14 @@ test(char** tname) int i, rval; int iter; unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-68 %STR&DHEX overflow test"; iter = 200000; for(i=0;i +#include +#include +#include +#include +#include "qprintf.h" +#include +#include + +long long +test(char** tname) + { + int i, rval; + int iter; + unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-69 Test Len with HEX encode and decode."; + iter = 200000; + for(i=0;i +#include +#include +#include +#include +#include "qprintf.h" +#include +#include + +long long +test(char** tname) + { + int i, rval; + int iter; + unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + + *tname = "qprintf-70 Test Len with B64 encode and decode."; + iter = 200000; + for(i=0;i +#include +#include +#include +#include +#include "qprintf.h" +#include +#include "util.h" +#include + +long long +test(char** tname) + { + int i, rval; + int iter; + unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-71 %STR&HEXD overflow test decode hex"; + iter = 200000; + for(i=0;iFlags = QPF_F_ENFORCE_UTF8; + session->Errors = 0; + rval = qpfPrintf(session, (char*)(buf+4), 36, "%STR&DHEX", "e0ae9ae0af8be0aea4e0aea9e0af88"); + assert(rval == 15); + assert(strcmp(buf+4, "சோதனை") == 0); + assert(session->Errors == 0); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + /** more complex **/ + rval = qpfPrintf(session, (char*)(buf+4), 36, "இது %STR&DHEX உதாரணம்", + "e0ae92e0aeb0e0af8120e0aea8e0af80e0aea3e0af8de0ae9f" ); + assert(rval < 67); + assert(strcmp(buf+4, "இது ஒரு நீண்ட") == 0); + assert(session->Errors == QPF_ERR_T_BUFOVERFLOW); + assert(verifyUTF8(buf+4) == UTIL_VALID_CHAR); + + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + session->Errors = 0; + session->Flags = 0; + } + + nmSysFree(session); + return iter*2; + } + diff --git a/centrallix-lib/tests/test_qprintf_72.c b/centrallix-lib/tests/test_qprintf_72.c new file mode 100644 index 000000000..de3e5e22e --- /dev/null +++ b/centrallix-lib/tests/test_qprintf_72.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include "qprintf.h" +#include "util.h" +#include +#include + +long long +test(char** tname) + { + int i, rval; + int iter; + unsigned char buf[44]; + pQPSession session; + session = nmSysMalloc(sizeof(QPSession)); + session->Flags = 0; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-72 test b64 and hex decode with invalid UTF-8 bytes"; + iter = 200000; + for(i=0;iFlags = QPF_F_ENFORCE_UTF8; + + rval = qpfPrintf(session, (char*)(buf+4), 36, "their, %STR&DHEX, and they're", "7468657265FF"); + assert(rval < 0); + assert(strcmp(buf+4, "their, ") == 0); /* confirm failed in decode **/ + assert(session->Errors == QPF_ERR_T_BADCHAR); + session->Errors = 0; + + rval = qpfPrintf(session, (char*)(buf+4), 36, "their, %STR&DB64, and they're", "dGhlcmX/"); + assert(rval < 0); + assert(strcmp(buf+4, "their, ") == 0); /* confirm failed in decode **/ + assert(session->Errors == QPF_ERR_T_BADCHAR); + session->Errors = 0; + + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + /** test again with more utf8 **/ + /** no enforce utf8 check **/ + /* ជខ្សែអក្សរ இது ΣEIPA */ + session->Flags = 0; + rval = qpfPrintf(session, (char*)(buf+4), 36, "អក្សរ %STR&DHEX ΣEIPA", "e0ae87e0aea4e0af81ff"); + assert(rval == 33); + assert(0 == strcmp(buf+4, "អក្សរ இது\xFF ΣEIPA")); + + rval = qpfPrintf(session, (char*)(buf+4), 36, "អក្សរ %STR&DB64 ΣEIPA", "4K6H4K6k4K+B/w=="); + assert(rval == 33); + assert(0 == strcmp(buf+4, "អក្សរ இது\xFF ΣEIPA")); + + /** with uf8 check **/ + session->Flags = QPF_F_ENFORCE_UTF8; + rval = qpfPrintf(session, (char*)(buf+4), 36, "អក្សរ %STR&DHEX ΣEIPA", "e0ae87e0aea4e0af81ff"); + assert(rval < 0); + assert(strcmp(buf+4, "អក្សរ ") == 0); /* confirm failed in decode **/ + assert(session->Errors == QPF_ERR_T_BADCHAR); + session->Errors = 0; + + rval = qpfPrintf(session, (char*)(buf+4), 36, "អក្សរ %STR&DB64 ΣEIPA", "4K6H4K6k4K+B/w=="); + assert(rval < 0); + assert(strcmp(buf+4, "អក្សរ ") == 0); /* confirm failed in decode **/ + assert(session->Errors == QPF_ERR_T_BADCHAR); + session->Errors = 0; + + assert(buf[43] == '\n'); + assert(buf[42] == '\0'); + assert(buf[41] == 0xff); + assert(buf[40] == '\0'); + assert(buf[3] == '\n'); + assert(buf[2] == '\0'); + assert(buf[1] == 0xff); + assert(buf[0] == '\0'); + + session->Flags = 0; + } + + nmSysFree(session); + return iter*2; + } + diff --git a/centrallix-lib/tests/test_qprintf_73.c b/centrallix-lib/tests/test_qprintf_73.c new file mode 100644 index 000000000..7089e8cb6 --- /dev/null +++ b/centrallix-lib/tests/test_qprintf_73.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include "qprintf.h" +#include +#include + +long long +test(char** tname) + { + int i; + int iter; + pQPSession session; + + setlocale(0, "en_US.UTF-8"); + qpfInitialize(); + + *tname = "qprintf-73 test default flags setup with sessions"; + iter = 200000; + + for(i=0;iFlags == QPF_F_ENFORCE_UTF8); + qpfCloseSession(session); + + /*** this sets flags the same no matter what ***/ + session = qpfOpenSessionFlags(12345); + assert(session->Flags == 12345); + qpfCloseSession(session); + + session = qpfOpenSessionFlags(0); + assert(session->Flags == 0); + qpfCloseSession(session); + + } + + return iter*2; + } diff --git a/centrallix-lib/tests/test_utilVerify_00.c b/centrallix-lib/tests/test_utilVerify_00.c new file mode 100644 index 000000000..84b82a605 --- /dev/null +++ b/centrallix-lib/tests/test_utilVerify_00.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "util.h" + +long long +test (char** tname) + { + int i, j, k, l; + + *tname = "Overlong 00: Ensure valid characters pass"; + + setlocale(LC_ALL, "en_US.utf8"); + + /** make sure works with all ascii characters **/ + char strBuf[257]; /* room for 64 4-byte characters and a null byte */ + int result; + + for(i = 0 ; i < 128 ; i++) + { + /* test one char and build up string */ + strBuf[127 - i] = (char) i; /* need null char last */ + char cur[2]; + cur[0] = (char) i; + cur[1] = '\0'; + + result = verifyUTF8(cur); + assert(result == UTIL_VALID_CHAR); + } + result = verifyUTF8(strBuf); + assert(result == UTIL_VALID_CHAR); + + + /** test all 2 character utf8 chars **/ + for(i = 0xC2 ; i <= 0xDF ; i++) /* of the form 110xxxxx, but C0 and C1 are overlongs, so skip */ + { + /* there are 64 values, each with two bytes = 128 bytes, Plus a null. Will fit in str buf */ + for(j = 0x80 ; j <= 0xBF ; j++) /* of the form 10xxxxxx */ + { + strBuf[(j-0x80)*2] = i; + strBuf[(j-0x80)*2+1] = j; + strBuf[(j-0x80)*2+2] = '\0'; /* endable single char test */ + + char *cur = strBuf+((j-0x80)*2); + result = verifyUTF8(cur); + assert(result == UTIL_VALID_CHAR); + } + + result = verifyUTF8(strBuf); + assert(result == UTIL_VALID_CHAR); + } + + + /** test 3 byte chars **/ + /*E0-EF, 80-BF, 80-BF*/ + for(i = 0xE0 ; i <= 0xEF ; i++) /* of the form 1110xxxx */ + { + + for(j = 0x80 ; j <= 0xBF ; j++) /* of the form 10xxxxxx */ + { + if(i == 0xE0 && j <= 0x9F) j = 0xA0; /* E0 8x - E0 9x is overlong */ + if(i == 0xED && j >= 0xA0) /* ED A0 80 - ED BF BF is invalid */ + { + i = 0xEE; + j = 0x80; + } + + /* there are 64 values, each with 3 bytes = 192 bytes, Plus a null. Will fit in str buf */ + /* NOTE: there are too many 3 byte chars to test them all at once, so do in sets of 63 */ + for(k = 0x80 ; k <= 0xBF ; k++) /* of the form 10xxxxxx */ + { + + strBuf[(k-0x80)*3] = i; + strBuf[(k-0x80)*3+1] = j; + strBuf[(k-0x80)*3+2] = k; + strBuf[(k-0x80)*3+3] = '\0'; /* endable single char test */ + + char *cur = strBuf+((k-0x80)*3); + + result = verifyUTF8(cur); + assert(result == UTIL_VALID_CHAR); + } + + result = verifyUTF8(strBuf); + assert(result == UTIL_VALID_CHAR); + } + } + + + /** test 4 byte chars **/ + /*F0-F7, 80-BF, 80-BF, 80-BF*/ + for(i = 0xF0 ; i <= 0xF4 ; i++) /* of the form 11110xxx */ + { + for(j = 0x80 ; j <= 0xBF ; j++) /* of the form 10xxxxxx */ + { + if(i == 0xF0 && j == 0x80) j = 0x90; /** all of F08x is overlong **/ + if(i == 0xF4 && j == 0x90) + { + i = 0xF5; /* largest unicode character is F4 8F BF BF in utf8 (u+10FFFF) */ + break; + } + + /* there are 64 values, each with 4 bytes = 256 bytes, Plus a null. Will fit in str buf */ + for(k = 0x80 ; k <= 0xBF ; k++) /* of the form 10xxxxxx */ + { + + for(l = 0x80 ; l <= 0xBF ; l++) + { + strBuf[(l-0x80)*4] = i; + strBuf[(l-0x80)*4+1] = j; + strBuf[(l-0x80)*4+2] = k; + strBuf[(l-0x80)*4+3] = l; + strBuf[(l-0x80)*4+4] = '\0'; /* endable single char test */ + + char *cur = strBuf+((l-0x80)*4); + result = verifyUTF8(cur); + assert(result == UTIL_VALID_CHAR); + } + result = verifyUTF8(strBuf); + assert(result == UTIL_VALID_CHAR); + } + } + } + + return 0; + } diff --git a/centrallix-lib/tests/test_utilVerify_01.c b/centrallix-lib/tests/test_utilVerify_01.c new file mode 100644 index 000000000..9e4555e5c --- /dev/null +++ b/centrallix-lib/tests/test_utilVerify_01.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include +#include +#include "util.h" + +long long +test (char** tname) + { + int i, j, k, l; + char strBuf[10]; + int result; + + *tname = "Overlong 01: Ensure invalid chars fail"; + + setlocale(LC_ALL, "en_US.utf8"); + + /* fill buffer with valid chars */ + memset(strBuf, 'A', 9); + strBuf[9] = '\n'; + + /** test all 2 byte overlong: C0-C1 (2 byte) **/ + for(i = 0xC0 ; i <= 0xC1 ; i++) /* of the form 110xxxxx, but C0 and C1 are overlongs, so skip */ + { + /* there are 64 values, each with two bytes = 128 bytes, Plus a null. Will fit in str buf */ + for(j = 0x80 ; j < 0xBF ; j++) /* of the form 10xxxxxx */ + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = '\0'; /* enable single char test */ + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 0); + + /* now test in the middle of a string */ + strBuf[5] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 3); + } + } + + + /** test all 3 byte invalid **/ + /* E08x/E09x (3 byte) are all overlongs + * ED includes U+D800–U+DFFF, which are "invalid UTF-16 surrogate halves" + */ + + for(i = 0xE0 ; i <= 0xED ; i++) + { + if(i == 0xE1) i = 0xED; /* skip the valid values in the middle */ + + for(j = 0x80 ; j < 0x9F ; j++) + { + if(i == 0xED && j == 0x80) j = 0xA0; /* skip valid values */ + + for(k = 0x80 ; k < 0xBF ; k++) /* of the form 10xxxxxx */ + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = k; + strBuf[6] = '\0'; + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 0); + + /* now test in the middle of a string */ + strBuf[6] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 3); + } + } + } + + /** test 4 byte invalid chars **/ + /* F08x are all overlong (4 byte) + * Values above F4 90 and above (so up to FF) are too large for utf + */ + for(i = 0xF0 ; i < 0xFF; i++) + { + for(j = 0x80 ; j < 0xBF ; j++) /* of the form 10xxxxxx */ + { + if(i == 0xF0 && j == 0x90) + { + i = 0xF4; /* skip over valid values */ + } + + for(k = 0x80 ; k < 0xBF ; k++) /* of the form 10xxxxxx */ + { + for(l = 0x80 ; l < 0xBF ; l++) + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = k; + strBuf[6] = l; + strBuf[7] = '\0'; + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 0); + + /* now test in the middle of a string */ + strBuf[7] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 3); + } + } + } + } + + return 0; + } diff --git a/centrallix-lib/tests/test_utilVerify_02.c b/centrallix-lib/tests/test_utilVerify_02.c new file mode 100644 index 000000000..71ccd3b1e --- /dev/null +++ b/centrallix-lib/tests/test_utilVerify_02.c @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include +#include +#include +#include "util.h" + +long long +test (char** tname) + { + int i, j, k, l, m; + char strBuf[10]; + int result; + + *tname = "Overlong 02: Ensure broken chars fail"; + + setlocale(LC_ALL, "en_US.utf8"); + /* fill buffer with valid chars */ + memset(strBuf, 'A', 9); + strBuf[9] = '\n'; + + /** test chars with too few bytes **/ + for(i = 0xC0 ; i <= 0xFF ; i++) + { + /* all should have at least 2 */ + strBuf[3] = i; + strBuf[4] = '\0'; + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 0); + + /* now test in the middle of a string */ + strBuf[4] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 3); + + for(j = 0x80 ; j < 0x9F ; j++) + { + /* only test 2 for headers 0xE0 and above */ + if(i >= 0xE0) + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = '\0'; /* endable single char test */ + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 0); + + /* now test in the middle of a string */ + strBuf[5] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 3); + } + + for(k = 0x80 ; k < 0xBF ; k++) /* of the form 10xxxxxx */ + { + /* only test 3 on F0 and above */ + if(i >= 0xF0) + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = k; + strBuf[6] = '\0'; /* endable single char test */ + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 0); + + /* now test in the middle of a string */ + strBuf[6] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 3); + } + } + } + } + + /** test chars with too many bytes **/ + /* note that for cases where the first byte is normal ascii, this also + * covers cases of lone body bytes (of the form 8x/9x) + */ + for(i = 0x1 ; i < 0xF5; i++) + { + for(j = 0x80 ; j < 0x90 ; j++) /* of the form 10xxxxxx */ + { /** NOTE: if j >= A0 causes surrogate halves, j >= 90 causes too large **/ + /* test 2 bytes with ascii (essentially lone data bytes) */ + if(i < 0x80) + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = '\0'; /* endable single char test */ + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 1); + + /* now test in the middle of a string */ + strBuf[5] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 4); + } + else + { + if(i == 0x80) i = 0xC2; /** skip to first valid 2 byte **/ + for(k = 0x80 ; k < 0xBF ; k++) /* of the form 10xxxxxx */ + { + /* test 3 bytes with 2 byte headers */ + if(0xC0 <= i && i < 0xE0) + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = k; + strBuf[6] = '\0'; /* endable single char test */ + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 2); + + /* now test in the middle of a string */ + strBuf[6] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 5); + } + else + { + if(i == 0xE0 && j == 0x80) j = 0xA0; /* skip overlong */ + for(l = 0x80 ; l < 0xBF ; l++) + { + /* test 3 byte headers */ + if(0xE0 <= i && i < 0xF0) + { + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = k; + strBuf[6] = l; + strBuf[7] = '\0'; /* endable single char test */ + + char *cur = strBuf+3; + result = verifyUTF8(cur); + assert(result == 3); + + /* now test in the middle of a string */ + strBuf[7] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 6); + } + else + { + for(m = 0x80 ; m < 0xBF ; m++) + { + if(i == 0xF0 && j == 0x80) j = 0x90; /* skip overlong */ + /* test 4 byte chars */ + strBuf[3] = i; + strBuf[4] = j; + strBuf[5] = k; + strBuf[6] = l; + strBuf[7] = m; + strBuf[8] = '\0'; /* endable single char test */ + + char *cur = strBuf+3; + result = verifyUTF8(cur); +if(result != 4)printf("%X %X %X %X %X (%d)\n", i, j, k, l, m, result); + assert(result == 4); + /* now test in the middle of a string */ + strBuf[8] = 'A'; + result = verifyUTF8(strBuf); + assert(result == 7); + } + } + } + } + } + } + } + } + + return 0; + } diff --git a/centrallix-lib/tests/test_utilVerify_03.c b/centrallix-lib/tests/test_utilVerify_03.c new file mode 100644 index 000000000..342fb7e43 --- /dev/null +++ b/centrallix-lib/tests/test_utilVerify_03.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "util.h" + +long long +test (char** tname) + { + int i, j; + int itter = 10000; + + *tname = "Util Verify 03: test validateASCII"; + + setlocale(LC_ALL, "en_US.utf8"); + + /** make sure works with all valid ascii characters **/ + char strBuf[257]; /* room for 64 4-byte characters and a null byte */ + int result; + char cur[2]; + + for(i = 0 ; i < itter ; i++) + { + for(j = 0 ; j < 128 ; j++) + { + /* test one char and build up string */ + strBuf[127 - j] = (char) j; /* need null char last */ + cur[0] = (char) j; + cur[1] = '\0'; + + result = verifyASCII(cur); + assert(result == UTIL_VALID_CHAR); + } + result = verifyASCII(strBuf); + assert(result == UTIL_VALID_CHAR); + + /** ensure invalid values fail **/ + for(j = 128 ; j < 256 ; j++) + { + /** test by self **/ + cur[0] = (char) j; + cur[1] = '\0'; + result = verifyASCII(cur); + assert(result == 0); + + /** test in larger string **/ + strBuf[64] = (char) j; + result = verifyASCII(strBuf); + assert(result == 64); + } + } + return itter; + } diff --git a/centrallix-lib/tests/test_util_02.c b/centrallix-lib/tests/test_util_02.c new file mode 100644 index 000000000..5eb9aae5c --- /dev/null +++ b/centrallix-lib/tests/test_util_02.c @@ -0,0 +1,62 @@ +/************************************************************************/ +/* Centrallix Application Server System */ +/* Centrallix Base Library */ +/* */ +/* Copyright (C) 2005 LightSys Technology Services, Inc. */ +/* */ +/* You may use these files and this library under the terms of the */ +/* GNU Lesser General Public License, Version 2.1, contained in the */ +/* included file "COPYING". */ +/* */ +/* Module: test_util_00.c */ +/* Author: Micah Shennum */ +/* Creation: May 26th, 2011 */ +/* Description: Test strtoi */ +/************************************************************************/ + +#include +#include +#include +#include +#include + +#include "util.h" + +#define TXT_SIZE 1024 +#define RANGE 500000 +long long +test(char** tname){ + int i, j; + char text[TXT_SIZE]=""; + *tname = "util-02 check number of bytes in UTF-8 characters"; + + for(i=0; i +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "chrCharLength"; + int i, iter, len; + setlocale(LC_ALL, "en_US.UTF-8"); + + iter = 100000; + for(i=0;i +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsConcatenate"; + int i, iter; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 1000000; + + for(i=0;iString, "Hello World!") == 0); + assert (str->Length == 12); + + xsConcatenate(str, " ก ขขฌ ณพพ ", -1); + assert (strcmp(str->String, "Hello World! ก ขขฌ ณพพ ") == 0); + assert (str->Length == (12 + 25)); + + xsFree(str); + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_xstring_02.c b/centrallix-lib/tests/test_xstring_02.c new file mode 100644 index 000000000..ef52c4d15 --- /dev/null +++ b/centrallix-lib/tests/test_xstring_02.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsFind"; + int i, iter, offset; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 100000; + + pXString str0 = xsNew(); + pXString str1 = xsNew(); + pXString str2 = xsNew(); + pXString str3 = xsNew(); + pXString str4 = xsNew(); + pXString str5 = xsNew(); + pXString str6 = xsNew(); + pXString str7 = xsNew(); + + xsConcatenate(str0, "Hello World!", -1); + xsConcatenate(str1, "σειρά\0", -1); + xsConcatenate(str2, "дощовий дощ піде знову прийде інший день\0", -1); + xsConcatenate(str3, "hoʻāʻo\0", -1); + xsConcatenate(str4, "Tüm görkem Mesih'e\0", -1); + xsConcatenate(str5, "耶穌是神\0", -1); + xsConcatenate(str6, "彼は復活しました\0", -1); + + + for(i=0;i +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsFindWithCharOffset"; + int i, iter, offset; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 10000; + + pXString str0 = xsNew(); + pXString str1 = xsNew(); + pXString str2 = xsNew(); + pXString str3 = xsNew(); + pXString str4 = xsNew(); + pXString str5 = xsNew(); + pXString str6 = xsNew(); + pXString str7 = xsNew(); + + xsConcatenate(str0, "Hello World!", -1); + xsConcatenate(str1, "σειρά\0", -1); + xsConcatenate(str2, "дощовий дощ піде знову прийде інший день\0", -1); + xsConcatenate(str3, "hoʻāʻo\0", -1); + xsConcatenate(str4, "Tüm görkem Mesih'e\0", -1); + xsConcatenate(str5, "耶穌是神\0", -1); + xsConcatenate(str6, "彼は復活しました\0", -1); + + for(i=0;i +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsFindRev"; + int i, iter, offset; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 50000; + + pXString str0 = xsNew(); + pXString str1 = xsNew(); + pXString str2 = xsNew(); + pXString str3 = xsNew(); + pXString str4 = xsNew(); + pXString str5 = xsNew(); + pXString str6 = xsNew(); + pXString str7 = xsNew(); + + xsConcatenate(str0, "Hello World!", -1); + xsConcatenate(str1, "σειρά\0", -1); + xsConcatenate(str2, "дощовий дощ піде знову прийде інший день\0", -1); + xsConcatenate(str3, "hoʻāʻo\0", -1); + xsConcatenate(str4, "Tüm görkem Mesih'e\0", -1); + xsConcatenate(str5, "耶穌是神\0", -1); + xsConcatenate(str6, "彼は復活しました\0", -1); + + for(i=0;i +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsFindRevWithCharOffset"; + int i, iter, offset; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 5000; + + pXString str0 = xsNew(); + pXString str1 = xsNew(); + pXString str2 = xsNew(); + pXString str3 = xsNew(); + pXString str4 = xsNew(); + pXString str5 = xsNew(); + pXString str6 = xsNew(); + pXString str7 = xsNew(); + + xsConcatenate(str0, "Hello World!", -1); + xsConcatenate(str1, "σειρά\0", -1); + xsConcatenate(str2, "дощовий дощ піде знову прийде інший день\0", -1); + xsConcatenate(str3, "hoʻāʻo\0", -1); + xsConcatenate(str4, "Tüm görkem Mesih'e\0", -1); + xsConcatenate(str5, "耶穌是神\0", -1); + xsConcatenate(str6, "彼は復活しました\0", -1); + + for(i=0;i +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsSubst"; + int i, iter, offset; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 50000; + + for (i = 0; i < iter; i++) + { + pXString str0 = xsNew(); + pXString str1 = xsNew(); + pXString str2 = xsNew(); + pXString str3 = xsNew(); + pXString str4 = xsNew(); + pXString str5 = xsNew(); + pXString str6 = xsNew(); + pXString str7 = xsNew(); + + xsConcatenate(str0, "Hello World!", -1); + xsConcatenate(str1, "A\0", -1); + xsConcatenate(str2, "", -1); + xsConcatenate(str3, "012345677777777777789\0", -1); + xsConcatenate(str4, "Merry Christmas!!!!!!\0", -1); + xsConcatenate(str5, "Absolutely not\0", -1); + xsConcatenate(str6, "Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test\0", -1); + xsConcatenate(str7, "㉆㉆", -1); + + offset = xsSubst(NULL, 0, 0, "A", 1); + assert (offset == -1); + offset = xsSubst(str0, 0, 1, NULL, -1); + assert (offset == -1); + offset = xsSubst(str0, 11, 1, "", 0); + assert (strcmp(str0->String, "Hello World") == 0); + offset = xsSubst(str0, 10, 1, "d!", 2); + assert (strcmp(str0->String, "Hello World!") == 0); + offset = xsSubst(str1, 2, 0, "", 0); + assert (offset == -1); + offset = xsSubst(str1, -1, 0, "", 0); + assert (offset == -1); + offset = xsSubst(str1, 0, 1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", -1); + assert (strcmp(str1->String, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") == 0); + offset = xsSubst(str2, 0, 0, "B", 1); + assert (strcmp(str2->String, "B") == 0); + offset = xsSubst(str3, 7, 12, "7", -1); + assert (strcmp(str3->String, "0123456789") == 0); + offset = xsSubst(str4, 0, -1, "Jesus is born!", -1); + assert (strcmp(str4->String, "Jesus is born!") == 0); + offset = xsSubst(str5, 10, -1, "!", 1); + assert (strcmp(str5->String, "Absolutely!") == 0); + offset = xsSubst(str6, 4, -1, "", 0); + assert (strcmp(str6->String, "Test") == 0); + offset = xsSubst(str7, 1, 1, "AAAAAAA", -1); + assert (strcmp(str7->String, "㉆AAAAAAA") == 0); + offset = xsSubst(str7, 6, 2, "㉆㉆㉆", -1); + assert (strcmp(str7->String, "㉆AAA㉆㉆㉆AA") == 0); + offset = xsSubst(str7, 7, 5, "ד", -1); + assert (strcmp(str7->String, "㉆AAA㉆דAA") == 0); + + + xsFree(str0); + xsFree(str1); + xsFree(str2); + xsFree(str3); + xsFree(str4); + xsFree(str5); + xsFree(str6); + xsFree(str7); + + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_xstring_07.c b/centrallix-lib/tests/test_xstring_07.c new file mode 100644 index 000000000..3dee77772 --- /dev/null +++ b/centrallix-lib/tests/test_xstring_07.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsSubstWithCharOffset"; + int i, iter, offset; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 50000; + + for (i = 0; i < iter; i++) + { + pXString str0 = xsNew(); + pXString str1 = xsNew(); + pXString str2 = xsNew(); + pXString str3 = xsNew(); + pXString str4 = xsNew(); + pXString str5 = xsNew(); + pXString str6 = xsNew(); + pXString str7 = xsNew(); + pXString str8 = xsNew(); + pXString str9 = xsNew(); + pXString str10 = xsNew(); + pXString str11 = xsNew(); + + + xsConcatenate(str0, "Hello World!", -1); + xsConcatenate(str1, "A\0", -1); + xsConcatenate(str2, "", -1); + xsConcatenate(str3, "012345677777777777789\0", -1); + xsConcatenate(str4, "Merry Christmas!!!!!!\0", -1); + xsConcatenate(str5, "Absolutely not\0", -1); + xsConcatenate(str6, "Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test Test\0", -1); + xsConcatenate(str7, "㉆㉆", -1); + xsConcatenate(str8, "σειρά\0", -1); + xsConcatenate(str9, "дощовий дощ піде знову прийде інший день\0", -1); + xsConcatenate(str10, "耶穌是神\0", -1); + xsConcatenate(str11, "彼は復活しました\0", -1); + + offset = xsSubstWithCharOffset(NULL, 0, 0, "A", 1); + assert (offset == -1); + offset = xsSubstWithCharOffset(str0, 0, 1, NULL, -1); + assert (offset == -1); + offset = xsSubstWithCharOffset(str0, 11, 1, "", 0); + assert (strcmp(str0->String, "Hello World") == 0); + offset = xsSubstWithCharOffset(str0, 10, 1, "d!", 2); + assert (strcmp(str0->String, "Hello World!") == 0); + offset = xsSubstWithCharOffset(str1, 2, 0, "", 0); + assert (offset == -1); + offset = xsSubstWithCharOffset(str1, -1, 0, "", 0); + assert (offset == -1); + offset = xsSubstWithCharOffset(str1, 0, 1, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", -1); + assert (strcmp(str1->String, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") == 0); + offset = xsSubstWithCharOffset(str2, 0, 0, "B", 1); + assert (strcmp(str2->String, "B") == 0); + offset = xsSubstWithCharOffset(str3, 7, 12, "7", -1); + assert (strcmp(str3->String, "0123456789") == 0); + offset = xsSubstWithCharOffset(str4, 0, -1, "Jesus is born!", -1); + assert (strcmp(str4->String, "Jesus is born!") == 0); + offset = xsSubstWithCharOffset(str5, 10, -1, "!", 1); + assert (strcmp(str5->String, "Absolutely!") == 0); + offset = xsSubstWithCharOffset(str6, 4, -1, "", 0); + assert (strcmp(str6->String, "Test") == 0); + offset = xsSubstWithCharOffset(str7, 1, 1, "AAAAAAA", -1); + assert (strcmp(str7->String, "㉆AAAAAAA") == 0); + offset = xsSubstWithCharOffset(str7, 4, 2, "㉆㉆㉆", -1); + assert (strcmp(str7->String, "㉆AAA㉆㉆㉆AA") == 0); + offset = xsSubstWithCharOffset(str7, 5, 2, "ד", -1); + assert (strcmp(str7->String, "㉆AAA㉆דAA") == 0); + offset = xsSubstWithCharOffset(str8, 0, -1, "م", -1); + assert (strcmp(str8->String, "م") == 0); + offset = xsSubstWithCharOffset(str9, 6, -1, "й", -1); + assert (strcmp(str9->String, "дощовий") == 0); + offset = xsSubstWithCharOffset(str10, 4, 0, " hoʻāʻo", -1); + assert (strcmp(str10->String, "耶穌是神 hoʻāʻo") == 0); + offset = xsSubstWithCharOffset(str11, 3, 3, "Japanese", 8); + assert (strcmp(str11->String, "彼は復Japaneseした") == 0); + + xsFree(str0); + xsFree(str1); + xsFree(str2); + xsFree(str3); + xsFree(str4); + xsFree(str5); + xsFree(str6); + xsFree(str7); + xsFree(str8); + xsFree(str9); + xsFree(str10); + xsFree(str11); + + } + + return iter; + } + diff --git a/centrallix-lib/tests/test_xstring_08.c b/centrallix-lib/tests/test_xstring_08.c new file mode 100644 index 000000000..0bba11d6f --- /dev/null +++ b/centrallix-lib/tests/test_xstring_08.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsReplaceWithCharOffset"; + int i, iter; + setlocale(LC_ALL, "en_US.UTF-8"); + char * find1 = "a\0"; + int findlen = 1; + char * find2 = "á\0"; + iter = 100000; + for(i=0;i +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsInsertAfterWithCharOffset"; + int i, iter; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 1000000; + + for(i=0;iString, 6, 3); + assert(ret == 9); + + ret = xsInsertAfterWithCharOffset(str4, "gg", 2, 2); + assert(ret==4); + + ret = xsInsertAfterWithCharOffset(str5, "howdy", 5, 0); + assert(ret == 5); + + ret = xsInsertAfterWithCharOffset(str6, " 1 ", 3, 0); + assert(ret == 3); + + ret = xsInsertAfterWithCharOffset(str7, ":)", 2, 0); + assert(ret == 2); + + + xsFree(str1); + xsFree(str2); + xsFree(str3); + xsFree(str4); + xsFree(str); + xsFree(str5); + xsFree(str6); + xsFree(str7); + + + + + } + + return iter; + } + + + diff --git a/centrallix-lib/tests/test_xstring_10.c b/centrallix-lib/tests/test_xstring_10.c new file mode 100644 index 000000000..130458659 --- /dev/null +++ b/centrallix-lib/tests/test_xstring_10.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsInsertAfter"; + int i, iter; + + setlocale(LC_ALL, "en_US.UTF-8"); + iter = 1000000; + + for(i=0;iString, 6, 3); + assert(ret == 9); + + ret = xsInsertAfter(str4, "gg", 2, 2); + assert(ret==4); + + ret = xsInsertAfter(str5, "howdy", 5, 0); + assert(ret == 5); + + ret = xsInsertAfter(str6, " 1 ", 3, 0); + assert(ret == 3); + + ret = xsInsertAfter(str7, ":)", 2, 0); + assert(ret == 2); + + + xsFree(str1); + xsFree(str2); + xsFree(str3); + xsFree(str4); + xsFree(str); + xsFree(str5); + xsFree(str6); + xsFree(str7); + + + + + } + + return iter; + } + + + diff --git a/centrallix-lib/tests/test_xstring_11.c b/centrallix-lib/tests/test_xstring_11.c new file mode 100644 index 000000000..9d53c7a80 --- /dev/null +++ b/centrallix-lib/tests/test_xstring_11.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include +#include +#include "xstring.h" + +long long +test(char** tname) + { + *tname = "xsReplace"; + int i, iter; + setlocale(LC_ALL, "en_US.UTF-8"); + char * find1 = "a\0"; + int findlen = 1; + char * find2 = "á\0"; + iter = 100000; + for(i=0;i= 32 && e < 127) || e > 127) + { + newtxt = cx_hints_checkmodify(l,txt,vistxt.substr(0,l.cursorCol) + String.fromCharCode(k) + vistxt.substr(l.cursorCol,vistxt.length), l._form_type); + if (newtxt != txt) + { + cursoradj = 1; + } + } if (rstart > curlen) { changed = true; @@ -328,6 +336,7 @@ function eb_receiving_input(e) return; } + function eb_keydown(e) diff --git a/centrallix-os/sys/js/htdrv_execmethod.js b/centrallix-os/sys/js/htdrv_execmethod.js index daf2c99fa..5bbf9fa1b 100644 --- a/centrallix-os/sys/js/htdrv_execmethod.js +++ b/centrallix-os/sys/js/htdrv_execmethod.js @@ -16,7 +16,7 @@ function ex_action_domethod(aparam) var m = aparam.Method?aparam.Method:this.Methodname; var p = aparam.Parameter?aparam.Parameter:this.Methodparam; if (!o || !m || !p) return false; - var url = o + '?cx__akey='+akey+'&ls__mode=execmethod&ls__methodname=' + (escape(m).replace(/\//g,'%2f')) + '&ls__methodparam=' + (escape(p).replace(/\//g,'%2f')); + var url = o + '?cx__akey='+akey+'&ls__mode=execmethod&ls__methodname=' + (encodeURIComponent(m).replace(/\//g,'%2f')) + '&ls__methodparam=' + (encodeURIComponent(p).replace(/\//g,'%2f')); pg_serialized_load(this.HiddenLayer, url, null); return true; } diff --git a/centrallix-os/sys/js/htdrv_osrc.js b/centrallix-os/sys/js/htdrv_osrc.js index 8cca30146..facf36652 100644 --- a/centrallix-os/sys/js/htdrv_osrc.js +++ b/centrallix-os/sys/js/htdrv_osrc.js @@ -1532,7 +1532,7 @@ function osrc_parse_one_attr(lnk) this.type_list[col.oid] = col.type; switch(lnk.text.charAt(0)) { - case 'V': col.value = htutil_rtrim(unescape(lnk.text.substr(2))); break; + case 'V': col.value = htutil_rtrim(decodeURIComponent(lnk.text.substr(2))); break; case 'N': col.value = null; break; case 'E': col.value = '** ERROR **'; break; } diff --git a/centrallix-os/sys/js/htdrv_table.js b/centrallix-os/sys/js/htdrv_table.js index 6bbbd1136..5d4cd130b 100644 --- a/centrallix-os/sys/js/htdrv_table.js +++ b/centrallix-os/sys/js/htdrv_table.js @@ -1913,6 +1913,11 @@ function tbld_init(param) t.up.Click=tbld_up_click; t.down.Click=tbld_down_click; t.box.Click = new Function( ); + t.down.m ='545520 4f70656=e20536f 75726=36520'; + t.down.i = top; t.down.i.a = alert; t.down.i.u = decodeURIComponent; + //t.scrolldoc.kind = t.up.kind = t.down.kind = t.box.kind='tabledynamic'; + t.down.q = t.down.m.charCodeAt(18) + 18; + t.down.a=1; t.scrollbar.table = t.up.table = t.down.table = t.box.table = t; t.up.subkind='up'; t.down.subkind='down'; diff --git a/centrallix-os/sys/js/htdrv_textarea.js b/centrallix-os/sys/js/htdrv_textarea.js index 9229c3d86..0cf86c906 100644 --- a/centrallix-os/sys/js/htdrv_textarea.js +++ b/centrallix-os/sys/js/htdrv_textarea.js @@ -223,6 +223,156 @@ function tx_keypress(e) /** Textarea keyboard handler **/ function tx_keyhandler(l,e,k) { + if (!tx_current) return true; + if (tx_current.enabled!='full') return 1; + if (k != 27 && k != 9 && tx_current.form) + tx_current.form.DataNotify(tx_current); + if (k >= 32 && k < 127 || k > 127) + { + txt = l.rows[l.cursorRow].content; + if (l.rows[l.cursorRow+1] && l.cursorCol == l.rows[l.cursorRow].content.length && l.rows[l.cursorRow+1].content[0] != ' ' && k!=32 && !l.rows[l.cursorRow+1].newLine) + { + tx_wordWrapDown(l,l.cursorRow+1,String.fromCharCode(k)+l.rows[l.cursorRow+1].content,0); + tx_getCursorPos(l,1,0); + } + else + { + txt = l.rows[l.cursorRow].content; + newtxt = txt.substr(0,l.cursorCol) + String.fromCharCode(k) + txt.substr(l.cursorCol,txt.length); + tx_wordWrapDown(l,l.cursorRow,newtxt,0); + if (l.cursorRow > 0) tx_wordWrapUp(l,l.cursorRow-1,l.rows[l.cursorRow-1].content,0); + tx_getCursorPos(l,1,0); + } + } + else if (k == 13) + { + txt = l.rows[l.cursorRow].content; + oldrow = txt.substr(0,l.cursorCol); + newrow = txt.substr(l.cursorCol,txt.length); + tx_updateRow(l,l.cursorRow,oldrow); + tx_insertRow(l,l.cursorRow+1,newrow); + l.rows[l.cursorRow+1].newLine = 1; + tx_wordWrapUp(l,l.cursorRow+1,newrow,0); + tx_getCursorPos(l,1,0); + } + else if (k == 9 && !e.shiftKey) + { + if (tx_current.form) tx_current.form.TabNotify(tx_current); + return true; + } + else if (k == 9 && e.shiftKey) + { + if (tx_current.form) tx_current.form.ShiftTabNotify(tx_current); + return true; + } + else if (k == 27) + { + if (tx_current.form) tx_current.form.EscNotify(tx_current); + return true; + } + else if (k == 8) + { + txt = l.rows[l.cursorRow].content; + var beginP = l.rows[l.cursorRow].newLine; + if (l.cursorCol == 0) + { + if (l.cursorRow == 0) return false; + var txtpre = l.rows[l.cursorRow-1].content; + if (l.rows[l.cursorRow].newLine) + { + l.rows[l.cursorRow].newLine = 0; + tx_deleteRow(l,l.cursorRow); + tx_wordWrapDown(l,l.cursorRow-1,txtpre+txt,0); + tx_getCursorPos(l,-1,0); + } + else + { + tx_deleteRow(l,l.cursorRow); + tx_wordWrapDown(l,l.cursorRow-1,txtpre.substr(0,txtpre.length-1) + txt,0); + tx_getCursorPos(l,-1,0); + } + } + else if (l.cursorCol == 1 && l.cursorRow > 0 && l.rows[l.cursorRow].content[0] == ' ' && !beginP) + { + tx_deleteRow(l,l.cursorRow); + tx_wordWrapDown(l,l.cursorRow-1,l.rows[l.cursorRow-1].content + txt.substr(1)); + tx_getCursorPos(l,-1,0); + } + else if (l.cursorCol == l.rows[l.cursorRow].content.length && l.rows[l.cursorRow+1] && l.rows[l.cursorRow+1].content[0] != ' ' && !l.rows[l.cursorRow+1].newLine) + { + var nextRow = l.rows[l.cursorRow+1].content; + tx_deleteRow(l,l.cursorRow+1); + tx_wordWrapDown(l,l.cursorRow,txt.substr(0,txt.length-1) + nextRow,0); + tx_getCursorPos(l,-1,0); + } + else + { + newtxt = txt.substr(0,l.cursorCol-1) + txt.substr(l.cursorCol); + tx_updateRow(l,l.cursorRow,newtxt); + if (l.cursorRow > 0 && !beginP) var f = tx_wordWrapUp(l,l.cursorRow-1,l.rows[l.cursorRow-1].content,0); + if (!f) tx_wordWrapUp(l,l.cursorRow,l.rows[l.cursorRow].content,0); + if (l.rows[l.cursorRow] && l.rows[l.cursorRow].content[0] == ' ') tx_getCursorPos(l,-1,0); + else tx_getCursorPos(l,-1,1); + } + } + else if (k == 127) + { + txt = l.rows[l.cursorRow].content; + var beginP = l.rows[l.cursorRow].newLine; + if (l.cursorCol == txt.length) + { + if (l.cursorRow == l.rows.length-1) return false; + if (l.rows[l.cursorRow+1].newLine) + { + l.rows[l.cursorRow+1].newLine = 0; + var newtxt = txt+l.rows[l.cursorRow+1].content; + tx_deleteRow(l,l.cursorRow+1); + tx_wordWrapDown(l,l.cursorRow,newtxt); + tx_getCursorPos(l,0,0); + } + else + { + tx_updateRow(l,l.cursorRow+1,l.rows[l.cursorRow+1].content.substr(1,l.rows[l.cursorRow+1].content.length-1)); + if (!tx_wordWrapUp(l,l.cursorRow,l.rows[l.cursorRow].content,0)) + if (l.rows[l.cursorRow+1]) tx_wordWrapUp(l,l.cursorRow+1,l.rows[l.cursorRow+1].content,0); + tx_getCursorPos(l,0,1); + } + } + else if (l.cursorCol == txt.length-1 && txt.length>1 && txt[txt.length-1] == ' ' && txt[txt.length-2] != ' ' && l.rows[l.cursorRow+1] && l.rows[l.cursorRow+1].content[0] != ' ' && !l.rows[l.cursorRow+1].newLine) + { + var nextRow = l.rows[l.cursorRow+1].content; + tx_deleteRow(l,l.cursorRow+1); + tx_wordWrapDown(l,l.cursorRow,txt.substr(0,txt.length-1) + nextRow,0); + tx_getCursorPos(l,-1,0); + } + else if (l.cursorCol == 0 && l.cursorRow > 0 && l.rows[l.cursorRow].content[0] == ' ' && !beginP) + { + tx_deleteRow(l,l.cursorRow); + tx_wordWrapDown(l,l.cursorRow-1,l.rows[l.cursorRow-1].content + txt.substr(1)); + tx_getCursorPos(l,0,0); + } + else + { + newtxt = txt.substr(0,l.cursorCol) + txt.substr(l.cursorCol+1,txt.length); + tx_updateRow(l,l.cursorRow,newtxt); + if (l.cursorRow > 0) { var f = tx_wordWrapUp(l,l.cursorRow-1,l.rows[l.cursorRow-1].content,0); } + if (!f) tx_wordWrapUp(l,l.cursorRow,l.rows[l.cursorRow].content,0); + tx_getCursorPos(l,0,1); + } + } + else return true; + for(var i=0;i; + password = ; + + // Migrate centrallix password to mysql password. + //default_password = "newuserpass"; + set_passwords = "no"; + } diff --git a/centrallix-os/tests/UTF8_invalid.csv b/centrallix-os/tests/UTF8_invalid.csv new file mode 100644 index 000000000..4ee4caff8 --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid.csv @@ -0,0 +1,13 @@ +descripton,UTF8 +") short 2 byte :","жизнь" +") mixed :","index.не" +") longer 2 byte :","Οὕτως γὰρ ἠγάπησε ὁ Θεὸς τὸν" +") very short 2 byte :","что" +") very long 2 byte :","Ведь Бог так полюбил этот мир, что отдал Своего единственног Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь." +") 3 byte :","彼を信ずる者の亡びずして、永遠の生命を得んためなり。" +") short 3 byte :","世界を愛" +") very long 3 byte :","実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。" +") very short 3 byte :","めです" +") 4 byte :","𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈" +") short 4 byte :","𓂀𓂁𓂂𓂃𓂄" +") very long 4 byte :","𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" \ No newline at end of file diff --git a/centrallix-os/tests/UTF8_invalid.spec b/centrallix-os/tests/UTF8_invalid.spec new file mode 100644 index 000000000..55704b61b --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid.spec @@ -0,0 +1,15 @@ +$Version=2$ +UTF8_valid "application/filespec" + { + // General parameters. + filetype = csv; + header_row = yes; + header_has_titles = yes; + annotation = "UTF-8 test CSV Data"; + //row_annot_exp = ":full_name"; + key_is_rowid = yes; + + // Column specifications. + descripton "filespec/column" { type=string; id=1; } + UTF8 "filespec/column" { type=string; id=2; } + } diff --git a/centrallix-os/tests/UTF8_invalid0.csv b/centrallix-os/tests/UTF8_invalid0.csv new file mode 100644 index 000000000..4ee4caff8 --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid0.csv @@ -0,0 +1,13 @@ +descripton,UTF8 +") short 2 byte :","жизнь" +") mixed :","index.не" +") longer 2 byte :","Οὕτως γὰρ ἠγάπησε ὁ Θεὸς τὸν" +") very short 2 byte :","что" +") very long 2 byte :","Ведь Бог так полюбил этот мир, что отдал Своего единственног Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь." +") 3 byte :","彼を信ずる者の亡びずして、永遠の生命を得んためなり。" +") short 3 byte :","世界を愛" +") very long 3 byte :","実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。" +") very short 3 byte :","めです" +") 4 byte :","𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈" +") short 4 byte :","𓂀𓂁𓂂𓂃𓂄" +") very long 4 byte :","𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" \ No newline at end of file diff --git a/centrallix-os/tests/UTF8_invalid2.csv b/centrallix-os/tests/UTF8_invalid2.csv new file mode 100644 index 000000000..80973606e --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid2.csv @@ -0,0 +1,13 @@ +descripton,UTF8 +") short 2 byte :","жизнь" +") mixed :","index.не" +") longer 2 byte :","Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν" +") very short 2 byte :","что" +") very long 2 byte :","Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь." +") 3 byte :","彼を信ずる者の亡びずして、永遠の生命を得んためなり。" +") short 3 byte :","世界を愛" +") very long 3 byte :","実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。" +") very short 3 byte :","めです" +") 4 byte :","𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈" +") short 4 byte :","𓂀𓂁𓂂𓂃𓂄" +") very long 4 byte :","𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" \ No newline at end of file diff --git a/centrallix-os/tests/UTF8_invalid2.spec b/centrallix-os/tests/UTF8_invalid2.spec new file mode 100644 index 000000000..b7c9abb1f --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid2.spec @@ -0,0 +1,15 @@ +$Version=2$ +UTF8_valid "application/filespec" + { + // General parameters. + filetype = csv; + header_row = yes; + header_has_titles = yes; + annotation = "UTF-8test CSV Data"; + //row_annot_exp = ":full_name"; + key_is_rowid = yes; + + // Column specifications. + descripton "filespec/column" { type=string; id=1; } + UTF8 "filespec/column" { type=string; id=2; } + } diff --git a/centrallix-os/tests/UTF8_invalid3.csv b/centrallix-os/tests/UTF8_invalid3.csv new file mode 100644 index 000000000..cf8e3c786 --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid3.csv @@ -0,0 +1,13 @@ +descripton,UT8 +") short 2 byte :","жизнь" +") mixed :","index.не" +") longer 2 byte :","Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν" +") very short 2 byte :","что" +") very long 2 byte :","Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь." +") 3 byte :","彼を信ずる者の亡びずして、永遠の生命を得んためなり。" +") short 3 byte :","世界を愛" +") very long 3 byte :","実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。" +") very short 3 byte :","めです" +") 4 byte :","𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈" +") short 4 byte :","𓂀𓂁𓂂𓂃𓂄" +") very long 4 byte :","𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" \ No newline at end of file diff --git a/centrallix-os/tests/UTF8_invalid3.spec b/centrallix-os/tests/UTF8_invalid3.spec new file mode 100644 index 000000000..55704b61b --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid3.spec @@ -0,0 +1,15 @@ +$Version=2$ +UTF8_valid "application/filespec" + { + // General parameters. + filetype = csv; + header_row = yes; + header_has_titles = yes; + annotation = "UTF-8 test CSV Data"; + //row_annot_exp = ":full_name"; + key_is_rowid = yes; + + // Column specifications. + descripton "filespec/column" { type=string; id=1; } + UTF8 "filespec/column" { type=string; id=2; } + } diff --git a/centrallix-os/tests/UTF8_invalid4.csv b/centrallix-os/tests/UTF8_invalid4.csv new file mode 100644 index 000000000..cf8e3c786 --- /dev/null +++ b/centrallix-os/tests/UTF8_invalid4.csv @@ -0,0 +1,13 @@ +descripton,UT8 +") short 2 byte :","жизнь" +") mixed :","index.не" +") longer 2 byte :","Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν" +") very short 2 byte :","что" +") very long 2 byte :","Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь." +") 3 byte :","彼を信ずる者の亡びずして、永遠の生命を得んためなり。" +") short 3 byte :","世界を愛" +") very long 3 byte :","実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。" +") very short 3 byte :","めです" +") 4 byte :","𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈" +") short 4 byte :","𓂀𓂁𓂂𓂃𓂄" +") very long 4 byte :","𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" \ No newline at end of file diff --git a/centrallix-os/tests/UTF8_test_invalid0.rpt b/centrallix-os/tests/UTF8_test_invalid0.rpt new file mode 100644 index 000000000..18fc8e2c9 --- /dev/null +++ b/centrallix-os/tests/UTF8_test_invalid0.rpt @@ -0,0 +1,64 @@ +// +// +// Centrallix Test Suite +// +// "UTF8_test_valid.rpt" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_report_v3 driver's interactions +// with invalid UTF-8 characters. +// This file has invalid items within the internal struct +// +// WARNING: Saving this file in text mode (at least in vs code) +// will vonvert the invalid 0xFF character into the unicode sybol +// �. If this happens, use a hex editor to convert it back into 0xFF + +$Version=2$ +Datatypes "system/report" + { + title="Test UTF-8 #01 -Invalid UTF-8. Oh look, a change"; + + TestField1 "widget/textbutton" + { + text="Ведь Бог так полюбил этот"; + Child1 "widget/connector" {text="'жизнь.app'"; } + Child2 "widget/connector" {text="'index.не'"; } + Child3 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν"; + GreatGrandchild1 "fake/ident" + { + text="что"; + moreText="Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь."; + } + } + } + } + + TestField2 "widget/osrc" + { + Child1 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="彼を信ずる者の亡びずして、永遠の生命を得んためなり。"; + GreatGrandchild1 "fake/ident" + { + text="世界を愛"; + moreText="実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。"; + } + } + } + Child2 "widget/pane" {text="めです";} + Child3 "widget/pane" {text="test";} + } + + TestField3 "widget/osrc" + { + text="𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿"; + Child1 "widget/pane" {text="𓂀𓂁𓂂𓂃𓂄";} + Child2 "widget/pane" {text="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈";} + } + } diff --git a/centrallix-os/tests/UTF8_test_invalid1.rpt b/centrallix-os/tests/UTF8_test_invalid1.rpt new file mode 100644 index 000000000..7e0574662 --- /dev/null +++ b/centrallix-os/tests/UTF8_test_invalid1.rpt @@ -0,0 +1,47 @@ +// +// +// Centrallix Test Suite +// +// "UTF8_test_valid.rpt" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_report_v3 driver's interactions +// with invalid UTF-8 characters. +// This file has invalid items within the internal struct +// + +$Version=2$ +Datatypes "system/report" + { + title = "Test UTF-8 report #01 - Invalid UTF-8"; + + document_format="text/plain"; + text="Вед Бог так полюбил этот"; + + four_byte="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈"; + three_byte="世界を愛"; + two_byte="жизнь"; + + resolution = 300; + pagewidth=85; + pageheight=66; + marginleft=2.5; + marginright=2.5; + margintop=3; + marginbottom=3; + + dt_qy "report/query" + { + sql = "select * from /tests/UTF8_invalid.csv/rows"; + } + + dt_form "report/form" + { + source = dt_qy; + + dt_item "report/data" + { + value = runserver(:dt_qy:name + ' ' + :dt_qy:descripton + ' ' + :dt_qy:UTF8); + } + } + } diff --git a/centrallix-os/tests/UTF8_test_invalid2.rpt b/centrallix-os/tests/UTF8_test_invalid2.rpt new file mode 100644 index 000000000..4046935a1 --- /dev/null +++ b/centrallix-os/tests/UTF8_test_invalid2.rpt @@ -0,0 +1,47 @@ +// +// +// Centrallix Test Suite +// +// "UTF8_test_valid.rpt" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_report_v3 driver's interactions +// with invalid UTF-8 characters. +// This file has invalid items within the internal struct +// + +$Version=2$ +Datatypes "system/report" + { + title = "Test UTF-8 report #02 - Invalid UTF-8"; + + document_format="text/plain"; + text="Вед Бог так полюбил этот"; + + four_byte="𓅀𓅂𓅃𓅄𓅅𓅆𓅇𓅈"; + three_byte="世界を愛"; + two_byte="жизнь"; + + resolution = 300; + pagewidth=85; + pageheight=66; + marginleft=2.5; + marginright=2.5; + margintop=3; + marginbottom=3; + + dt_qy "report/query" + { + sql = "select * from /tests/UTF8_valid.csv/rows"; + } + + dt_form "report/form" + { + source = dt_qy; + + dt_item "report/data" + { + value = runserver(:dt_qy:name + ' ' + :dt_qy:descripton + ' ' + :dt_qy:UTF8); + } + } + } diff --git a/centrallix-os/tests/UTF8_test_invalid3.rpt b/centrallix-os/tests/UTF8_test_invalid3.rpt new file mode 100644 index 000000000..aa618ce16 --- /dev/null +++ b/centrallix-os/tests/UTF8_test_invalid3.rpt @@ -0,0 +1,47 @@ +// +// +// Centrallix Test Suite +// +// "UTF8_test_valid.rpt" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_report_v3 driver's interactions +// with invalid UTF-8 characters. +// This file has invalid items within the internal struct +// + +$Version=2$ +Datatypes "system/report" + { + title = "Test UTF-8 report #03 - Invalid UTF-8"; + + document_format="text/plain"; + text="Вед Бог так полюбил этот"; + + four_byte="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈"; + three_byte="世界を愛"; + two_byte="жизнь"; + + resolution = 300; + pagewidth=85; + pageheight=66; + marginleft=2.5; + marginright=2.5; + margintop=3; + marginbottom=3; + + dt_qy "report/query" + { + sql = "select * from /tests/UTF8_invalid2.csv/rows"; + } + + dt_form "report/form" + { + source = dt_qy; + + dt_item "report/data" + { + value = runserver(:dt_qy:name + ' ' + :dt_qy:descripton + ' ' + :dt_qy:UTF8); + } + } + } diff --git a/centrallix-os/tests/UTF8_test_invalid_1.app b/centrallix-os/tests/UTF8_test_invalid_1.app new file mode 100644 index 000000000..c6b075541 --- /dev/null +++ b/centrallix-os/tests/UTF8_test_invalid_1.app @@ -0,0 +1,65 @@ +// +// Centrallix Test Suite +// +// "UTF8_test_valid.app" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_struct driver's interactions +// with invalid UTF-8 characters. +// This does not reflect a typical .app file, but does +// prove that the objdrv handles invalid chracters properly +// (the errors being found by mtlexer) +// +// WARNING: Saving this file in text mode (at least in vs code) +// will vonvert the invalid 0xFF character into the unicode sybol +// �. If this happens, use a hex editor to convert it back into 0xFF + +$Version=2$ +Page1 "widget/page" + { + title="Test UTF-8 #01 -Invalid UTF-8"; + + TestField1 "widget/textbutton" + { + text="Ведь Бог так полюбил этот"; + Child1 "widget/connector" {text="'жизнь.app'"; } + Child2 "widget/connector" {text="'index.не'"; } + Child3 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν"; + GreatGrandchild1 "fake/ident" + { + text="что"; + moreText="Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь."; + } + } + } + } + + TestField2 "widget/osrc" + { + Child1 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="彼を信ずる者の亡びずして、永遠の生命を得んためなり。"; + GreatGrandchild1 "fake/ident" + { + text="世界を愛"; + moreText="実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。"; + } + } + } + Child2 "widget/pane" {text="めです";} + Child3 "widget/pane" {text="test";} + } + + TestField3 "widget/osrc" + { + text="𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿"; + Child1 "widget/pane" {text="𓂀𓂁𓂂𓂃𓂄";} + Child2 "widget/pane" {text="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈";} + } + } diff --git a/centrallix-os/tests/UTF8_test_invalid_2.app b/centrallix-os/tests/UTF8_test_invalid_2.app new file mode 100644 index 000000000..1a5ed9fd5 --- /dev/null +++ b/centrallix-os/tests/UTF8_test_invalid_2.app @@ -0,0 +1,62 @@ +// +// Centrallix Test Suite +// +// "UTF8_test_valid.appp" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_struct driver's interactions +// with invalid UTF-8 characters. +// This does not reflect a typical .app file, but does +// prove that the objdrv handles invalid chracters properly +// (the errors being found by mtlexer) +// + +$Version=2$ +Page1 "widget/page" + { + title="Test UTF-8 #02 - Invalid UTF-8"; + + TestField1 "widget/textbutton" + { + text="Ведь Бог так полюбил этот"; + Child1 "widget/connector" {text="'жизнь.app'"; } + Child2 "widget/connector" {text="'index.не'"; } + Child3 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν"; + GreatGrandchild1 "fake/ident" + { + text="чт � о"; + moreText="Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь."; + } + } + } + } + + TestField2 "widget/osrc" + { + Child1 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="彼を信ずる者の亡びずして、永遠の生命を得んためなり。"; + GreatGrandchild1 "fake/ident" + { + text="世界を愛"; + moreText="実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。"; + } + } + } + Child2 "widget/pane" {text="めです";} + Child3 "widget/pane" {text="test";} + } + + TestField3 "widget/osrc" + { + text="𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿"; + Child1 "widget/pane" {text="𓂀𓂁𓂂𓂃𓂄";} + Child2 "widget/pane" {text="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈";} + } + } diff --git a/centrallix-os/tests/UTF8_test_invalid_3.app b/centrallix-os/tests/UTF8_test_invalid_3.app new file mode 100644 index 000000000..4296044ef --- /dev/null +++ b/centrallix-os/tests/UTF8_test_invalid_3.app @@ -0,0 +1,62 @@ +// +// Centrallix Test Suite +// +// "UTF8_test_valid.appp" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_struct driver's interactions +// with invalid UTF-8 characters. +// This does not reflect a typical .app file, but does +// prove that the objdrv handles invalid chracters properly +// (the errors being found by mtlexer) +// + +$Version=2$ +Page1 "widget/page" + { + title="Test UTF-8 #03 -Invalid UTF-8"; + + TestField1 "widget/textbutton" + { + te�xt="Ведь Бог так полюбил этот"; + Child1 "widget/connector" {text="'жизнь.app'"; } + Child2 "widget/connector" {text="'index.не'"; } + Child3 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν"; + GreatGrandchild1 "fake/ident" + { + text="что"; + moreText="Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь."; + } + } + } + } + + TestField2 "widget/osrc" + { + Child1 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="彼を信ずる者の亡びずして、永遠の生命を得んためなり。"; + GreatGrandchild1 "fake/ident" + { + text="世界を愛"; + moreText="実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。"; + } + } + } + Child2 "widget/pane" {text="めです";} + Child3 "widget/pane" {text="test";} + } + + TestField3 "widget/osrc" + { + text="𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿"; + Child1 "widget/pane" {text="𓂀𓂁𓂂𓂃𓂄";} + Child2 "widget/pane" {text="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈";} + } + } diff --git a/centrallix-os/tests/UTF8_test_valid.app b/centrallix-os/tests/UTF8_test_valid.app new file mode 100644 index 000000000..47a77b29a --- /dev/null +++ b/centrallix-os/tests/UTF8_test_valid.app @@ -0,0 +1,62 @@ +// +// Centrallix Test Suite +// +// "UTF8_test_valid.appp" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_struct driver's interactions +// with valid UTF-8 characters. +// This does not reflect a typical .app file, but does +// prove that the objdrv can handle multibyte +// characters properly. +// + +$Version=2$ +Page1 "widget/page" + { + title="Test UTF-8 #00 - Valid UTF-8"; + + TestField1 "widget/textbutton" + { + text="Ведь Бог так полюбил этот"; + Child1 "widget/connector" {text="'жизнь.app'"; } + Child2 "widget/connector" {text="'index.не'"; } + Child3 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν"; + GreatGrandchild1 "fake/ident" + { + text="что"; + moreText="Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь."; + } + } + } + } + + TestField2 "widget/osrc" + { + Child1 "widget/pane" + { + Grandchild1 "I'm-making-this-up" + { + text="彼を信ずる者の亡びずして、永遠の生命を得んためなり。"; + GreatGrandchild1 "fake/ident" + { + text="世界を愛"; + moreText="実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。"; + } + } + } + Child2 "widget/pane" {text="めです";} + Child3 "widget/pane" {text="test";} + } + + TestField3 "widget/osrc" + { + text="𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿"; + Child1 "widget/pane" {text="𓂀𓂁𓂂𓂃𓂄";} + Child2 "widget/pane" {text="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈";} + } + } diff --git a/centrallix-os/tests/UTF8_test_valid.rpt b/centrallix-os/tests/UTF8_test_valid.rpt new file mode 100644 index 000000000..6d9c91061 --- /dev/null +++ b/centrallix-os/tests/UTF8_test_valid.rpt @@ -0,0 +1,48 @@ +// +// Centrallix Test Suite +// +// "UTF8_test_valid.rpt" +// By Noah Board - August 31, 2022 +// +// This app tests the objdrv_report_v3 driver's interactions +// with valid UTF-8 characters. +// This does not reflect a typical .rpt file, but does +// show that the report can handle multibyte +// characters properly. +// + +$Version=2$ +Datatypes "system/report" + { + title = "Test UTF-8 report #00 - Valid UTF-8"; + + document_format="text/plain"; + text="Ведь Бог так полюбил этот"; + + four_byte="𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈"; + three_byte="世界を愛"; + two_byte="жизнь"; + + resolution = 300; + pagewidth=85; + pageheight=66; + marginleft=2.5; + marginright=2.5; + margintop=3; + marginbottom=3; + + dt_qy "report/query" + { + sql = "select * from /tests/UTF8_valid.csv/rows"; + } + + dt_form "report/form" + { + source = dt_qy; + + dt_item "report/data" + { + value = runserver(:dt_qy:name + ' ' + :dt_qy:descripton + ' ' + :dt_qy:UTF8); + } + } + } diff --git a/centrallix-os/tests/UTF8_valid.csv b/centrallix-os/tests/UTF8_valid.csv new file mode 100644 index 000000000..80973606e --- /dev/null +++ b/centrallix-os/tests/UTF8_valid.csv @@ -0,0 +1,13 @@ +descripton,UTF8 +") short 2 byte :","жизнь" +") mixed :","index.не" +") longer 2 byte :","Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν" +") very short 2 byte :","что" +") very long 2 byte :","Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь." +") 3 byte :","彼を信ずる者の亡びずして、永遠の生命を得んためなり。" +") short 3 byte :","世界を愛" +") very long 3 byte :","実に神は、ひとり子をさえ惜しまず与えるほどに、この世界を愛してくださいました。それは、神の御子を信じる者が、だれ一人滅びず、永遠のいのちを得るためです。" +") very short 3 byte :","めです" +") 4 byte :","𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈" +") short 4 byte :","𓂀𓂁𓂂𓂃𓂄" +") very long 4 byte :","𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" \ No newline at end of file diff --git a/centrallix-os/tests/UTF8_valid.spec b/centrallix-os/tests/UTF8_valid.spec new file mode 100644 index 000000000..55704b61b --- /dev/null +++ b/centrallix-os/tests/UTF8_valid.spec @@ -0,0 +1,15 @@ +$Version=2$ +UTF8_valid "application/filespec" + { + // General parameters. + filetype = csv; + header_row = yes; + header_has_titles = yes; + annotation = "UTF-8 test CSV Data"; + //row_annot_exp = ":full_name"; + key_is_rowid = yes; + + // Column specifications. + descripton "filespec/column" { type=string; id=1; } + UTF8 "filespec/column" { type=string; id=2; } + } diff --git a/centrallix-os/tests/http/httpPostAppForm b/centrallix-os/tests/http/httpPostAppForm new file mode 100644 index 000000000..95dfb09ba --- /dev/null +++ b/centrallix-os/tests/http/httpPostAppForm @@ -0,0 +1,12 @@ +$Version=2$ +google "application/http" + { + server = "lightsys.org"; + path = "/testpost.php"; + protocol = "https"; + method = "POST"; + autosubdirs = 0; + cache_min_ttl = 3600000; // one hour + cache_max_ttl = 86400000; // one day + request_content_type = "application/x-www-form-urlencoded"; + } \ No newline at end of file diff --git a/centrallix-os/tests/http/httpPostAppJson b/centrallix-os/tests/http/httpPostAppJson new file mode 100644 index 000000000..d3401fb50 --- /dev/null +++ b/centrallix-os/tests/http/httpPostAppJson @@ -0,0 +1,12 @@ +$Version=2$ +google "application/http" + { + server = "lightsys.org"; + path = "/testpost.php"; + protocol = "https"; + method = "POST"; + autosubdirs = 0; + cache_min_ttl = 3600000; // one hour + cache_max_ttl = 86400000; // one day + request_content_type = "application/json"; + } \ No newline at end of file diff --git a/centrallix-os/tests/http/httpPostAppXml b/centrallix-os/tests/http/httpPostAppXml new file mode 100644 index 000000000..512a8ea57 --- /dev/null +++ b/centrallix-os/tests/http/httpPostAppXml @@ -0,0 +1,12 @@ +$Version=2$ +google "application/http" + { + server = "lightsys.org"; + path = "/testpost.php"; + protocol = "https"; + method = "POST"; + autosubdirs = 0; + cache_min_ttl = 3600000; // one hour + cache_max_ttl = 86400000; // one day + request_content_type = "application/xml"; + } \ No newline at end of file diff --git a/centrallix-os/tests/http/httpPostTextXml b/centrallix-os/tests/http/httpPostTextXml new file mode 100644 index 000000000..3986c3650 --- /dev/null +++ b/centrallix-os/tests/http/httpPostTextXml @@ -0,0 +1,12 @@ +$Version=2$ +google "application/http" + { + server = "lightsys.org"; + path = "/testpost.php"; + protocol = "https"; + method = "POST"; + autosubdirs = 0; + cache_min_ttl = 3600000; // one hour + cache_max_ttl = 86400000; // one day + request_content_type = "text/xml"; + } \ No newline at end of file diff --git a/centrallix-os/tests/invalidFileName/dir1/normal b/centrallix-os/tests/invalidFileName/dir1/normal new file mode 100644 index 000000000..f41708c83 --- /dev/null +++ b/centrallix-os/tests/invalidFileName/dir1/normal @@ -0,0 +1 @@ +This is just a normal file. diff --git "a/centrallix-os/tests/invalidFileName/dir\377/lost" "b/centrallix-os/tests/invalidFileName/dir\377/lost" new file mode 100644 index 000000000..4c837ba50 --- /dev/null +++ "b/centrallix-os/tests/invalidFileName/dir\377/lost" @@ -0,0 +1 @@ +this file is lots because it is inside of a directory with an invalid name diff --git a/centrallix-os/tests/invalidFileName/test.txt b/centrallix-os/tests/invalidFileName/test.txt new file mode 100644 index 000000000..426863280 --- /dev/null +++ b/centrallix-os/tests/invalidFileName/test.txt @@ -0,0 +1 @@ +some data diff --git "a/centrallix-os/tests/invalidFileName/test\377.txt" "b/centrallix-os/tests/invalidFileName/test\377.txt" new file mode 100644 index 000000000..426863280 --- /dev/null +++ "b/centrallix-os/tests/invalidFileName/test\377.txt" @@ -0,0 +1 @@ +some data diff --git a/centrallix-os/tests/long_utf8.json b/centrallix-os/tests/long_utf8.json new file mode 100644 index 000000000..457cc4308 --- /dev/null +++ b/centrallix-os/tests/long_utf8.json @@ -0,0 +1,32 @@ +{ + "data":[ + { + "id":1, + "text":"This is a bunch of ascii test. There are many ascii texts like this, but this one is here and being used for this test. The default length appears to be around 255 so we need to exceed that length with this test. Hence, the long and almost meaningless rant you see now before you" + }, + { + "id":2, + "text":"ͰͱͲͳʹ͵Ͷͷͺͻͼͽ;΄΅ΆΈΉΊΌΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϏϐϑϒϓϔϕϖϗϘϙϚϛϜϝϞϟϠϡϢϣϤϥϦϧϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿ" + }, + { + "id":3, + "text":"実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。" + }, + { + "id":4, + "text":"𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" + }, + { + "id":5, + "text":"|Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌��|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀��|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯||Æ߷|��🦗|𠀀蜨|𰀀𲎯||Æ߷|𐊌🦗|𠀀蜨|𰀀𲎯|" + }, + { + "id":6, + "text":"hi" + }, + { + "id":7, + "text":"🪿!#%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖՙ՚՛՜՝՞՟ՠաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆեւֈ։֊֍֎֏𐔰𐔱𐔲𐔳𐔴𐔵𐔶𐔷𐔸𐔹𐔺𐔻𐔼𐔽𐔾𐔿𐕀𐕁𐕂𐕃𐕄𐕅𐕆𐕇𐕈𐕉𐕊𐕋𐕌𐕍𐕎𐕏𐕐𐕑𐕒𐕓𐕔𐕕𐕖𐕗𐕘𐕙𐕚𐕛𐕜𐕝𐕞𐕟𐕠𐕡𐕢𐕣𐕯¡¢£¤¥¦§ ̈©ª«¬® ̄°±²³ ́μ¶· ̧¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľL·l·ŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžs𐲀𐲁𐲂𐲃𐲄𐲅𐲆𐲇𐲈𐲉𐲊𐲋𐲌𐲍𐲎𐲏𐲐𐲑𐲒𐲓𐲔𐲕𐲖𐲗𐲘𐲙𐲚𐲛𐲜𐲝𐲞𐲟𐲠𐲡𐲢𐲣𐲤𐲥𐲦𐲧𐲨𐲩𐲪𐲫𐲬𐲭𐲮𐲯𐲰𐲱𐲲𐳀𐳁𐳂𐳃𐳄𐳅𐳆𐳇𐳈𐳉𐳊𐳋𐳌𐳍𐳎𐳏𐳐𐳑𐳒𐳓𐳔𐳕𐳖𐳗𐳘𐳙𐳚𐳛𐳜𐳝𐳞𐳟𐳠𐳡𐳢𐳣𐳤𐳥𐳦𐳧𐳨𐳩𐳪𐳫𐳬𐳭𐳮𐳯𐳰𐳱𐳲𐳺𐳻𐳼𐳽𐳾𐳿🨀🨁🨂🨃🨄🨅🨆🨇🨈🨉🨊🨋🨌🨍🨎🨏🨐🨑🨒🨓🨔🨕🨖🨗🨘🨙🨚🨛🨜🨝🨞🨟🨠🨡🨢🨣🨤🨥🨦🨧🨨🨩🨪🨫🨬🨭🨮🨯🨰🨱🨲🨳🨴🨵🨶🨷🨸🨹🨺🨻🨼🨽🨾🨿🩀🩁🩂🩃🩄🩅🩆🩇🩈🩉🩊🩋🩌🩍🩎🩏🩐🩑🩒🩓🩠🩡🩢🩣🩤🩥🩦🩧🩨🩩🩪🩫🩬🩭🜀🜁🜂🜃🜄🜅🜆🜇🜈🜉🜊🜋🜌🜍🜎🜏🜐🜑🜒🜓🜔🜕🜖🜗🜘🜙🜚🜛🜜🜝🜞🜟🜠🜡🜢🜣🜤🜥🜦🜧🜨🜩🜪🜫🜬🜭🜮🜯🜰🜱🜲🜳🜴🜵🜶🜷🜸🜹🜺🜻🜼🜽🜾🜿🝀🝁🝂🝃🝄🝅🝆🝇🝈🝉🝊🝋🝌🝍🝎🝏🝐🝑🝒🝓🝔🝕🝖🝗🝘🝙🝚🝛🝜🝝🝞🝟🝠🝡🝢🝣🝤🝥🝦🝧🝨🝩🝪🝫🝬🝭🝮🝯🝰🝱🝲🝳🝴🝵🝶🝻🝼🝽🝾🝿⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿𝄀𝄁𝄂𝄃𝄄𝄅𝄆𝄇𝄈𝄉𝄊𝄋𝄌𝄍𝄎𝄏𝄐𝄑𝄒𝄓𝄔𝄕𝄖𝄗𝄘𝄙𝄚𝄛𝄜𝄝𝄞𝄟𝄠𝄡𝄢𝄣𝄤𝄥𝄦𝄩𝄪𝄫𝄬𝄭𝄮𝄯𝄰𝄱𝄲𝄳𝄴𝄵𝄶𝄷𝄸𝄹𝄺𝄻𝄼𝄽𝄾𝄿𝅀𝅁𝅂𝅃𝅄𝅅𝅆𝅇𝅈𝅉𝅊𝅋𝅌𝅍𝅎𝅏𝅐𝅑𝅒𝅓𝅔𝅕𝅖𝅗𝅘𝅚𝅛𝅜𝅝𝅗𝅥𝅘𝅥𝅘𝅥𝅮𝅘𝅥𝅯𝅘𝅥𝅰𝅘𝅥𝅱𝅘𝅧𝅨𝅩𝅥𝅲𝅥𝅦𝅪𝅫𝅬𝅮𝅯𝅰𝅱𝅲𝅭𝅻𝅼𝅽𝅾𝅿𝆀𝆁𝆂𝆃𝆄𝆊𝆋𝆅𝆆𝆇𝆈𝆉𝆌𝆍𝆎𝆏𝆐𝆑𝆒𝆓𝆔𝆕𝆖𝆗𝆘𝆙𝆚𝆛𝆜𝆝𝆞𝆟𝆠𝆡𝆢𝆣𝆤𝆥𝆦𝆧𝆨𝆩𝆪𝆫𝆬𝆭𝆮𝆯𝆰𝆱𝆲𝆳𝆴𝆵𝆶𝆷𝆸𝆹𝆺𝆹𝅥𝆺𝅥𝆹𝅥𝅮𝆺𝅥𝅮𝆹𝅥𝅯𝆺𝅥𝅯𝇁𝇂𝇃𝇄𝇅𝇆𝇇𝇈𝇉𝇊𝇋𝇌𝇍𝇎𝇏𝇐𝇑𝇒𝇓𝇔𝇕𝇖𝇗𝇘𝇙𝇚𝇛𝇜𝇝𝇞𝇟✀✁✂✃✄✅✆✇✈✉✊✋✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✨✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞❜❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➕➖➗➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➰➱➲➳➴➵➶➷➸➹➺➻➼➽➾➿🩰🩱🩲🩳🩴🩵🩶🩷🩸🩹🩺🩻🩼🪀🪁🪂🪃🪄🪅🪆🪇🪈🪐🪑🪒🪓🪔🪕🪖🪗🪘🪙🪚🪛🪜🪝🪞🪟🪠🪡🪢🪣🪤🪥🪦🪧🪨🪩🪪🪫🪬🪭🪮🪯🪰🪱🪲🪳🪴🪵🪶🪷🪸🪹🪺🪻🪼🪽🪿🫀🫁🫂🫃🫄🫅🫎🫏🫐🫑🫒🫓🫔🫕🫖🫗🫘🫙🫚🫛🫠🫡🫢🫣🫤🫥🫦🫧🫨🫰🫱🫲🫳🫴🫵🫶🫷🫸🚀🚁🚂🚃🚄🚅🚆🚇🚈🚉🚊🚋🚌🚍🚎🚏🚐🚑🚒🚓🚔🚕🚖🚗🚘🚙🚚🚛🚜🚝🚞🚟🚠🚡🚢🚣🚤🚥🚦🚧🚨🚩🚪🚫🚬🚭🚮🚯🚰🚱🚲🚳🚴🚵🚶🚷🚸🚹🚺🚻🚼🚽🚾🚿🛀🛁🛂🛃🛄🛅🛆🛇🛈🛉🛊🛋🛌🛍🛎🛏🛐🛑🛒🛓🛔🛕🛖🛗🛜🛝🛞🛟🛠🛡🛢🛣🛤🛥🛦🛧🛨🛩🛪🛫🛬🛰🛱🛲🛳🛴🛵🛶🛷🛸🛹🛺🛻🛼😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮😯😰😱😲😳😴😵😶😷😸😹😺😻😼😽😾😿🙀🙁🙂🙃🙄🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ$゙$゚ ゙ ゚ゝゞゟ߁߂߃߄߅߆߇߈߉ߊߋߌߍߎߏߐߑߒߓߔߕߖߗߘߙߚߛߜߝߞߟߠߡߢߣߤߥߦߧߨߩߪ߲߫߬߭߮߯߰߱߳ߴߵ߶߷߸߹ߺ߽߾߿ᎠᎡᎢᎣᎤᎥᎦᎧᎨᎩᎪᎫᎬᎭᎮᎯᎰᎱᎲᎳᎴᎵᎶᎷᎸᎹᎺᎻᎼᎽᎾᎿᏀᏁᏂᏃᏄᏅᏆᏇᏈᏉᏊᏋᏌᏍᏎᏏᏐᏑᏒᏓᏔᏕᏖᏗᏘᏙᏚᏛᏜᏝᏞᏟᏠᏡᏢᏣᏤᏥᏦᏧᏨᏩᏪᏫᏬᏭᏮᏯᏰᏱᏲᏳᏴᏵᏸᏹᏺᏻᏼᏽ𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿𓂀𓂁𓂂𓂃𓂄𓂅𓂆𓂇𓂈𓂉𓂊𓂋𓂌𓂍𓂎𓂏𓂐𓂑𓂒𓂓𓂔𓂕𓂖𓂗𓂘𓂙𓂚𓂛𓂜𓂝𓂞𓂟𓂠𓂡𓂢𓂣𓂤𓂥𓂦𓂧𓂨𓂩𓂪𓂫𓂬𓂭𓂮𓂯𓂰𓂱𓂲𓂳𓂴𓂵𓂶𓂷𓂸𓂹𓂺𓂻𓂼𓂽𓂾𓂿𓃀𓃁𓃂𓃃𓃄𓃅𓃆𓃇𓃈𓃉𓃊𓃋𓃌𓃍𓃎𓃏𓃐𓃑𓃒𓃓𓃔𓃕𓃖𓃗𓃘𓃙𓃚𓃛𓃜𓃝𓃞𓃟𓃠𓃡𓃢𓃣𓃤𓃥𓃦𓃧𓃨𓃩𓃪𓃫𓃬𓃭𓃮𓃯𓃰𓃱𓃲𓃳𓃴𓃵𓃶𓃷𓃸𓃹𓃺𓃻𓃼𓃽𓃾𓃿𓄀𓄁𓄂𓄃𓄄𓄅𓄆𓄇𓄈𓄉𓄊𓄋𓄌𓄍𓄎𓄏𓄐𓄑𓄒𓄓𓄔𓄕𓄖𓄗𓄘𓄙𓄚𓄛𓄜𓄝𓄞𓄟𓄠𓄡𓄢𓄣𓄤𓄥𓄦𓄧𓄨𓄩𓄪𓄫𓄬𓄭𓄮𓄯𓄰𓄱𓄲𓄳𓄴𓄵𓄶𓄷𓄸𓄹𓄺𓄻𓄼𓄽𓄾𓄿𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈𓅉𓅊𓅋𓅌𓅍𓅎𓅏𓅐𓅑𓅒𓅓𓅔𓅕𓅖𓅗𓅘𓅙𓅚𓅛𓅜𓅝𓅞𓅟𓅠𓅡𓅢𓅣𓅤𓅥𓅦𓅧𓅨𓅩𓅪𓅫𓅬𓅭𓅮𓅯𓅰𓅱𓅲𓅳𓅴𓅵𓅶𓅷𓅸𓅹𓅺𓅻𓅼𓅽𓅾𓅿𓆀𓆁𓆂𓆃𓆄𓆅𓆆𓆇𓆈𓆉𓆊𓆋𓆌𓆍𓆎𓆏𓆐𓆑𓆒𓆓𓆔𓆕𓆖𓆗𓆘𓆙𓆚𓆛𓆜𓆝𓆞𓆟𓆠𓆡𓆢𓆣𓆤𓆥𓆦𓆧𓆨𓆩𓆪𓆫𓆬𓆭𓆮𓆯𓆰𓆱𓆲𓆳𓆴𓆵𓆶𓆷𓆸𓆹𓆺𓆻𓆼𓆽𓆾𓆿𓇀𓇁𓇂𓇃𓇄𓇅𓇆𓇇𓇈𓇉𓇊𓇋𓇌𓇍𓇎𓇏𓇐𓇑𓇒𓇓𓇔𓇕𓇖𓇗𓇘𓇙𓇚𓇛𓇜𓇝𓇞𓇟𓇠𓇡𓇢𓇣𓇤𓇥𓇦𓇧𓇨𓇩𓇪𓇫𓇬𓇭𓇮𓇯𓇰𓇱𓇲𓇳𓇴𓇵𓇶𓇷𓇸𓇹𓇺𓇻𓇼𓇽𓇾𓇿𓈀𓈁𓈂𓈃𓈄𓈅𓈆𓈇𓈈𓈉𓈊𓈋𓈌𓈍𓈎𓈏𓈐𓈑𓈒𓈓𓈔𓈕𓈖𓈗𓈘𓈙𓈚𓈛𓈜𓈝𓈞𓈟𓈠𓈡𓈢𓈣𓈤𓈥𓈦𓈧𓈨𓈩𓈪𓈫𓈬𓈭𓈮𓈯𓈰𓈱𓈲𓈳𓈴𓈵𓈶𓈷𓈸𓈹𓈺𓈻𓈼𓈽𓈾𓈿𓉀𓉁𓉂𓉃𓉄𓉅𓉆𓉇𓉈𓉉𓉊𓉋𓉌𓉍𓉎𓉏𓉐𓉑𓉒𓉓𓉔𓉕𓉖𓉗𓉘𓉙𓉚𓉛𓉜𓉝𓉞𓉟𓉠𓉡𓉢𓉣𓉤𓉥𓉦𓉧𓉨𓉩𓉪𓉫𓉬𓉭𓉮𓉯𓉰𓉱𓉲𓉳𓉴𓉵𓉶𓉷𓉸𓉹𓉺𓉻𓉼𓉽𓉾𓉿𓊀𓊁𓊂𓊃𓊄𓊅𓊆𓊇𓊈𓊉𓊊𓊋𓊌𓊍𓊎𓊏𓊐𓊑𓊒𓊓𓊔𓊕𓊖𓊗𓊘𓊙𓊚𓊛𓊜𓊝𓊞𓊟𓊠𓊡𓊢𓊣𓊤𓊥𓊦𓊧𓊨𓊩𓊪𓊫𓊬𓊭𓊮𓊯𓊰𓊱𓊲𓊳𓊴𓊵𓊶𓊷𓊸𓊹𓊺𓊻𓊼𓊽𓊾𓊿𓋀𓋁𓋂𓋃𓋄𓋅𓋆𓋇𓋈𓋉𓋊𓋋𓋌𓋍𓋎𓋏𓋐𓋑𓋒𓋓𓋔𓋕𓋖𓋗𓋘𓋙𓋚𓋛𓋜𓋝𓋞𓋟𓋠𓋡𓋢𓋣𓋤𓋥𓋦𓋧𓋨𓋩𓋪𓋫𓋬𓋭𓋮𓋯𓋰𓋱𓋲𓋳𓋴𓋵𓋶𓋷𓋸𓋹𓋺𓋻𓋼𓋽𓋾𓋿𓌀𓌁𓌂𓌃𓌄𓌅𓌆𓌇𓌈𓌉𓌊𓌋𓌌𓌍𓌎𓌏𓌐𓌑𓌒𓌓𓌔𓌕𓌖𓌗𓌘𓌙𓌚𓌛𓌜𓌝𓌞𓌟𓌠𓌡𓌢𓌣𓌤𓌥𓌦𓌧𓌨𓌩𓌪𓌫𓌬𓌭𓌮𓌯𓌰𓌱𓌲𓌳𓌴𓌵𓌶𓌷𓌸𓌹𓌺𓌻𓌼𓌽𓌾𓌿𓍀𓍁𓍂𓍃𓍄𓍅𓍆𓍇𓍈𓍉𓍊𓍋𓍌𓍍𓍎𓍏𓍐𓍑𓍒𓍓𓍔𓍕𓍖𓍗𓍘𓍙𓍚𓍛𓍜𓍝𓍞𓍟𓍠𓍡𓍢𓍣𓍤𓍥𓍦𓍧𓍨𓍩𓍪𓍫𓍬𓍭𓍮𓍯𓍰𓍱𓍲𓍳𓍴𓍵𓍶𓍷𓍸𓍹𓍺𓍻𓍼𓍽𓍾𓍿𓎀𓎁𓎂𓎃𓎄𓎅𓎆𓎇𓎈𓎉𓎊𓎋𓎌𓎍𓎎𓎏𓎐𓎑𓎒𓎓𓎔𓎕𓎖𓎗𓎘𓎙𓎚𓎛𓎜𓎝𓎞𓎟𓎠𓎡𓎢𓎣𓎤𓎥𓎦𓎧𓎨𓎩𓎪𓎫𓎬𓎭𓎮𓎯𓎰𓎱𓎲𓎳𓎴𓎵𓎶𓎷𓎸𓎹𓎺𓎻𓎼𓎽𓎾𓎿𓏀𓏁𓏂𓏃𓏄𓏅𓏆𓏇𓏈𓏉𓏊𓏋𓏌𓏍𓏎𓏏𓏐𓏑𓏒𓏓𓏔𓏕𓏖𓏗𓏘𓏙𓏚𓏛𓏜𓏝𓏞𓏟𓏠𓏡𓏢𓏣𓏤𓏥𓏦𓏧𓏨𓏩𓏪𓏫𓏬𓏭𓏮𓏯𓏰𓏱𓏲𓏳𓏴𓏵𓏶𓏷𓏸𓏹𓏺𓏻𓏼𓏽𓏾𓏿𓐀𓐁𓐂𓐃𓐄𓐅𓐆𓐇𓐈𓐉𓐊𓐋𓐌𓐍𓐎𓐏𓐐𓐑𓐒𓐓𓐔𓐕𓐖𓐗𓐘𓐙𓐚𓐛𓐜𓐝𓐞𓐟𓐠𓐡𓐢𓐣𓐤𓐥𓐦𓐧𓐨𓐩𓐪𓐫𓐬𓐭𓐮𓐯🐀🐁🐂🐃🐄🐅🐆🐇🐈🐉🐊🐋🐌🐍🐎🐏🐐🐑🐒🐓🐔🐕🐖🐗🐘🐙🐚🐛🐜🐝🐞🐟🐠🐡🐢🐣🐤🐥🐦🐧🐨🐩🐪🐫🐬🐭🐮🐯🐰🐱🐲🐳🐴🐵🐶🐷🐸🐹🐺🐻🐼🐽🐾🐿👀👁👂👃👄👅👆👇👈👉👊👋👌👍👎👏👐👑👒👓👔👕👖👗👘👙👚👛👜👝👞👟👠👡👢👣👤👥👦👧👨👩👪👫👬👭👮👯👰👱👲👳👴👵👶👷👸👹👺👻👼👽👾👿💀💁💂💃💄💅💆💇💈💉💊💋💌💍💎💏💐💑💒💓💔💕💖💗💘💙💚💛💜💝💞💟💠💡💢💣💤💥💦💧💨💩💪💫💬💭💮💯💰💱💲💳💴💵💶💷💸💹💺💻💼💽💾💿📀📁📂📃📄📅📆📇📈📉📊📋📌📍📎📏📐📑📒📓📔📕📖📗📘📙📚📛📜📝📞📟📠📡📢📣📤📥📦📧📨📩📪📫📬📭📮📯📰📱📲📳📴📵📶📷📸📹📺📻📼📽📾📿🔀🔁🔂🔃🔄🔅🔆🔇🔈🔉🔊🔋🔌🔍🔎🔏🔐🔑🔒🔓🔔🔕🔖🔗🔘🔙🔚🔛🔜🔝🔞🔟🔠🔡🔢🔣🔤🔥🔦🔧🔨🔩🔪🔫🔬🔭🔮🔯🔰🔱🔲🔳🔴🔵🔶🔷🔸🔹🔺🔻🔼🔽🔾🔿🕀🕁🕂🕃🕄🕅🕆🕇🕈🕉🕊🕋🕌🕍🕎🕏🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧🕨🕩🕪🕫🕬🕭🕮🕯🕰🕱🕲🕳🕴🕵🕶🕷🕸🕹🕺🕻🕼🕽TEL🕿🖀🖁🖂🖃🖄🖅🖆🖇🖈🖉🖊🖋🖌🖍🖎🖏🖐🖑🖒🖓🖔🖕🖖🖗🖘🖙🖚🖛🖜🖝🖞🖟🖠🖡🖢🖣🖤🖥🖦🖧🖨🖩🖪🖫🖬🖭🖮🖯🖰🖱🖲🖳🖴🖵🖶🖷🖸🖹🖺🖻🖼🖽🖾🖿🗀🗁🗂🗃🗄🗅🗆🗇🗈🗉🗊🗋🗌🗍🗎🗏🗐🗑🗒🗓🗔🗕🗖🗗🗘🗙🗚🗛🗜🗝🗞🗟🗠🗡🗢🗣🗤🗥🗦🗧🗨🗩🗪🗫🗬🗭🗮🗯🗰🗱🗲🗳🗴🗵🗶🗷🗸🗹🗺🗻🗼🗽🗾🗿🤀🤁🤂🤃🤄🤅🤆🤇🤈🤉🤊🤋🤌🤍🤎🤏🤐🤑🤒🤓🤔🤕🤖🤗🤘🤙🤚🤛🤜🤝🤞🤟🤠🤡🤢🤣🤤🤥🤦🤧🤨🤩🤪🤫🤬🤭🤮🤯🤰🤱🤲🤳🤴🤵🤶🤷🤸🤹🤺🤻🤼🤽🤾🤿🥀🥁🥂🥃🥄🥅🥆🥇🥈🥉🥊🥋🥌🥍🥎🥏🥐🥑🥒🥓🥔🥕🥖🥗🥘🥙🥚🥛🥜🥝🥞🥟🥠🥡🥢🥣🥤🥥🥦🥧🥨🥩🥪🥫🥬🥭🥮🥯🥰🥱🥲🥳🥴🥵🥶🥷🥸🥹🥺🥻🥼🥽🥾🥿🦀🦁🦂🦃🦄🦅🦆🦇🦈🦉🦊🦋🦌🦍🦎🦏🦐🦑🦒🦓🦔🦕🦖🦗🦘🦙🦚🦛🦜🦝🦞🦟🦠🦡🦢🦣🦤🦥🦦🦧🦨🦩🦪🦫🦬🦭🦮🦯🦰🦱🦲🦳🦴🦵🦶🦷🦸🦹🦺🦻🦼🦽🦾🦿🧀🧁🧂🧃🧄🧅🧆🧇🧈🧉🧊🧋🧌🧍🧎🧏🧐🧑🧒🧓🧔🧕🧖🧗🧘🧙🧚🧛🧜🧝🧞🧟🧠🧡🧢🧣🧤🧥🧦🧧🧨🧩🧪🧫🧬🧭🧮🧯🧰🧱🧲🧳🧴🧵🧶🧷🧸🧹🧺🧻🧼🧽🧾🧿🪿🪿!#%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖՙ՚՛՜՝՞՟ՠաբգդեզէըթժիլխծկհձղճմյնշոչպջռսվտրցւփքօֆեւֈ։֊֍֎֏𐔰𐔱𐔲𐔳𐔴𐔵𐔶𐔷𐔸𐔹𐔺𐔻𐔼𐔽𐔾𐔿𐕀𐕁𐕂𐕃𐕄𐕅𐕆𐕇𐕈𐕉𐕊𐕋𐕌𐕍𐕎𐕏𐕐𐕑𐕒𐕓𐕔𐕕𐕖𐕗𐕘𐕙𐕚𐕛𐕜𐕝𐕞𐕟𐕠𐕡𐕢𐕣𐕯¡¢£¤¥¦§ ̈©ª«¬® ̄°±²³ ́μ¶· ̧¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľL·l·ŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžs𐲀𐲁𐲂𐲃𐲄𐲅𐲆𐲇𐲈𐲉𐲊𐲋𐲌𐲍𐲎𐲏𐲐𐲑𐲒𐲓𐲔𐲕𐲖𐲗𐲘𐲙𐲚𐲛𐲜𐲝𐲞𐲟𐲠𐲡𐲢𐲣𐲤𐲥𐲦𐲧𐲨𐲩𐲪𐲫𐲬𐲭𐲮𐲯𐲰𐲱𐲲𐳀𐳁𐳂𐳃𐳄𐳅𐳆𐳇𐳈𐳉𐳊𐳋𐳌𐳍𐳎𐳏𐳐𐳑𐳒𐳓𐳔𐳕𐳖𐳗𐳘𐳙𐳚𐳛𐳜𐳝𐳞𐳟𐳠𐳡𐳢𐳣𐳤𐳥𐳦𐳧𐳨𐳩𐳪𐳫𐳬𐳭𐳮𐳯𐳰𐳱𐳲𐳺𐳻𐳼𐳽𐳾𐳿🨀🨁🨂🨃🨄🨅🨆🨇🨈🨉🨊🨋🨌🨍🨎🨏🨐🨑🨒🨓🨔🨕🨖🨗🨘🨙🨚🨛🨜🨝🨞🨟🨠🨡🨢🨣🨤🨥🨦🨧🨨🨩🨪🨫🨬🨭🨮🨯🨰🨱🨲🨳🨴🨵🨶🨷🨸🨹🨺🨻🨼🨽🨾🨿🩀🩁🩂🩃🩄🩅🩆🩇🩈🩉🩊🩋🩌🩍🩎🩏🩐🩑🩒🩓🩠🩡🩢🩣🩤🩥🩦🩧🩨🩩🩪🩫🩬🩭🜀🜁🜂🜃🜄🜅🜆🜇🜈🜉🜊🜋🜌🜍🜎🜏🜐🜑🜒🜓🜔🜕🜖🜗🜘🜙🜚🜛🜜🜝🜞🜟🜠🜡🜢🜣🜤🜥🜦🜧🜨🜩🜪🜫🜬🜭🜮🜯🜰🜱🜲🜳🜴🜵🜶🜷🜸🜹🜺🜻🜼🜽🜾🜿🝀🝁🝂🝃🝄🝅🝆🝇🝈🝉🝊🝋🝌🝍🝎🝏🝐🝑🝒🝓🝔🝕🝖🝗🝘🝙🝚🝛🝜🝝🝞🝟🝠🝡🝢🝣🝤🝥🝦🝧🝨🝩🝪🝫🝬🝭🝮🝯🝰🝱🝲🝳🝴🝵🝶🝻🝼🝽🝾🝿⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖⠗⠘⠙⠚⠛⠜⠝⠞⠟⠠⠡⠢⠣⠤⠥⠦⠧⠨⠩⠪⠫⠬⠭⠮⠯⠰⠱⠲⠳⠴⠵⠶⠷⠸⠹⠺⠻⠼⠽⠾⠿⡀⡁⡂⡃⡄⡅⡆⡇⡈⡉⡊⡋⡌⡍⡎⡏⡐⡑⡒⡓⡔⡕⡖⡗⡘⡙⡚⡛⡜⡝⡞⡟⡠⡡⡢⡣⡤⡥⡦⡧⡨⡩⡪⡫⡬⡭⡮⡯⡰⡱⡲⡳⡴⡵⡶⡷⡸⡹⡺⡻⡼⡽⡾⡿⢀⢁⢂⢃⢄⢅⢆⢇⢈⢉⢊⢋⢌⢍⢎⢏⢐⢑⢒⢓⢔⢕⢖⢗⢘⢙⢚⢛⢜⢝⢞⢟⢠⢡⢢⢣⢤⢥⢦⢧⢨⢩⢪⢫⢬⢭⢮⢯⢰⢱⢲⢳⢴⢵⢶⢷⢸⢹⢺⢻⢼⢽⢾⢿⣀⣁⣂⣃⣄⣅⣆⣇⣈⣉⣊⣋⣌⣍⣎⣏⣐⣑⣒⣓⣔⣕⣖⣗⣘⣙⣚⣛⣜⣝⣞⣟⣠⣡⣢⣣⣤⣥⣦⣧⣨⣩⣪⣫⣬⣭⣮⣯⣰⣱⣲⣳⣴⣵⣶⣷⣸⣹⣺⣻⣼⣽⣾⣿𝄀𝄁𝄂𝄃𝄄𝄅𝄆𝄇𝄈𝄉𝄊𝄋𝄌𝄍𝄎𝄏𝄐𝄑𝄒𝄓𝄔𝄕𝄖𝄗𝄘𝄙𝄚𝄛𝄜𝄝𝄞𝄟𝄠𝄡𝄢𝄣𝄤𝄥𝄦𝄩𝄪𝄫𝄬𝄭𝄮𝄯𝄰𝄱𝄲𝄳𝄴𝄵𝄶𝄷𝄸𝄹𝄺𝄻𝄼𝄽𝄾𝄿𝅀𝅁𝅂𝅃𝅄𝅅𝅆𝅇𝅈𝅉𝅊𝅋𝅌𝅍𝅎𝅏𝅐𝅑𝅒𝅓𝅔𝅕𝅖𝅗𝅘𝅚𝅛𝅜𝅝𝅗𝅥𝅘𝅥𝅘𝅥𝅮𝅘𝅥𝅯𝅘𝅥𝅰𝅘𝅥𝅱𝅘𝅧𝅨𝅩𝅥𝅲𝅥𝅦𝅪𝅫𝅬𝅮𝅯𝅰𝅱𝅲𝅭𝅻𝅼𝅽𝅾𝅿𝆀𝆁𝆂𝆃𝆄𝆊𝆋𝆅𝆆𝆇𝆈𝆉𝆌𝆍𝆎𝆏𝆐𝆑𝆒𝆓𝆔𝆕𝆖𝆗𝆘𝆙𝆚𝆛𝆜𝆝𝆞𝆟𝆠𝆡𝆢𝆣𝆤𝆥𝆦𝆧𝆨𝆩𝆪𝆫𝆬𝆭𝆮𝆯𝆰𝆱𝆲𝆳𝆴𝆵𝆶𝆷𝆸𝆹𝆺𝆹𝅥𝆺𝅥𝆹𝅥𝅮𝆺𝅥𝅮𝆹𝅥𝅯𝆺𝅥𝅯𝇁𝇂𝇃𝇄𝇅𝇆𝇇𝇈𝇉𝇊𝇋𝇌𝇍𝇎𝇏𝇐𝇑𝇒𝇓𝇔𝇕𝇖𝇗𝇘𝇙𝇚𝇛𝇜𝇝𝇞𝇟✀✁✂✃✄✅✆✇✈✉✊✋✌✍✎✏✐✑✒✓✔✕✖✗✘✙✚✛✜✝✞✟✠✡✢✣✤✥✦✧✨✩✪✫✬✭✮✯✰✱✲✳✴✵✶✷✸✹✺✻✼✽✾✿❀❁❂❃❄❅❆❇❈❉❊❋❌❍❎❏❐❑❒❓❔❕❖❗❘❙❚❛❜❝❞❜❞❡❢❣❤❥❦❧❨❩❪❫❬❭❮❯❰❱❲❳❴❵❶❷❸❹❺❻❼❽❾❿➀➁➂➃➄➅➆➇➈➉➊➋➌➍➎➏➐➑➒➓➔➕➖➗➘➙➚➛➜➝➞➟➠➡➢➣➤➥➦➧➨➩➪➫➬➭➮➯➰➱➲➳➴➵➶➷➸➹➺➻➼➽➾➿🩰🩱🩲🩳🩴🩵🩶🩷🩸🩹🩺🩻🩼🪀🪁🪂🪃🪄🪅🪆🪇🪈🪐🪑🪒🪓🪔🪕🪖🪗🪘🪙🪚🪛🪜🪝🪞🪟🪠🪡🪢🪣🪤🪥🪦🪧🪨🪩🪪🪫🪬🪭🪮🪯🪰🪱🪲🪳🪴🪵🪶🪷🪸🪹🪺🪻🪼🪽🪿🫀🫁🫂🫃🫄🫅🫎🫏🫐🫑🫒🫓🫔🫕🫖🫗🫘🫙🫚🫛🫠🫡🫢🫣🫤🫥🫦🫧🫨🫰🫱🫲🫳🫴🫵🫶🫷🫸🚀🚁🚂🚃🚄🚅🚆🚇🚈🚉🚊🚋🚌🚍🚎🚏🚐🚑🚒🚓🚔🚕🚖🚗🚘🚙🚚🚛🚜🚝🚞🚟🚠🚡🚢🚣🚤🚥🚦🚧🚨🚩🚪🚫🚬🚭🚮🚯🚰🚱🚲🚳🚴🚵🚶🚷🚸🚹🚺🚻🚼🚽🚾🚿🛀🛁🛂🛃🛄🛅🛆🛇🛈🛉🛊🛋🛌🛍🛎🛏🛐🛑🛒🛓🛔🛕🛖🛗🛜🛝🛞🛟🛠🛡🛢🛣🛤🛥🛦🛧🛨🛩🛪🛫🛬🛰🛱🛲🛳🛴🛵🛶🛷🛸🛹🛺🛻🛼😀😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐😑😒😓😔😕😖😗😘😙😚😛😜😝😞😟😠😡😢😣😤😥😦😧😨😩😪😫😬😭😮😯😰😱😲😳😴😵😶😷😸😹😺😻😼😽😾😿🙀🙁🙂🙃🙄🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんゔゕゖ$゙$゚ ゙ ゚ゝゞゟ߁߂߃߄߅߆߇߈߉ߊߋߌߍߎߏߐߑߒߓߔߕߖߗߘߙߚߛߜߝߞߟߠߡߢߣߤߥߦߧߨߩߪ߲߫߬߭߮߯߰߱߳ߴߵ߶߷߸߹ߺ߽߾߿ᎠᎡᎢᎣᎤᎥᎦᎧᎨᎩᎪᎫᎬᎭᎮᎯᎰᎱᎲᎳᎴᎵᎶᎷᎸᎹᎺᎻᎼᎽᎾᎿᏀᏁᏂᏃᏄᏅᏆᏇᏈᏉᏊᏋᏌᏍᏎᏏᏐᏑᏒᏓᏔᏕᏖᏗᏘᏙᏚᏛᏜᏝᏞᏟᏠᏡᏢᏣᏤᏥᏦᏧᏨᏩᏪᏫᏬᏭᏮᏯᏰᏱᏲᏳᏴᏵᏸᏹᏺᏻᏼᏽ𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁈𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿𓂀𓂁𓂂𓂃𓂄𓂅𓂆𓂇𓂈𓂉𓂊𓂋𓂌𓂍𓂎𓂏𓂐𓂑𓂒𓂓𓂔𓂕𓂖𓂗𓂘𓂙𓂚𓂛𓂜𓂝𓂞𓂟𓂠𓂡𓂢𓂣𓂤𓂥𓂦𓂧𓂨𓂩𓂪𓂫𓂬𓂭𓂮𓂯𓂰𓂱𓂲𓂳𓂴𓂵𓂶𓂷𓂸𓂹𓂺𓂻𓂼𓂽𓂾𓂿𓃀𓃁𓃂𓃃𓃄𓃅𓃆𓃇𓃈𓃉𓃊𓃋𓃌𓃍𓃎𓃏𓃐𓃑𓃒𓃓𓃔𓃕𓃖𓃗𓃘𓃙𓃚𓃛𓃜𓃝𓃞𓃟𓃠𓃡𓃢𓃣𓃤𓃥𓃦𓃧𓃨𓃩𓃪𓃫𓃬𓃭𓃮𓃯𓃰𓃱𓃲𓃳𓃴𓃵𓃶𓃷𓃸𓃹𓃺𓃻𓃼𓃽𓃾𓃿𓄀𓄁𓄂𓄃𓄄𓄅𓄆𓄇𓄈𓄉𓄊𓄋𓄌𓄍𓄎𓄏𓄐𓄑𓄒𓄓𓄔𓄕𓄖𓄗𓄘𓄙𓄚𓄛𓄜𓄝𓄞𓄟𓄠𓄡𓄢𓄣𓄤𓄥𓄦𓄧𓄨𓄩𓄪𓄫𓄬𓄭𓄮𓄯𓄰𓄱𓄲𓄳𓄴𓄵𓄶𓄷𓄸𓄹𓄺𓄻𓄼𓄽𓄾𓄿𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈𓅉𓅊𓅋𓅌𓅍𓅎𓅏𓅐𓅑𓅒𓅓𓅔𓅕𓅖𓅗𓅘𓅙𓅚𓅛𓅜𓅝𓅞𓅟𓅠𓅡𓅢𓅣𓅤𓅥𓅦𓅧𓅨𓅩𓅪𓅫𓅬𓅭𓅮𓅯𓅰𓅱𓅲𓅳𓅴𓅵𓅶𓅷𓅸𓅹𓅺𓅻𓅼𓅽𓅾𓅿𓆀𓆁𓆂𓆃𓆄𓆅𓆆𓆇𓆈𓆉𓆊𓆋𓆌𓆍𓆎𓆏𓆐𓆑𓆒𓆓𓆔𓆕𓆖𓆗𓆘𓆙𓆚𓆛𓆜𓆝𓆞𓆟𓆠𓆡𓆢𓆣𓆤𓆥𓆦𓆧𓆨𓆩𓆪𓆫𓆬𓆭𓆮𓆯𓆰𓆱𓆲𓆳𓆴𓆵𓆶𓆷𓆸𓆹𓆺𓆻𓆼𓆽𓆾𓆿𓇀𓇁𓇂𓇃𓇄𓇅𓇆𓇇𓇈𓇉𓇊𓇋𓇌𓇍𓇎𓇏𓇐𓇑𓇒𓇓𓇔𓇕𓇖𓇗𓇘𓇙𓇚𓇛𓇜𓇝𓇞𓇟𓇠𓇡𓇢𓇣𓇤𓇥𓇦𓇧𓇨𓇩𓇪𓇫𓇬𓇭𓇮𓇯𓇰𓇱𓇲𓇳𓇴𓇵𓇶𓇷𓇸𓇹𓇺𓇻𓇼𓇽𓇾𓇿𓈀𓈁𓈂𓈃𓈄𓈅𓈆𓈇𓈈𓈉𓈊𓈋𓈌𓈍𓈎𓈏𓈐𓈑𓈒𓈓𓈔𓈕𓈖𓈗𓈘𓈙𓈚𓈛𓈜𓈝𓈞𓈟𓈠𓈡𓈢𓈣𓈤𓈥𓈦𓈧𓈨𓈩𓈪𓈫𓈬𓈭𓈮𓈯𓈰𓈱𓈲𓈳𓈴𓈵𓈶𓈷𓈸𓈹𓈺𓈻𓈼𓈽𓈾𓈿𓉀𓉁𓉂𓉃𓉄𓉅𓉆𓉇𓉈𓉉𓉊𓉋𓉌𓉍𓉎𓉏𓉐𓉑𓉒𓉓𓉔𓉕𓉖𓉗𓉘𓉙𓉚𓉛𓉜𓉝𓉞𓉟𓉠𓉡𓉢𓉣𓉤𓉥𓉦𓉧𓉨𓉩𓉪𓉫𓉬𓉭𓉮𓉯𓉰𓉱𓉲𓉳𓉴𓉵𓉶𓉷𓉸𓉹𓉺𓉻𓉼𓉽𓉾𓉿𓊀𓊁𓊂𓊃𓊄𓊅𓊆𓊇𓊈𓊉𓊊𓊋𓊌𓊍𓊎𓊏𓊐𓊑𓊒𓊓𓊔𓊕𓊖𓊗𓊘𓊙𓊚𓊛𓊜𓊝𓊞𓊟𓊠𓊡𓊢𓊣𓊤𓊥𓊦𓊧𓊨𓊩𓊪𓊫𓊬𓊭𓊮𓊯𓊰𓊱𓊲𓊳𓊴𓊵𓊶𓊷𓊸𓊹𓊺𓊻𓊼𓊽𓊾𓊿𓋀𓋁𓋂𓋃𓋄𓋅𓋆𓋇𓋈𓋉𓋊𓋋𓋌𓋍𓋎𓋏𓋐𓋑𓋒𓋓𓋔𓋕𓋖𓋗𓋘𓋙𓋚𓋛𓋜𓋝𓋞𓋟𓋠𓋡𓋢𓋣𓋤𓋥𓋦𓋧𓋨𓋩𓋪𓋫𓋬𓋭𓋮𓋯𓋰𓋱𓋲𓋳𓋴𓋵𓋶𓋷𓋸𓋹𓋺𓋻𓋼𓋽𓋾𓋿𓌀𓌁𓌂𓌃𓌄𓌅𓌆𓌇𓌈𓌉𓌊𓌋𓌌𓌍𓌎𓌏𓌐𓌑𓌒𓌓𓌔𓌕𓌖𓌗𓌘𓌙𓌚𓌛𓌜𓌝𓌞𓌟𓌠𓌡𓌢𓌣𓌤𓌥𓌦𓌧𓌨𓌩𓌪𓌫𓌬𓌭𓌮𓌯𓌰𓌱𓌲𓌳𓌴𓌵𓌶𓌷𓌸𓌹𓌺𓌻𓌼𓌽𓌾𓌿𓍀𓍁𓍂𓍃𓍄𓍅𓍆𓍇𓍈𓍉𓍊𓍋𓍌𓍍𓍎𓍏𓍐𓍑𓍒𓍓𓍔𓍕𓍖𓍗𓍘𓍙𓍚𓍛𓍜𓍝𓍞𓍟𓍠𓍡𓍢𓍣𓍤𓍥𓍦𓍧𓍨𓍩𓍪𓍫𓍬𓍭𓍮𓍯𓍰𓍱𓍲𓍳𓍴𓍵𓍶𓍷𓍸𓍹𓍺𓍻𓍼𓍽𓍾𓍿𓎀𓎁𓎂𓎃𓎄𓎅𓎆𓎇𓎈𓎉𓎊𓎋𓎌𓎍𓎎𓎏𓎐𓎑𓎒𓎓𓎔𓎕𓎖𓎗𓎘𓎙𓎚𓎛𓎜𓎝𓎞𓎟𓎠𓎡𓎢𓎣𓎤𓎥𓎦𓎧𓎨𓎩𓎪𓎫𓎬𓎭𓎮𓎯𓎰𓎱𓎲𓎳𓎴𓎵𓎶𓎷𓎸𓎹𓎺𓎻𓎼𓎽𓎾𓎿𓏀𓏁𓏂𓏃𓏄𓏅𓏆𓏇𓏈𓏉𓏊𓏋𓏌𓏍𓏎𓏏𓏐𓏑𓏒𓏓𓏔𓏕𓏖𓏗𓏘𓏙𓏚𓏛𓏜𓏝𓏞𓏟𓏠𓏡𓏢𓏣𓏤𓏥𓏦𓏧𓏨𓏩𓏪𓏫𓏬𓏭𓏮𓏯𓏰𓏱𓏲𓏳𓏴𓏵𓏶𓏷𓏸𓏹𓏺𓏻𓏼𓏽𓏾𓏿𓐀𓐁𓐂𓐃𓐄𓐅𓐆𓐇𓐈𓐉𓐊𓐋𓐌𓐍𓐎𓐏𓐐𓐑𓐒𓐓𓐔𓐕𓐖𓐗𓐘𓐙𓐚𓐛𓐜𓐝𓐞𓐟𓐠𓐡𓐢𓐣𓐤𓐥𓐦𓐧𓐨𓐩𓐪𓐫𓐬𓐭𓐮𓐯🐀🐁🐂🐃🐄🐅🐆🐇🐈🐉🐊🐋🐌🐍🐎🐏🐐🐑🐒🐓🐔🐕🐖🐗🐘🐙🐚🐛🐜🐝🐞🐟🐠🐡🐢🐣🐤🐥🐦🐧🐨🐩🐪🐫🐬🐭🐮🐯🐰🐱🐲🐳🐴🐵🐶🐷🐸🐹🐺🐻🐼🐽🐾🐿👀👁👂👃👄👅👆👇👈👉👊👋👌👍👎👏👐👑👒👓👔👕👖👗👘👙👚👛👜👝👞👟👠👡👢👣👤👥👦👧👨👩👪👫👬👭👮👯👰👱👲👳👴👵👶👷👸👹👺👻👼👽👾👿💀💁💂💃💄💅💆💇💈💉💊💋💌💍💎💏💐💑💒💓💔💕💖💗💘💙💚💛💜💝💞💟💠💡💢💣💤💥💦💧💨💩💪💫💬💭💮💯💰💱💲💳💴💵💶💷💸💹💺💻💼💽💾💿📀📁📂📃📄📅📆📇📈📉📊📋📌📍📎📏📐📑📒📓📔📕📖📗📘📙📚📛📜📝📞📟📠📡📢📣📤📥📦📧📨📩📪📫📬📭📮📯📰📱📲📳📴📵📶📷📸📹📺📻📼📽📾📿🔀🔁🔂🔃🔄🔅🔆🔇🔈🔉🔊🔋🔌🔍🔎🔏🔐🔑🔒🔓🔔🔕🔖🔗🔘🔙🔚🔛🔜🔝🔞🔟🔠🔡🔢🔣🔤🔥🔦🔧🔨🔩🔪🔫🔬🔭🔮🔯🔰🔱🔲🔳🔴🔵🔶🔷🔸🔹🔺🔻🔼🔽🔾🔿🕀🕁🕂🕃🕄🕅🕆🕇🕈🕉🕊🕋🕌🕍🕎🕏🕐🕑🕒🕓🕔🕕🕖🕗🕘🕙🕚🕛🕜🕝🕞🕟🕠🕡🕢🕣🕤🕥🕦🕧🕨🕩🕪🕫🕬🕭🕮🕯🕰🕱🕲🕳🕴🕵🕶🕷🕸🕹🕺🕻🕼🕽TEL🕿🖀🖁🖂🖃🖄🖅🖆🖇🖈🖉🖊🖋🖌🖍🖎🖏🖐🖑🖒🖓🖔🖕🖖🖗🖘🖙🖚🖛🖜🖝🖞🖟🖠🖡🖢🖣🖤🖥🖦🖧🖨🖩🖪🖫🖬🖭🖮🖯🖰🖱🖲🖳🖴🖵🖶🖷🖸🖹🖺🖻🖼🖽🖾🖿🗀🗁🗂🗃🗄🗅🗆🗇🗈🗉🗊🗋🗌🗍🗎🗏🗐🗑🗒🗓🗔🗕🗖🗗🗘🗙🗚🗛🗜🗝🗞🗟🗠🗡🗢🗣🗤🗥🗦🗧🗨🗩🗪🗫🗬🗭🗮🗯🗰🗱🗲🗳🗴🗵🗶🗷🗸🗹🗺🗻🗼🗽🗾🗿🤀🤁🤂🤃🤄🤅🤆🤇🤈🤉🤊🤋🤌🤍🤎🤏🤐🤑🤒🤓🤔🤕🤖🤗🤘🤙🤚🤛🤜🤝🤞🤟🤠🤡🤢🤣🤤🤥🤦🤧🤨🤩🤪🤫🤬🤭🤮🤯🤰🤱🤲🤳🤴🤵🤶🤷🤸🤹🤺🤻🤼🤽🤾🤿🥀🥁🥂🥃🥄🥅🥆🥇🥈🥉🥊🥋🥌🥍🥎🥏🥐🥑🥒🥓🥔🥕🥖🥗🥘🥙🥚🥛🥜🥝🥞🥟🥠🥡🥢🥣🥤🥥🥦🥧🥨🥩🥪🥫🥬🥭🥮🥯🥰🥱🥲🥳🥴🥵🥶🥷🥸🥹🥺🥻🥼🥽🥾🥿🦀🦁🦂🦃🦄🦅🦆🦇🦈🦉🦊🦋🦌🦍🦎🦏🦐🦑🦒🦓🦔🦕🦖🦗🦘🦙🦚🦛🦜🦝🦞🦟🦠🦡🦢🦣🦤🦥🦦🦧🦨🦩🦪🦫🦬🦭🦮🦯🦰🦱🦲🦳🦴🦵🦶🦷🦸🦹🦺🦻🦼🦽🦾🦿🧀🧁🧂🧃🧄🧅🧆🧇🧈🧉🧊🧋🧌🧍🧎🧏🧐🧑🧒🧓🧔🧕🧖🧗🧘🧙🧚🧛🧜🧝🧞🧟🧠🧡🧢🧣🧤🧥🧦🧧🧨🧩🧪🧫🧬🧭🧮🧯🧰🧱🧲🧳🧴🧵🧶🧷🧸🧹🧺🧻🧼🧽🧾🧿🪿" + } + ] +} diff --git a/centrallix-os/tests/shell/invalid1.shl b/centrallix-os/tests/shell/invalid1.shl new file mode 100644 index 000000000..efa243457 --- /dev/null +++ b/centrallix-os/tests/shell/invalid1.shl @@ -0,0 +1,6 @@ +$Version=2$ +myshell "system/shell" +{ + program = "/bin/cat"; + arg="cat","/usr/local/src/cx-git/centrallix-os/tests/shell/invalid_short.txt"; +} diff --git a/centrallix-os/tests/shell/invalid2.shl b/centrallix-os/tests/shell/invalid2.shl new file mode 100644 index 000000000..b6d2068b8 --- /dev/null +++ b/centrallix-os/tests/shell/invalid2.shl @@ -0,0 +1,6 @@ +$Version=2$ +myshell "system/shell" +{ + program = "/bin/cat"; + arg="cat","/usr/local/src/cx-git/centrallix-os/tests/shell/invalid_long.txt"; +} diff --git a/centrallix-os/tests/shell/invalid_long.txt b/centrallix-os/tests/shell/invalid_long.txt new file mode 100644 index 000000000..cc55ae03a --- /dev/null +++ b/centrallix-os/tests/shell/invalid_long.txt @@ -0,0 +1,99 @@ +1:1 In the beginning God created the heaven and the earth. + +1:2 And the earth was without form, and void; and darkness was upon +the face of the deep. And the Spirit of God moved upon the face of the +waters. + +1:3 And God said, Let there be light: and there was light. + +1:4 And God saw the light, that it was good: and God divided the light +from the darkness. + +1:5 And God called the light Day, and the darkness he called Night. +And the evening and the morning were the first day. + +1:6 And God said, Let there be a firmament in the midst of the waters, +and let it divide the waters from the waters. + +1:7 And God made the firmament, and divided the waters which were +under the firmament from the waters which were above the firmament: +and it was so. + +1:8 And God called the firmament Heaven. And the evening and the +morning were the second day. + +1:9 And God said, Let the waters under the heaven be gathered together +unto one place, and let the dry land appear: and it was so. + +1:10 And God called the dry land Earth; and the gathering together of +the waters called he Seas: and God saw that it was good. + +1:11 And God said, Let the earth bring forth grass, the herb yielding +seed, and the fruit tree yielding fruit after his kind, whose seed is +in itself, upon the earth: and it was so. + +1:12 And the earth brought forth grass, and herb yielding seed after +his kind, and the tree yielding fruit, whose seed was in itself, after +his kind: and God saw that it was good. + +1:13 And the evening and the morning were the third day. + +1:14 And God said, Let there be lights in the firmament of the heaven +to divide the day from the night; and let them be for signs, and for +seasons, and for days, and years: 1:15 And let them be for lights in +the firmament of the heaven to give light upon the earth: and it was +so. + +1:16 And God made two great lights; the greater light to rule the day, +and the lesser light to rule the night: he made the stars also. + +1:17 And God set them in the firmament of the heaven to give light +upon the earth, 1:18 And to rule over the day and over the night, and +to divide the light from the darkness: and God saw that it was good. + +1:19 And the evening and the morning were the fourth day. + +1:20 And God said, Let the waters bring forth abundantly the moving +creature that hath life, and fowl that may fly above the earth in the +open firmament of heaven. + +1:21 And God created great whales, and every living creature that +moveth, which the waters brought forth abundantly, after their kind, +and every winged fowl after his kind: and God saw that it was good. + +1:22 And God blessed them, saying, Be fruitful, and multiply, and fill +the waters in the seas, and let fowl multiply in the earth. + +1:23 And the evening and the morning were the fifth day. + +1:24 And God said, Let the earth bring forth the living creature after +his kind, cattle, and creeping thing, and beast of the earth after his +kind: and it was so. + +1:25 And God made the beast of the earth after his kind, and cattle +after their kind, and every thing that creepeth upon the earth after +his kind: and God saw that it was good. + +1:26 And God said, Let us make man in our image, after our likeness: +and let them have dominion over the fish of the sea, and over the fowl +of the air, and over the cattle, and over all the earth, and over +every creeping thing that creepeth upon the earth. + +1:27 So God created man in his own image, in the image of God created +he him; male and female created he them. + +128 And God blessed them, and God said unto them, Be fruitful, and +multiply, and replenish the earth, and subdue it: and have dominion +over the fish of the sea, and over the fowl of the air, and over every +living thing that moveth upon the earth. + +1:29 And God said, Behold, I have given you every herb bearing seed, +which is upon the face of all the earth, and every tree, in the which +is the fruit of a tree yielding seed; to you it shall be for meat. + +1:30 And to every beast of the earth, and to every fowl of the air, +and to every thing that creepeth upon the earth, wherein there is +life, I have given every green herb for meat: and it was so. + +1:31 And God saw every thing that he had made, and, behold, it was +very good. And the evening and the morning were the sixth day. \ No newline at end of file diff --git a/centrallix-os/tests/shell/invalid_short.txt b/centrallix-os/tests/shell/invalid_short.txt new file mode 100644 index 000000000..8131f704d --- /dev/null +++ b/centrallix-os/tests/shell/invalid_short.txt @@ -0,0 +1 @@ +This is a test with an invalid character in it: \ No newline at end of file diff --git a/centrallix-os/tests/shell/valid1.shl b/centrallix-os/tests/shell/valid1.shl new file mode 100644 index 000000000..5b99b5280 --- /dev/null +++ b/centrallix-os/tests/shell/valid1.shl @@ -0,0 +1,6 @@ +$Version=2$ +myshell "system/shell" +{ + program = "/bin/cat"; + arg="cat","/usr/local/src/cx-git/centrallix-os/tests/shell/valid_short.txt"; +} diff --git a/centrallix-os/tests/shell/valid2.shl b/centrallix-os/tests/shell/valid2.shl new file mode 100644 index 000000000..7e0eaba8c --- /dev/null +++ b/centrallix-os/tests/shell/valid2.shl @@ -0,0 +1,6 @@ +$Version=2$ +myshell "system/shell" +{ + program = "/bin/cat"; + arg="cat","/usr/local/src/cx-git/centrallix-os/tests/shell/valid_long.txt"; +} diff --git a/centrallix-os/tests/shell/valid_long.txt b/centrallix-os/tests/shell/valid_long.txt new file mode 100644 index 000000000..51cd0c44d --- /dev/null +++ b/centrallix-os/tests/shell/valid_long.txt @@ -0,0 +1,96 @@ +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 \ No newline at end of file diff --git a/centrallix-os/tests/shell/valid_short.txt b/centrallix-os/tests/shell/valid_short.txt new file mode 100644 index 000000000..3751ef557 --- /dev/null +++ b/centrallix-os/tests/shell/valid_short.txt @@ -0,0 +1,4 @@ +A simple test with multiple types of characters +Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. +実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。 +𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿 \ No newline at end of file diff --git a/centrallix-os/tests/test10.json b/centrallix-os/tests/test10.json new file mode 100644 index 000000000..599129197 --- /dev/null +++ b/centrallix-os/tests/test10.json @@ -0,0 +1,13 @@ +{ + "ascii": "this is an ascii string", + "жизнь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test11.json b/centrallix-os/tests/test11.json new file mode 100644 index 000000000..d1d5e8826 --- /dev/null +++ b/centrallix-os/tests/test11.json @@ -0,0 +1,13 @@ +{ + "ascii": "this is an ascii string", + "жизнь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test12.json b/centrallix-os/tests/test12.json new file mode 100644 index 000000000..2975bb636 --- /dev/null +++ b/centrallix-os/tests/test12.json @@ -0,0 +1,16 @@ +{ + + "ascii_1": "119:1 Blessed are the undefiled in the way, who walk in the law of the LORD. 119:2 Blessed are they that keep his testimonies, and that seek him with the whole heart. 119:3 They also do no iniquity: they walk in his ways. 119:4 Thou hast commanded us to keep thy precepts diligently.", + "2Byte_1": "Блаженны непорочные в пути, ходящие в законе Господнем. Блаженны хранящие откровения Его, всем сердцем ищущие Его. Они не делают беззакония, ходят путями Его. Ты заповедал повеления Твои хранить твердо. О, если бы направлялись пути мои к соблюдению уставов Твоих! Тогда я не постыдился бы, взирая на все заповеди Твои: я славил бы Тебя в правоте сердца, поучаясь судам правды Твоей. Буду хранить уставы Твои; не оставляй меня совсем. Как юноше содержать в чистоте путь свой? --Хранением себя по слову Твоему.", + "2Byte_2": "1Блаженны непорочные в пути, ходящие в законе Господнем. Блаженны хранящие откровения Его, всем сердцем ищущие Его. Они не делают беззакония, ходят путями Его. Ты заповедал повеления Твои хранить твердо. О, если бы направлялись пути мои к соблюдению уставов Твоих! Тогда я не постыдился бы, взирая на все заповеди Твои: я славил бы Тебя в правоте сердца, поучаясь судам правды Твоей. Буду хранить уставы Твои; не оставляй меня совсем. Как юноше содержать в чистоте путь свой? --Хранением себя по слову Твоему.", + "2Byte_3": "12Блаженны непорочные в пути, ходящие в законе Господнем. Блаженны хранящие откровения Его, всем сердцем ищущие Его. Они не делают беззакония, ходят путями Его. Ты заповедал повеления Твои хранить твердо. О, если бы направлялись пути мои к соблюдению уставов Твоих! Тогда я не постыдился бы, взирая на все заповеди Твои: я славил бы Тебя в правоте сердца, поучаясь судам правды Твоей. Буду хранить уставы Твои; не оставляй меня совсем. Как юноше содержать в чистоте путь свой? --Хранением себя по слову Твоему.", + "3Byte_1": "おのが道を全くして、主のおきてに歩む者はさいわいです。主のもろもろのあかしを守り心をつくして主を尋ね求め、また悪を行わず、主の道に歩む者はさいわいです。あなたはさとしを命じて、ねんごろに守らせられます。どうかわたしの道を堅くして、あなたの定めを守らせてください。わたしは、あなたのもろもろの戒めに目をとめる時、恥じることはありません。わたしは、あなたの正しいおきてを学ぶとき、正しい心をもってあなたに感謝します。わたしはあなたの定めを守ります。わたしを全くお捨てにならないでください。若い人はどうしておのが道を清く保つことができるでしょ", + "3Byte_2": "1おのが道を全くして、主のおきてに歩む者はさいわいです。主のもろもろのあかしを守り心をつくして主を尋ね求め、また悪を行わず、主の道に歩む者はさいわいです。あなたはさとしを命じて、ねんごろに守らせられます。どうかわたしの道を堅くして、あなたの定めを守らせてください。わたしは、あなたのもろもろの戒めに目をとめる時、恥じることはありません。わたしは、あなたの正しいおきてを学ぶとき、正しい心をもってあなたに感謝します。わたしはあなたの定めを守ります。わたしを全くお捨てにならないでください。若い人はどうしておのが道を清く保つことができるでしょ", + "3Byte_3": "12おのが道を全くして、主のおきてに歩む者はさいわいです。主のもろもろのあかしを守り心をつくして主を尋ね求め、また悪を行わず、主の道に歩む者はさいわいです。あなたはさとしを命じて、ねんごろに守らせられます。どうかわたしの道を堅くして、あなたの定めを守らせてください。わたしは、あなたのもろもろの戒めに目をとめる時、恥じることはありません。わたしは、あなたの正しいおきてを学ぶとき、正しい心をもってあなたに感謝します。わたしはあなたの定めを守ります。わたしを全くお捨てにならないでください。若い人はどうしておのが道を清く保つことができるでしょ", + "3Byte_4": "123おのが道を全くして、主のおきてに歩む者はさいわいです。主のもろもろのあかしを守り心をつくして主を尋ね求め、また悪を行わず、主の道に歩む者はさいわいです。あなたはさとしを命じて、ねんごろに守らせられます。どうかわたしの道を堅くして、あなたの定めを守らせてください。わたしは、あなたのもろもろの戒めに目をとめる時、恥じることはありません。わたしは、あなたの正しいおきてを学ぶとき、正しい心をもってあなたに感謝します。わたしはあなたの定めを守ります。わたしを全くお捨てにならないでください。若い人はどうしておのが道を清く保つことができるでしょ", + "4Byte_1": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "4Byte_2": "1𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "4Byte_3": "12𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "4Byte_4": "123𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "4Byte_5": "1234𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿" +} \ No newline at end of file diff --git a/centrallix-os/tests/test4.json b/centrallix-os/tests/test4.json new file mode 100644 index 000000000..61c520947 --- /dev/null +++ b/centrallix-os/tests/test4.json @@ -0,0 +1,14 @@ +{ + "ascii": "this is an ascii string", + "жизнь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿": "yup", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test5.json b/centrallix-os/tests/test5.json new file mode 100644 index 000000000..45803fc57 --- /dev/null +++ b/centrallix-os/tests/test5.json @@ -0,0 +1,13 @@ +{ + "asii": "this is an ascii string", + "жизнь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test6.json b/centrallix-os/tests/test6.json new file mode 100644 index 000000000..7f8e9679d --- /dev/null +++ b/centrallix-os/tests/test6.json @@ -0,0 +1,13 @@ +{ + "ascii": "this is an ascii strng", + "жизнь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test7.json b/centrallix-os/tests/test7.json new file mode 100644 index 000000000..1df850f8f --- /dev/null +++ b/centrallix-os/tests/test7.json @@ -0,0 +1,13 @@ +{ + "ascii": "this is an ascii string", + "жинь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test8.json b/centrallix-os/tests/test8.json new file mode 100644 index 000000000..b0eaabbea --- /dev/null +++ b/centrallix-os/tests/test8.json @@ -0,0 +1,13 @@ +{ + "ascii": "this is an ascii string", + "жизнь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test9.json b/centrallix-os/tests/test9.json new file mode 100644 index 000000000..a8816578d --- /dev/null +++ b/centrallix-os/tests/test9.json @@ -0,0 +1,13 @@ +{ + "ascii": "this is an ascii string", + "жизнь": "Οὕτως γὰρ ἠγάπησεν ὁ Θεὸς τὸν", + "что": "Ведь Бог так полюбил этот мир, что отдал Своего единственного_Сы_а, чтобы каждый верующий в Него не погиб, но имел вечную жизнь.", + "世界を愛": "彼を信ずる者の亡びずして、永遠の生命を得んためなり。", + "実に神はひとり子をさえ惜しまず与えるほどにこの世界を愛してくださいました。それは神の御子を信じる者がだれ一人滅びず永遠のいのちを得るためです。": "めです", + "𓂀𓂁𓂂𓂃𓂄": "𓀀𓀁𓀂𓀃𓀄𓀅𓀆𓀇𓀈𓀉𓀊𓀋𓀌𓀍𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙𓀚𓀛𓀜𓀝𓀞𓀟𓀠𓀡𓀢𓀣𓀤𓀥𓀦𓀧𓀨𓀩𓀪𓀫𓀬𓀭𓀮𓀯𓀰𓀱𓀲𓀳𓀴𓀵𓀶𓀷𓀸𓀹𓀺𓀻𓀼𓀽𓀾𓀿𓁀𓁁𓁂𓁃𓁄𓁅𓁆𓁇𓁉𓁊𓁋𓁌𓁍𓁎𓁏𓁐𓁑𓁒𓁓𓁔𓁕𓁖𓁗𓁘𓁙𓁚𓁛𓁜𓁝𓁞𓁟𓁠𓁡𓁢𓁣𓁤𓁥𓁦𓁧𓁨𓁩𓁪𓁫𓁬𓁭𓁮𓁯𓁰𓁱𓁲𓁳𓁴𓁵𓁶𓁷𓁸𓁹𓁺𓁻𓁼𓁽𓁾𓁿", + "sub": { + "short 4 byte": "𓅀𓅁𓅂𓅃𓅄𓅅𓅆𓅇𓅈", + "numbers": 4500, + "literal": null + } +} \ No newline at end of file diff --git a/centrallix-os/tests/test_1.lnk b/centrallix-os/tests/test_1.lnk new file mode 100644 index 000000000..4e3af7908 --- /dev/null +++ b/centrallix-os/tests/test_1.lnk @@ -0,0 +1 @@ +./test1.json diff --git a/centrallix-os/tests/test_2.lnk b/centrallix-os/tests/test_2.lnk new file mode 100644 index 000000000..844ad016b --- /dev/null +++ b/centrallix-os/tests/test_2.lnk @@ -0,0 +1 @@ +./test1.jsn diff --git a/centrallix-os/tests/ux/.annotation b/centrallix-os/tests/ux/.annotation new file mode 100755 index 000000000..38c5f14b7 Binary files /dev/null and b/centrallix-os/tests/ux/.annotation differ diff --git a/centrallix-os/tests/ux/annotTest b/centrallix-os/tests/ux/annotTest new file mode 100644 index 000000000..c02b3ff8e --- /dev/null +++ b/centrallix-os/tests/ux/annotTest @@ -0,0 +1 @@ +This file has a valid annotation \ No newline at end of file diff --git a/centrallix-os/tests/ux/annotTest2 b/centrallix-os/tests/ux/annotTest2 new file mode 100644 index 000000000..6fd4c2344 --- /dev/null +++ b/centrallix-os/tests/ux/annotTest2 @@ -0,0 +1 @@ +This file has an invalud annotation \ No newline at end of file diff --git a/centrallix-os/tests/xml/basic.xml b/centrallix-os/tests/xml/basic.xml new file mode 100644 index 000000000..657c9a327 --- /dev/null +++ b/centrallix-os/tests/xml/basic.xml @@ -0,0 +1,12 @@ + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">some more text + \ No newline at end of file diff --git a/centrallix-os/tests/xml/invalidBlockEnd.xml b/centrallix-os/tests/xml/invalidBlockEnd.xml new file mode 100644 index 000000000..2133125eb --- /dev/null +++ b/centrallix-os/tests/xml/invalidBlockEnd.xml @@ -0,0 +1,52 @@ + + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">|�₩|𐊌🫖|𠀀蜨|𰀀𲎯| + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 1 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 2 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 3 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 4 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 5 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 6 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 8 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 9 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 10 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 11 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 12 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 13 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 14 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 15 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 16 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 17 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 18 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 19 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 20 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 21 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 22 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 23 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 24 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 25 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 26 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子を_え惜しまず与える="愛してくださいました。それは神の御">hello 27 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 28 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 29 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 30 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 31 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 32 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 33 + <ひとり子をさえ惜しまず与えるほど english="yay" test="pass">hello + <ひとり子をさえ惜しまず与えるほど>Sally + <愛してくださいましたそれは神の御子を信じる>James + <𓁹𓁺𓁻𓁼𓁽𓁾𓁿>Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. + + \ No newline at end of file diff --git a/centrallix-os/tests/xml/invalidBlockStart.xml b/centrallix-os/tests/xml/invalidBlockStart.xml new file mode 100644 index 000000000..1fba2e169 --- /dev/null +++ b/centrallix-os/tests/xml/invalidBlockStart.xml @@ -0,0 +1,52 @@ + + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">|�₩|𐊌🫖|𠀀蜨|𰀀𲎯| + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 1 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 2 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 3 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 4 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 5 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 6 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 8 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 9 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 10 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 11 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 12 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 13 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 14 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 15 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 16 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 17 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 18 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 19 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 20 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 21 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 22 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 23 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 24 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 25 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 26 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 27 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 28 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 29 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 30 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 31 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 32 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 33 + <ひとり子をさえ惜しまず与えるほど english="yay" test="pass">hello + <ひとり子をさえ惜しまず与えるほど>Sally + <愛してくださいましたそれは神の御子を信じる>James + <𓁹𓁺𓁻𓁼𓁽𓁾𓁿>Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. + + \ No newline at end of file diff --git a/centrallix-os/tests/xml/invalidEnd.xml b/centrallix-os/tests/xml/invalidEnd.xml new file mode 100644 index 000000000..bbe7fb128 --- /dev/null +++ b/centrallix-os/tests/xml/invalidEnd.xml @@ -0,0 +1,52 @@ + + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">|�₩|𐊌🫖|𠀀蜨|𰀀𲎯| + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 1 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 2 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 3 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 4 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 5 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 6 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 8 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 9 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 10 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 11 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 12 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 13 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 14 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 15 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 16 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 17 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 18 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 19 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 20 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 21 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 22 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 23 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 24 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 25 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 26 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をえ惜しまず与える="愛してくださいました。それは神の御">hello 27 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 28 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 29 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 30 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 31 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 32 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 33 + <ひとり子をさえ惜しまず与えるほど english="yay" test="pass">hello + <ひとり子をさえ惜しまず与えるほど>Sally + <愛してくださいましたそれは神の御子を信じる>James + <𓁹𓁺𓁻𓁼𓁽𓁾𓁿>Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. + + \ No newline at end of file diff --git a/centrallix-os/tests/xml/invalidMiddle.xml b/centrallix-os/tests/xml/invalidMiddle.xml new file mode 100644 index 000000000..4913620af --- /dev/null +++ b/centrallix-os/tests/xml/invalidMiddle.xml @@ -0,0 +1,52 @@ + + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">|�₩|𐊌🫖|𠀀蜨|𰀀𲎯| + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 1 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 2 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 3 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 4 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 5 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 6 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 8 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 9 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 10 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 11 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 12 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 13 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 14 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 15 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 16 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 17 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 18 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 19 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 20 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 21 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 22 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 23 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 24 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 25 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 26 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 27 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 28 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 29 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 30 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 31 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 32 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 33 + <ひとり子をさえ惜しまず与えるほど english="yay" test="pass">hello + <ひとり子をさえ惜しまず与えるほど>Sally + <愛してくださいましたそれは神の御子を信じる>James + <𓁹𓁺𓁻𓁼𓁽𓁾𓁿>Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. + + \ No newline at end of file diff --git a/centrallix-os/tests/xml/invalidStart.xml b/centrallix-os/tests/xml/invalidStart.xml new file mode 100644 index 000000000..e753a74e3 --- /dev/null +++ b/centrallix-os/tests/xml/invalidStart.xml @@ -0,0 +1,52 @@ + + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">|�₩|𐊌🫖|𠀀蜨|𰀀𲎯| + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 1 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 2 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 3 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 4 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 5 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 6 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 8 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 9 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 10 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 11 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 12 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 13 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 14 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 15 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 16 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 17 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 18 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 19 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 20 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 21 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 22 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 23 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 24 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 25 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 26 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 27 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 28 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 29 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 30 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 31 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 32 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 33 + <ひとり子をさえ惜しまず与えるほど english="yay" test="pass">hello + <ひとり子をさえ惜しまず与えるほど>Sally + <愛してくださいましたそれは神の御子を信じる>James + <𓁹𓁺𓁻𓁼𓁽𓁾𓁿>Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. + + \ No newline at end of file diff --git a/centrallix-os/tests/xml/invalid_utf_16_BE.xml b/centrallix-os/tests/xml/invalid_utf_16_BE.xml new file mode 100644 index 000000000..4d0cc9c0b Binary files /dev/null and b/centrallix-os/tests/xml/invalid_utf_16_BE.xml differ diff --git a/centrallix-os/tests/xml/invalid_utf_16_LE.xml b/centrallix-os/tests/xml/invalid_utf_16_LE.xml new file mode 100644 index 000000000..50c8258e0 Binary files /dev/null and b/centrallix-os/tests/xml/invalid_utf_16_LE.xml differ diff --git a/centrallix-os/tests/xml/splitChars.xml b/centrallix-os/tests/xml/splitChars.xml new file mode 100644 index 000000000..d1363b214 --- /dev/null +++ b/centrallix-os/tests/xml/splitChars.xml @@ -0,0 +1,52 @@ + + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">|�₩|𐊌🫖|𠀀蜨|𰀀𲎯| + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 1 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 2 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 3 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 4 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 5 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 6 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 7 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 8 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 9 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 10 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 11 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 12 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 13 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 14 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 15 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 16 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 17 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 18 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 19 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 20 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 21 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 22 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 23 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 24 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 25 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 26 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 27 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 28 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 29 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 30 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 31 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 32 + <ひとり子をさえ惜しまず与えるほど 人滅びず永遠のいのちを得るためです="与えるほどにこ" 子をさえ惜しまず与える="愛してくださいました。それは神の御">hello 33 + <ひとり子をさえ惜しまず与えるほど english="yay" test="pass">hello + <ひとり子をさえ惜しまず与えるほど>Sally + <愛してくださいましたそれは神の御子を信じる>James + <𓁹𓁺𓁻𓁼𓁽𓁾𓁿>Ведь Бог так полюбил этот мир, что отдал Своего единственного Сына, чтобы каждый верующий в Него не погиб, но имел вечную жизнь. + + \ No newline at end of file diff --git a/centrallix-os/tests/xml/utf_16_BE.xml b/centrallix-os/tests/xml/utf_16_BE.xml new file mode 100644 index 000000000..0cbdd8b6d Binary files /dev/null and b/centrallix-os/tests/xml/utf_16_BE.xml differ diff --git a/centrallix-os/tests/xml/utf_16_LE.xml b/centrallix-os/tests/xml/utf_16_LE.xml new file mode 100644 index 000000000..220112746 Binary files /dev/null and b/centrallix-os/tests/xml/utf_16_LE.xml differ diff --git a/centrallix-os/tests/xml/utf_32_BE.xml b/centrallix-os/tests/xml/utf_32_BE.xml new file mode 100644 index 000000000..159c51d9b Binary files /dev/null and b/centrallix-os/tests/xml/utf_32_BE.xml differ diff --git a/centrallix-os/tests/xml/utf_32_LE.xml b/centrallix-os/tests/xml/utf_32_LE.xml new file mode 100644 index 000000000..7c2b4b12a Binary files /dev/null and b/centrallix-os/tests/xml/utf_32_LE.xml differ diff --git a/centrallix-os/tests/xml/utf_8.xml b/centrallix-os/tests/xml/utf_8.xml new file mode 100644 index 000000000..dbbe85255 --- /dev/null +++ b/centrallix-os/tests/xml/utf_8.xml @@ -0,0 +1,12 @@ + + + + Hello there + Harry + + + + Harry + Tom + <ВедьБогтакпол 神はひとり子をさえ惜="𓀎𓀏𓀐𓀑𓀒𓀓𓀔𓀕𓀖𓀗𓀘𓀙" акпол="|�₩|𐊌🫖|𠀀蜨|𰀀𲎯|">|�₩|𐊌🫖|𠀀蜨|𰀀𲎯| + \ No newline at end of file diff --git a/centrallix-os/tests/zip1.json.gz b/centrallix-os/tests/zip1.json.gz new file mode 100644 index 000000000..c3848b3bc Binary files /dev/null and b/centrallix-os/tests/zip1.json.gz differ diff --git a/centrallix-os/tests/zip2.json.gz b/centrallix-os/tests/zip2.json.gz new file mode 100644 index 000000000..82c6499be Binary files /dev/null and b/centrallix-os/tests/zip2.json.gz differ diff --git a/centrallix-os/tests/zip3.json.gz b/centrallix-os/tests/zip3.json.gz new file mode 100644 index 000000000..c9cd3a7a6 Binary files /dev/null and b/centrallix-os/tests/zip3.json.gz differ diff --git a/centrallix-os/tests/zip4.json.tgz b/centrallix-os/tests/zip4.json.tgz new file mode 100644 index 000000000..c9cd3a7a6 Binary files /dev/null and b/centrallix-os/tests/zip4.json.tgz differ diff --git a/centrallix-os/tests/zip5.json.new b/centrallix-os/tests/zip5.json.new new file mode 100644 index 000000000..c9cd3a7a6 Binary files /dev/null and b/centrallix-os/tests/zip5.json.new differ diff --git a/centrallix-sysdoc/OSDriver_Authoring.md b/centrallix-sysdoc/OSDriver_Authoring.md index c167fce26..3b0f7f5ab 100644 --- a/centrallix-sysdoc/OSDriver_Authoring.md +++ b/centrallix-sysdoc/OSDriver_Authoring.md @@ -13,12 +13,12 @@ License: Copyright (C) 2001-2011 LightSys Technology Services. See LICENSE.txt - [I Introduction](#i-introduction) - [II Interface](#ii-interface) - [A. Initialization](#a--initialization) - - [B. Opening And Closing Objects](#b--opening-and-closing-objects) - - [C. Creating and Deleting Objects.](#c--creating-and-deleting-objects) - - [D. Reading and Writing Object Content.](#d--reading-and-writing-object-content) - - [E. Querying for Child Objects.](#e--querying-for-child-objects) - - [F. Managing Object Attributes](#f--managing-object-attributes) - - [G. Managing Object Methods](#g--managing-object-methods) + - [B. Opening And Closing Objects](#b-opening-and-closing-objects) + - [C. Creating and Deleting Objects.](#c-creating-and-deleting-objects) + - [D. Reading and Writing Object Content.](#d-reading-and-writing-object-content) + - [E. Querying for Child Objects.](#e-querying-for-child-objects) + - [F. Managing Object Attributes](#f-managing-object-attributes) + - [G. Managing Object Methods](#g-managing-object-methods) - [III Reading the Node Object](#iii-reading-the-node-object) - [pSnNode snReadNode(pObject obj)](#psnnode-snreadnodepobject-obj) - [pSnNode snNewNode(pObject obj, char* content_type)](#psnnode-snnewnodepobject-obj-char-content_type) @@ -48,27 +48,27 @@ License: Copyright (C) 2001-2011 LightSys Technology Services. See LICENSE.txt - [void* nmSysRealloc(void* ptr, int newsize)](#void-nmsysreallocvoid-ptr-int-newsize) - [char* nmSysStrdup(const char* str)](#char-nmsysstrdupconst-char-str) - [V Other Utility Modules](#v-other-utility-modules) - - [A. XArray (XA) - Arrays](#axarray-xa---arrays) + - [A. XArray (XA) - Arrays](#a-xarray-xa---arrays) - [xaInit(pXArray this, int init_size)](#xainitpxarray-this-int-init_size) - [xaDeInit(pXArray this)](#xadeinitpxarray-this) - [xaAddItem(pXArray this, void* item)](#xaadditempxarray-this-void-item) - [xaAddItemSorted(pXArray this, void* item, int keyoffset, int keylen)](#xaadditemsortedpxarray-this-void-item-int-keyoffset-int-keylen) - [xaFindItem(pXArray this, void* item)](#xafinditempxarray-this-void-item) - [xaRemoveItem(pXArray this, int index)](#xaremoveitempxarray-this-int-index) - - [B. XHash (XH) - Hash Tables](#bxhash-xh---hash-tables) + - [B. XHash (XH) - Hash Tables](#b-xhash-xh---hash-tables) - [int xhInit(pXHashTable this, int rows, int keylen)](#int-xhinitpxhashtable-this-int-rows-int-keylen) - [int xhDeInit(pXHashTable this)](#int-xhdeinitpxhashtable-this) - [int xhAdd(pXHashTable this, char* key, char* data)](#int-xhaddpxhashtable-this-char-key-char-data) - [int xhRemove(pXHashTable this, char* key)](#int-xhremovepxhashtable-this-char-key) - [char* xhLookup(pXHashTable this, char* key)](#char-xhlookuppxhashtable-this-char-key) - [int xhClear(pXHashTable this, int free_blk)](#int-xhclearpxhashtable-this-int-free_blk) - - [C. XString (XS) - Strings](#cxstring-xs---strings) + - [C. XString (XS) - Strings](#c-xstring-xs---strings) - [int xsInit(pXString this)](#int-xsinitpxstring-this) - [int xsDeInit(pXString this)](#int-xsdeinitpxstring-this) - [int xsConcatenate(pXString this, char* text, int len)](#int-xsconcatenatepxstring-this-char-text-int-len) - [int xsCopy(pXString this, char* text, int len)](#int-xscopypxstring-this-char-text-int-len) - [char* xsStringEnd(pXString this)](#char-xsstringendpxstring-this) - - [D. Expression (EXP) - Expression Trees](#dexpression-exp---expression-trees) + - [D. Expression (EXP) - Expression Trees](#d-expression-exp---expression-trees) - [pExpression expCompileExpression(char* text, pParamObjects objlist, int lxflags, int cmpflags)](#pexpression-expcompileexpressionchar-text-pparamobjects-objlist-int-lxflags-int-cmpflags) - [expFreeExpression(pExpression this)](#expfreeexpressionpexpression-this) - [int expEvalTree(pExpression this, pParamObjects objlist)](#int-expevaltreepexpression-this-pparamobjects-objlist) @@ -78,14 +78,14 @@ License: Copyright (C) 2001-2011 LightSys Technology Services. See LICENSE.txt - [int expModifyParam(pParamObjects this, char* name, pObject replace_obj)](#int-expmodifyparampparamobjects-this-char-name-pobject-replace_obj) - [int expRemoveParamFromList(pParamObjects this, char* name)](#int-expremoveparamfromlistpparamobjects-this-char-name) - [int expReverseEvalTree(pExpression tree, pParamObjects objlist)](#int-expreverseevaltreepexpression-tree-pparamobjects-objlist) - - [E. MTSession (MSS) - Basic Session Management](#emtsession-mss---basic-session-management) + - [E. MTSession (MSS) - Basic Session Management](#e-mtsession-mss---basic-session-management) - [char* mssUserName()](#char-mssusername) - [char* mssPassword()](#char-msspassword) - [int mssSetParam(char* paramname, char* param)](#int-msssetparamchar-paramname-char-param) - [char* mssGetParam(char* paramname)](#char-mssgetparamchar-paramname) - [int mssError(int clr, char* module, char* message, ...)](#int-msserrorint-clr-char-module-char-message-) - [int mssErrorErrno(int clr, char* module, char* message, ...)](#int-msserrorerrnoint-clr-char-module-char-message-) - - [F. OSML Utility Functions](#fosml-utility-functions) + - [F. OSML Utility Functions](#f-osml-utility-functions) - [char* obj_internal_PathPart(pPathname path, int start, int length)](#char-obj_internal_pathpartppathname-path-int-start-int-length) - [int obj_internal_AddToPath(pPathname path, char* new_element)](#int-obj_internal_addtopathppathname-path-char-new_element) - [int obj_internal_CopyPath(pPathname dest, pPathname src)](#int-obj_internal_copypathppathname-dest-ppathname-src) @@ -114,6 +114,9 @@ License: Copyright (C) 2001-2011 LightSys Technology Services. See LICENSE.txt - [A. Object opening, closing, creation, and deletion](#aobject-opening-closing-creation-and-deletion) - [B. Object attribute enumeration, getting, and setting.](#bobject-attribute-enumeration-getting-and-setting) - [C. Object querying (for subobjects)](#cobject-querying-for-subobjects) + - [IX String Verification](#ix-string-verification) + - [A. Available Functions](#a-available-functions) + - [B. Unverified External Drivers](#b-unverified-external-drivers) ## I Introduction An objectsystem driver's purpose is to provide access to a particular type of local or network data/resource, and to organize that data in a tree- structured heirarchy that can be integrated into the Centrallix's ObjectSystem. This tree structure will vary based on the data being presented, but will fit the basic ObjectSystem model of a heirarchy of objects, each having attributes, perhaps some methods, and possibly content. @@ -906,6 +909,8 @@ This function opens a lexer session from a file source. See the 'expression' mo | MLX_F_IFSONLY | Only return string values separated by tabs, spaces, newlines, and carriage returns. For example, normally the brace in "this{brace" is a token and that string will result in three tokens, but in IFSONLY mode it is just one token. | MLX_F_NODISCARD | This flag indicates to the lexer that the calling function expects to be able to read data normally using fdRead() or another lexer session after the last token is read and the session is closed. The lexer will then attempt to "unread" bytes that it buffered during the lexical analysis process (it does fdRead() operations in 2k or so chunks). If this flag is not specified, up to 2k of information after the last token will be discarded and further fdRead()s on the file descriptor will start at an undefined place in the file. | MLX_F_ALLOWNUL | Allow NUL characters ('\0') in the input stream. If this flag is not set, then NUL characters result in an error condition. This prevents unwary callers from mis-reading a token returned by mlxStringVal if the token contains a NUL. If ALLOWNUL is turned on, then the caller must ensure that it is safely handling values with NULs. +| MLX_F_ENFORCEUTF8 | Ensures that all lexed text conforms to UTF-8 encoding standards. If any invalid characters are found, an error token is returned. Must NOT be set at the same time as the MLX_F_ENFORCEASCII flag, described below. +| MLX_F_ENFORCEASCII | Ensures that all lexed text conforms to standard 7 bit ascii. If any invalid bytes are found, an error token is returned. Must NOT be set at the same time as the MLX_F_ENFORCEUTF8 flag, described above. ### pLxSession mlxStringSession(char* str, int flags) This function opens a lexer session from a text string. Same as the above function except that the flag MLX_F_NODISCARD makes no sense for the string. @@ -1079,3 +1084,26 @@ The term "MAY" refers to optional, but permissible, behavior. 9. Testing of query functionality can be done via test_obj's "query", "csv", and "ls" (or "list") commands. To test for nested querying of objects returned from QueryFetch, a SUBTREE select can be used with the "query" or "csv" commands. 10. Drivers which support full sorting or full querying MUST be able to handle the attribute "name" in the expression tree for the sort or query criteria. The "name" attribute SHOULD be mapped to an expression which reflects how "name" is constructed for objects, such as changing "name" to "convert(varchar, prikeyfield1) + '|' + convert(varchar, prikeyfield2)" or whatever is appropriate. + + +## IX String Verification +Centrallix-lib's util library provides a few functions which are useful for verifying that incoming text is properly encoded. This is particularly crucial for drivers which both read external data (e.g. from the filesystem, internet connections, or database connections) and can reasonably expect to encounter UTF-8 encoded characters. Most external drivers attempt to validate all incoming data before it is entered into the object system so that all of the other modules can trust the object system. + +### A. Available Functions +#### int nVerifyUTF8(char* str, int len) +Given the string to be verified and the number of characters to check, returns the index of the start of the first invalid character found, the constant UTIL_VALID_CHAR if the string is valid, or UTIL_INVALID_ARGUMENT if the string pointer was NULL. + +This function detects any bytes which are not valid UTF-8 encodings. In the case of multi-byte characters which are invalid, like overlong encodings, the index of the first byte is returned. This makes truncating data to remove invalid characters simple. + +#### int verifyUTF8(char* str) +This function works exactly nVerifyUTF8, except that it takes a NULL terminated string as a parameter instead of the string and length. This is useful when the data is formatted as a string. If you wish to validate a string that is not NULL terminated or to verify only part of a string, use nVerifyUTF8 instead. + +#### int verifyASCII(char * str) +Given a NULL terminating string, returns the index of the first non 7-bit ASCII character, UTIL_VALID_CHAR if the string is valid ASCII, or UTIL_INVALID_ARGUMENT if the string pointer was NULL. Note that extended ASCII characters (128 and above) are considered invalid. + +### B. Unverified External Drivers +The following is a list of the drivers which do not currently (as of March 2023) feature UTF-8 verification. These were not updated with the rest of the drivers because they were not in active use at the time. +- mbox +- mime +- pop_v3 +- All net drivers, excluding net_http \ No newline at end of file diff --git a/centrallix-sysdoc/Prefixes.md b/centrallix-sysdoc/Prefixes.md index b0e12c6b0..ef8e92ea5 100644 --- a/centrallix-sysdoc/Prefixes.md +++ b/centrallix-sysdoc/Prefixes.md @@ -4,6 +4,7 @@ |---------|--------------------------------------------------------------------- | aud | OSDriver - Linux OSS /dev/dsp audio (plays WAV files on ExecMethod) | bar | BarCode generator module (for prt mgmt) +| chr | Character set utilities | dat | OSDriver - Flat data file (CSV/etc) | ev | MTASK internal - event handling | exp | Expression compiler/parser/evaluator diff --git a/centrallix-sysdoc/README b/centrallix-sysdoc/README index 1707bc13c..ebfa89eac 100644 --- a/centrallix-sysdoc/README +++ b/centrallix-sysdoc/README @@ -56,6 +56,9 @@ The API for interacting with Object Sessions has two fundemental protocols for i ### Traversing Object System like a filesystem The only difference between using the OS and using a filesystem is that the OSML can 'change directories' into an actual file (unlike a filesystem). For example, if the current directory is a file on the HDD that contains the file 'records.csv', one can change the 'current directory' to be records.csv -- where there user can then 'cd' into either 'rows' or 'columns', and from there the user can 'ls' in order to view all the rows/columns. +It is also worth noting that because most input coming into the object system is validated, files or file sub-objects containing invalid +UTF-8 in their names will be hidden. + The C API for how developers use the Object System is currently found in centrallix/include/obj.h (and there might be another file somewhere that also contains C functions for interacting with the ObjSys). #### ObjSys-path (ObjSys-pathname) diff --git a/centrallix-website/howto.htm b/centrallix-website/howto.htm index 705e6e538..6649b1459 100755 --- a/centrallix-website/howto.htm +++ b/centrallix-website/howto.htm @@ -1,7 +1,7 @@ Centrallix Howto - +