diff --git a/microscript/ILibDuktape_ScriptContainer.c b/microscript/ILibDuktape_ScriptContainer.c index c23bd29..7001d5b 100644 --- a/microscript/ILibDuktape_ScriptContainer.c +++ b/microscript/ILibDuktape_ScriptContainer.c @@ -1638,10 +1638,10 @@ duk_ret_t ILibDuktape_ScriptContainer_OS_arch(duk_context *ctx) } else { - int mlen = strlen(u.machine); + int mlen = strlen(u.machine); // size is not specified, but is gauranteed to be NULL terminated if (mlen > 4 && strncmp(u.machine, "armv", 4) == 0) { - if (atoi(u.machine + 4) > 7) + if (ILib_atoi2_int32(u.machine + 4, mlen) > 7) { duk_push_string(ctx, "arm64"); } diff --git a/microscript/ILibDuktape_net.c b/microscript/ILibDuktape_net.c index 8e52945..db99db8 100644 --- a/microscript/ILibDuktape_net.c +++ b/microscript/ILibDuktape_net.c @@ -2134,7 +2134,7 @@ duk_ret_t ILibDuktape_TLS_connect(duk_context *ctx) if (pct > 0) { hostCopy[pct] = 0; - pct = atoi(hostCopy + pct + 1); + pct = ILib_atoi2_int32(hostCopy + pct + 1, sizeof(hostCopy)); } else { diff --git a/microscript/ILibduktape_EventEmitter.c b/microscript/ILibduktape_EventEmitter.c index 058aca3..96646e5 100644 --- a/microscript/ILibduktape_EventEmitter.c +++ b/microscript/ILibduktape_EventEmitter.c @@ -156,7 +156,7 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch { memcpy_s(numtmp, sizeof(numtmp), pr2->LastResult->data, pr2->LastResult->datalength); numtmp[pr2->LastResult->datalength] = 0; - retVal = atoi(numtmp); + retVal = ILib_atoi2_int32(numtmp, sizeof(numtmp)); ILibDestructParserResults(pr2); break; } diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 3a3593c..ec9b6ad 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -1077,6 +1077,53 @@ void ILibMemory_Free(void *ptr) free(ILibMemory_RawPtr(ptr)); } } +int ILib_atoi_uint64_ex(uint64_t *val, const char *instr, size_t instrLen, uint64_t MAX) +{ + char* eptr; + *val = strtoull(instr, &eptr, 10); + int e = errno; + if (errno == ERANGE || eptr == instr || *val > MAX) + { + *val = 0; + return(1); + } + return(0); +} +int ILib_atoi_uint32_ex(uint32_t *val, const char *instr, size_t instrLen, uint64_t MAX) +{ + uint64_t v64; + int ret = ILib_atoi_uint64_ex(&v64, instr, instrLen, MAX); + *val = (uint32_t)v64; + return(ret); +} +int ILib_atoi_uint16_ex(uint16_t *val, const char *instr, size_t instrLen, uint64_t MAX) +{ + uint64_t v64; + int ret = ILib_atoi_uint64_ex(&v64, instr, instrLen, MAX); + *val = (uint16_t)v64; + return(ret); +} +uint64_t ILib_atoi2_uint64(const char *instr, size_t instrLen) +{ + uint64_t val; + if (ILib_atoi_uint64(&val, instr, instrLen) != 0) { val = 0; } + return(val); +} +uint32_t ILib_atoi2_uint32(const char *instr, size_t instrLen) +{ + uint32_t val; + if (ILib_atoi_uint32(&val, instr, instrLen) != 0) { val = 0; } + return(val); + +} +uint16_t ILib_atoi2_uint16(const char *instr, size_t instrLen) +{ + uint16_t val; + if (ILib_atoi_uint16(&val, instr, instrLen) != 0) { val = 0; } + return(val); +} + + #ifdef WIN32 int ILibMemory_CanaryOK(void *ptr) @@ -5917,7 +5964,7 @@ struct packetheader* ILibParsePacketHeader(char* buffer, int offset, int length) // The other tokens contain the Status code and data // tempbuffer[StartLine->FirstResult->NextResult->datalength] = '\0'; - RetVal->StatusCode = (int)atoi(tempbuffer); + RetVal->StatusCode = ILib_atoi2_int32(tempbuffer, 255); free(tempbuffer); RetVal->StatusData = StartLine->FirstResult->NextResult->NextResult != NULL ? StartLine->FirstResult->NextResult->NextResult->data : NULL; RetVal->StatusDataLength = RetVal->StatusData != NULL ? ((int)((f->data + f->datalength) - RetVal->StatusData)) : 0; @@ -6395,7 +6442,7 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr, if ((TempString2 = (char*)malloc(result3->LastResult->datalength + 1)) == NULL) ILIBCRITICALEXIT(254); memcpy_s(TempString2, result3->LastResult->datalength + 1, result3->LastResult->data, result3->LastResult->datalength); TempString2[result3->LastResult->datalength] = '\0'; - lport = (unsigned short)atoi(TempString2); + lport = ILib_atoi2_uint16(TempString2, result3->LastResult->datalength + 1); free(TempString2); } } @@ -6442,7 +6489,7 @@ ILibParseUriResult ILibParseUriEx (const char* URI, size_t URILen, char** Addr, if (pct > 0) { laddr[pct] = 0; - pct = atoi(laddr + pct + 1); + pct = ILib_atoi2_int32(laddr + pct + 1, laddrLen - 1); } else { @@ -9525,14 +9572,14 @@ int ILibTime_ValidateTimePortion(char *timeString) if (pr->FirstResult->datalength==2 && pr->FirstResult->NextResult->datalength==2) // Klockwork says this could be NULL, but that is not possible because NumResults is 3 or 4 { temp = ILibString_Copy(pr->FirstResult->data,pr->FirstResult->datalength); - if (atoi(temp)<24 && atoi(temp)>=0) + if (ILib_atoi2_int32(temp, pr->FirstResult->datalength)<24 && ILib_atoi2_int32(temp, pr->FirstResult->datalength) >=0) { // // hh is correct // free(temp); temp = ILibString_Copy(pr->FirstResult->NextResult->data,pr->FirstResult->NextResult->datalength); - if (atoi(temp)>=0 && atoi(temp)<60) + if (ILib_atoi2_int32(temp, pr->FirstResult->NextResult->datalength)>=0 && ILib_atoi2_int32(temp, pr->FirstResult->NextResult->datalength)<60) { // // mm is correct @@ -9542,7 +9589,7 @@ int ILibTime_ValidateTimePortion(char *timeString) switch((int)strnlen_s(temp, length-6)) { case 2: // ss - if (!(atoi(temp)>=0 && atoi(temp)<60)) + if (!(ILib_atoi2_int32(temp, length-6)>=0 && ILib_atoi2_int32(temp, length - 6)<60)) { RetVal=1; } @@ -9551,7 +9598,7 @@ int ILibTime_ValidateTimePortion(char *timeString) if (temp[2]=='Z') { temp[2]=0; - if (!(atoi(temp)>=0 && atoi(temp)<60)) + if (!(ILib_atoi2_int32(temp, length - 6) >=0 && ILib_atoi2_int32(temp, length - 6)<60)) { RetVal=1; } @@ -9566,7 +9613,7 @@ int ILibTime_ValidateTimePortion(char *timeString) if (temp[2]=='.') { temp[2]=0; - if (!(atoi(temp)>=0 && atoi(temp)<60)) + if (!(ILib_atoi2_int32(temp, length - 6) >=0 && ILib_atoi2_int32(temp, length - 6)<60)) { RetVal = 1; } @@ -9584,7 +9631,7 @@ int ILibTime_ValidateTimePortion(char *timeString) if (temp[2]=='-' || temp[2]=='+') { temp[2] = 0; - if (!(atoi(temp)>=0 && atoi(temp)<60 && atoi(temp+3)>=0 && atoi(temp+3)<24)) + if (!(ILib_atoi2_int32(temp, length - 6) >=0 && ILib_atoi2_int32(temp, length-6)<60 && ILib_atoi2_int32(temp+3, length - 6) >=0 && ILib_atoi2_int32(temp+3, length - 6)<24)) { RetVal=1; } @@ -9598,7 +9645,7 @@ int ILibTime_ValidateTimePortion(char *timeString) if (temp[2]=='.' && temp[9]==':' && (temp[6]=='+' || temp[6]=='-')) { temp[2]=0; - if (!(atoi(temp)>=0 && atoi(temp)<60)) + if (!(ILib_atoi2_int32(temp, length - 6) >=0 && ILib_atoi2_int32(temp, length - 6)<60)) { RetVal = 1; } @@ -9617,7 +9664,7 @@ int ILibTime_ValidateTimePortion(char *timeString) // // Check the last mm component // - if (!(atoi(pr->LastResult->data)>=0 && atoi(pr->LastResult->data)<60)) + if (!(ILib_atoi2_int32(pr->LastResult->data, pr->LastResult->datalength)>=0 && ILib_atoi2_int32(pr->LastResult->data, pr->LastResult->datalength)<60)) { RetVal=1; } @@ -9674,12 +9721,12 @@ char* ILibTime_ValidateDatePortion(char *timeString) { // This means it is in yyyy-xx-zz format startTime = ILibString_Copy(pr->FirstResult->NextResult->data,pr->FirstResult->NextResult->datalength); - if (atoi(startTime)<=12 && atoi(startTime)>0) + if (ILib_atoi2_int32(startTime, pr->FirstResult->NextResult->datalength)<=12 && ILib_atoi2_int32(startTime, pr->FirstResult->NextResult->datalength)>0) { // This means it is in yyyy-mm-xx format free(startTime); startTime = ILibString_Copy(pr->LastResult->data,pr->LastResult->datalength); - if (atoi(startTime)<=31 && atoi(startTime)>0) + if (ILib_atoi2_int32(startTime, pr->LastResult->datalength)<=31 && ILib_atoi2_int32(startTime, pr->LastResult->datalength)>0) { // Everything in correct format errCode = 0; @@ -9794,9 +9841,9 @@ int ILibTime_ParseEx(char *timeString, time_t *val) day = pr2->LastResult->data; day[pr2->LastResult->datalength]=0; - t.tm_year = atoi(year)-1900; - t.tm_mon = atoi(month)-1; - t.tm_mday = atoi(day); + t.tm_year = ILib_atoi2_int32(year, pr2->FirstResult->datalength)-1900; + t.tm_mon = ILib_atoi2_int32(month, pr2->FirstResult->NextResult->datalength)-1; + t.tm_mday = ILib_atoi2_int32(day, pr2->LastResult->datalength); ILibDestructParserResults(pr2); } @@ -9826,9 +9873,9 @@ int ILibTime_ParseEx(char *timeString, time_t *val) } if (hour!=NULL && minute!=NULL && second!=NULL) { - t.tm_hour = atoi(hour); - t.tm_min = atoi(minute); - t.tm_sec = atoi(second); + t.tm_hour = ILib_atoi2_int32(hour, pr2->FirstResult->datalength); + t.tm_min = ILib_atoi2_int32(minute, pr2->FirstResult->NextResult->datalength); + t.tm_sec = ILib_atoi2_int32(second, 2); RetVal = mktime(&t); } diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index 2b65ae5..83ce0cf 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -170,6 +170,24 @@ static inline void ignore_result(uintptr_t result) { (void)result; } #define PRINTERROR() #endif + +int ILib_atoi_uint64_ex(uint64_t *val, const char *instr, size_t instrLen, uint64_t MAX); +int ILib_atoi_uint32_ex(uint32_t *val, const char *instr, size_t instrLen, uint64_t MAX); +int ILib_atoi_uint16_ex(uint16_t *val, const char *instr, size_t instrLen, uint64_t MAX); +uint64_t ILib_atoi2_uint64(const char *instr, size_t instrLen); +uint32_t ILib_atoi2_uint32(const char *instr, size_t instrLen); +uint16_t ILib_atoi2_uint16(const char *instr, size_t instrLen); +#define ILib_atoi2_int64(instr, instrLen) (ILib_atoi2_uint64(instr, instrLen)<=INT64_MAX?ILib_atoi2_uint64(instr, instrLen):0) +#define ILib_atoi2_int32(instr, instrLen) (ILib_atoi2_uint64(instr, instrLen)<=INT32_MAX?ILib_atoi2_uint32(instr, instrLen):0) +#define ILib_atoi2_int16(instr, instrLen) (ILib_atoi2_uint64(instr, instrLen)<=INT16_MAX?ILib_atoi2_uint16(instr, instrLen):0) + +#define ILib_atoi_uint64(pval, instr, instrLen) ILib_atoi_uint64_ex(pval, instr, instrLen, UINT64_MAX) +#define ILib_atoi_int64(pval, instr, instrLen) ILib_atoi_uint64_ex(pval, instr, instrLen, INT64_MAX) +#define ILib_atoi_uint32(pval, instr, instrLen) ILib_atoi_uint32_ex(pval, instr, instrLen, UINT32_MAX) +#define ILib_atoi_int32(pval, instr, instrLen) ILib_atoi_uint32_ex(pval, instr, instrLen, INT32_MAX) +#define ILib_atoi_uint16(pval, instr, instrLen) ILib_atoi_uint16_ex(pval, instr, instrLen, UINT16_MAX) +#define ILib_atoi_int16(pval, instr, instrLen) ILib_atoi_uint16_ex(pval, instr, instrLen, INT16_MAX) + #ifdef WIN32 char *ILibWideToUTF8Ex(WCHAR* wstr, int wstrCharacterLen, char *buffer, int bufferLen); #define ILibWideToUTF8(wstr, wstrCharacterLen) ILibWideToUTF8Ex(wstr, wstrCharacterLen, NULL, 0) diff --git a/microstack/ILibProcessPipe.c b/microstack/ILibProcessPipe.c index 0c5c568..d23622f 100644 --- a/microstack/ILibProcessPipe.c +++ b/microstack/ILibProcessPipe.c @@ -666,31 +666,31 @@ ILibProcessPipe_Process ILibProcessPipe_Manager_SpawnProcessEx4(ILibProcessPipe_ { if (strcasecmp("LINES", options[0]) == 0) { - w.ws_row = atoi(options[1]); + w.ws_row = ILib_atoi2_uint16(options[1], 0); } else if (strcasecmp("COLUMNS", options[0]) == 0) { - w.ws_col = atoi(options[1]); + w.ws_col = ILib_atoi2_uint16(options[1], 0); } else if (strcasecmp("c_iflag", options[0]) == 0) { flags = 1; - tios.c_iflag = (tcflag_t)atoi(options[1]); + tios.c_iflag = (tcflag_t)ILib_atoi2_uint32(options[1], 0); } else if (strcasecmp("c_oflag", options[0]) == 0) { flags = 1; - tios.c_oflag = (tcflag_t)atoi(options[1]); + tios.c_oflag = (tcflag_t)ILib_atoi2_uint32(options[1], 0); } else if (strcasecmp("c_cflag", options[0]) == 0) { flags = 1; - tios.c_cflag = (tcflag_t)atoi(options[1]); + tios.c_cflag = (tcflag_t)ILib_atoi2_uint32(options[1], 0); } else if (strcasecmp("c_lflag", options[0]) == 0) { flags = 1; - tios.c_lflag = (tcflag_t)atoi(options[1]); + tios.c_lflag = (tcflag_t)ILib_atoi2_uint32(options[1], 0); } options += 2; diff --git a/microstack/ILibSimpleDataStore.c b/microstack/ILibSimpleDataStore.c index 34fce04..80cf2f3 100644 --- a/microstack/ILibSimpleDataStore.c +++ b/microstack/ILibSimpleDataStore.c @@ -846,7 +846,7 @@ __EXPORT_TYPE int ILibSimpleDataStore_GetInt(ILibSimpleDataStore dataStore, char { int bufLen = ILibSimpleDataStore_Get(dataStore, key, ILibScratchPad, sizeof(ILibScratchPad)); if (bufLen == 0 || bufLen >= sizeof(ILibScratchPad)) { return(defaultValue); } - return(atoi(ILibScratchPad)); + return(ILib_atoi2_int32(ILibScratchPad, sizeof(ILibScratchPad))); } // Get a value from the data store given a key diff --git a/microstack/ILibWebClient.c b/microstack/ILibWebClient.c index bf55102..a8bc553 100644 --- a/microstack/ILibWebClient.c +++ b/microstack/ILibWebClient.c @@ -1665,7 +1665,7 @@ ILibWebClient_DataResults ILibWebClient_OnData(ILibAsyncSocket_SocketModule sock // wcdo->WaitForClose = 0; phfn->FieldData[phfn->FieldDataLength] = '\0'; - wcdo->BytesLeft = atoi(phfn->FieldData); + wcdo->BytesLeft = ILib_atoi2_int32(phfn->FieldData, phfn->FieldDataLength); if (wcdo->BytesLeft < 0) { wcdo->BytesLeft = 0; @@ -3370,14 +3370,14 @@ void ILibWebClient_Parse_ContentRange(char *contentRange, int *Start, int *End, { hasErrors = 1; } - *TotalLength = atoi(pr2->LastResult->data); + *TotalLength = ILib_atoi2_int32(pr2->LastResult->data, pr2->LastResult->datalength); pr3 = ILibParseString(pr2->FirstResult->data, 0, pr2->FirstResult->datalength, "-", 1); if (pr3->NumResults==2) { pr3->FirstResult->data[pr3->FirstResult->datalength] = 0; pr3->LastResult->data[pr3->LastResult->datalength] = 0; - *Start = atoi(pr3->FirstResult->data); - *End = atoi(pr3->LastResult->data); + *Start = ILib_atoi2_int32(pr3->FirstResult->data, pr3->FirstResult->datalength); + *End = ILib_atoi2_int32(pr3->LastResult->data, pr3->LastResult->datalength); if (pr3->FirstResult->datalength == 0 || pr3->LastResult->datalength == 0) { hasErrors = 1; diff --git a/microstack/ILibWrapperWebRTC.c b/microstack/ILibWrapperWebRTC.c index 27db15a..e611db3 100644 --- a/microstack/ILibWrapperWebRTC.c +++ b/microstack/ILibWrapperWebRTC.c @@ -231,20 +231,20 @@ char* ILibWrapper_SdpToBlock(char* sdp, int sdpLen, int *isActive, char **userna unsigned short port; tmp[pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->NextResult->datalength] = 0; - port = (unsigned short)atoi(tmp); + port = ILib_atoi2_uint16(tmp, pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->NextResult->datalength); pr3 = ILibParseString(pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->data, 0, pr2->FirstResult->NextResult->NextResult->NextResult->NextResult->datalength, ".", 1); if (pr3->NumResults == 4) { candidateData = pr3->FirstResult->data; pr3->FirstResult->data[pr3->FirstResult->datalength] = 0; - candidateData[0] = (char)atoi(pr3->FirstResult->data); + candidateData[0] = (char)ILib_atoi2_int16(pr3->FirstResult->data, pr3->FirstResult->datalength); pr3->FirstResult->NextResult->data[pr3->FirstResult->NextResult->datalength] = 0; - candidateData[1] = (char)atoi(pr3->FirstResult->NextResult->data); + candidateData[1] = (char)ILib_atoi2_int16(pr3->FirstResult->NextResult->data, pr3->FirstResult->NextResult->datalength); pr3->FirstResult->NextResult->NextResult->data[pr3->FirstResult->NextResult->NextResult->datalength] = 0; - candidateData[2] = (char)atoi(pr3->FirstResult->NextResult->NextResult->data); + candidateData[2] = (char)ILib_atoi2_int16(pr3->FirstResult->NextResult->NextResult->data, pr3->FirstResult->NextResult->NextResult->datalength); pr3->FirstResult->NextResult->NextResult->NextResult->data[pr3->FirstResult->NextResult->NextResult->NextResult->datalength] = 0; - candidateData[3] = (char)atoi(pr3->FirstResult->NextResult->NextResult->NextResult->data); + candidateData[3] = (char)ILib_atoi2_int16(pr3->FirstResult->NextResult->NextResult->NextResult->data, pr3->FirstResult->NextResult->NextResult->NextResult->datalength); ((unsigned short*)candidateData)[2] = htons(port); candidateData[6] = 0; @@ -1015,7 +1015,7 @@ int ILibWrapper_WebRTC_PerformStunEx(ILibWrapper_WebRTC_ConnectionStruct *connec memcpy_s(temp, sizeof(temp), connection->stunServerList[i], delimiter); temp[delimiter] = 0; host = temp; - port = (unsigned short)atoi(connection->stunServerList[i] + delimiter + 1); + port = ILib_atoi2_uint16(connection->stunServerList[i] + delimiter + 1, 255); } else {