From cff2d2712adee34a49d74a50fe9d8f77f2549995 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Sun, 1 Sep 2019 12:46:17 +0200 Subject: [PATCH 1/7] Minor update: - Added IntToBinStr() method to convert int to binary output --- UtilCore.cpp | 34 ++++++++++++++++++++++++++++++++++ UtilCore.h | 6 ++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/UtilCore.cpp b/UtilCore.cpp index cbbfd11..29b14f6 100644 --- a/UtilCore.cpp +++ b/UtilCore.cpp @@ -119,6 +119,40 @@ char * BytesToBinStr( const char * Bytes, const int Len, const char * Separator, } //--------------------------------------------------------------------------- +char * IntToBinStr( const int Bytes, const int Len, const char * Separator, char * OutBuf ) +{ + char * TempBuf; + char * BufPos; + bool First = true; + char SepLen = (Separator)? strlen(Separator) : 0; + u_int8_t Byte; + + // Select/create output buffer + if (!OutBuf) { + TempBuf = ReturnStr; + } + else { +// if (!*OutBuf) +// *OutBuf = (char*)malloc( Len*(8+SepLen)+1 ); +// TempBuf = *OutBuf; + TempBuf = OutBuf; + } + BufPos = TempBuf; + + // Print each byte as 8-bit binary + for (int i=Len-1; i>=0; i--) { + Byte = (Bytes >> (i*8)) & 0xFF; + sprintf( BufPos, "%s%c%c%c%c%c%c%c%c", ((First || !Separator)? "" : Separator), + (Byte & 0x80)?'1':'0', (Byte & 0x40)?'1':'0', (Byte & 0x20)?'1':'0', (Byte & 0x10)?'1':'0', + (Byte & 0x08)?'1':'0', (Byte & 0x04)?'1':'0', (Byte & 0x02)?'1':'0', (Byte & 0x01)?'1':'0' ); + BufPos += (First)? 8 : 8+SepLen; + First = false; + } + *BufPos = 0; + return TempBuf; +} +//--------------------------------------------------------------------------- + char * HexStrToBytes( const char * Str, const int Len, const char * Separator, char * OutBuf ) { char * TempBuf; diff --git a/UtilCore.h b/UtilCore.h index dd4425b..d5072bb 100644 --- a/UtilCore.h +++ b/UtilCore.h @@ -18,8 +18,10 @@ // Convert raw bytes to string char * BytesToSafeStr( const char * Bytes, const int Len, const bool NoCrLf = false, const char SpecChar = '.', char * OutBuf = NULL ); -char * BytesToHexStr( const char * Bytes, const int Len, const char *Separator = " ", char * OutBuf = NULL ); -char * BytesToBinStr( const char * Bytes, const int Len, const char *Separator = " ", char * OutBuf = NULL ); +char * BytesToHexStr( const char * Bytes, const int Len, const char * Separator = " ", char * OutBuf = NULL ); +char * BytesToBinStr( const char * Bytes, const int Len, const char * Separator = " ", char * OutBuf = NULL ); + +char * IntToBinStr( const int Bytes, const int Len, const char * Separator = " ", char * OutBuf = NULL ); // Convert string to raw bytes inline u_int8_t HexToInt( char Digit ) { From aa86837e93944916f0065e791def6ba210c5fa98 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Sun, 8 Sep 2019 08:13:03 +0200 Subject: [PATCH 2/7] Minor update: - Move strlcase() from SelectableCore to UtilCore --- SelectableCore.cpp | 1 + SelectableCore.h | 7 ------- UtilCore.h | 10 +++++++++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 814f2e5..62a6a6f 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -25,6 +25,7 @@ // redA Libraries #include "ApplicationCore.h" #include "SelectableCore.h" +#include "UtilCore.h" //--------------------------------------------------------------------------- diff --git a/SelectableCore.h b/SelectableCore.h index 67a8207..bfdc5ea 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -223,13 +223,6 @@ protected: // Buffer operations virtual bool ProcessInputBuffer( THandle * Handle, bool Force ); - // Convert string to lower case - inline char * strlcase( char * Str ) { - for (char * Ch = Str; *Ch; Ch++ ) - *Ch = tolower(*Ch); - return Str; - } - public: // Life Cycle CSelectableBare( const char * Name, const char * Type = TYPE_SELECTABLE ); diff --git a/UtilCore.h b/UtilCore.h index d5072bb..1a8f568 100644 --- a/UtilCore.h +++ b/UtilCore.h @@ -9,7 +9,7 @@ #define REDACORE_UTILCORE_H_ // Standard C/C++ Libraries -/* none */ +#include // redA Libraries /* none */ @@ -36,6 +36,14 @@ char * BinStrToBytes( const char * Str, const int Len, const char * Separator = // Search string data char * StrSearch( const char * Haystack, const char * Needle, const int hLen = 0, const int nLen = 0 ); +// Convert string to lower case +inline char * strlcase( char * Str ) { + for (char * Ch = Str; *Ch; Ch++ ) + *Ch = tolower(*Ch); + return Str; +} + + //--------------------------------------------------------------------------- #endif /* REDACORE_UTILCORE_H_ */ From c2c08c527cf090a5fae6ad2c11b5521b6c477a89 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Sun, 8 Sep 2019 10:01:38 +0200 Subject: [PATCH 3/7] Minor Update: - Add GetAddress() to CApplciation - Call GetAddress() from GetHandleAddress() is SelectableCore - Correct "Name" overload in SelectableCore->Init() --- ApplicationCore.cpp | 18 ++++++++++++++++++ ApplicationCore.h | 2 ++ SelectableBare.cpp | 13 ++----------- SelectableCore.cpp | 20 ++++++++++---------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/ApplicationCore.cpp b/ApplicationCore.cpp index 5c90216..2244562 100644 --- a/ApplicationCore.cpp +++ b/ApplicationCore.cpp @@ -404,6 +404,24 @@ CFunctionCore * CApplication::GetFunction( const char * Name ) } //--------------------------------------------------------------------------- +CDataMember * CApplication::GetAddress( const char * SearchAddress ) +{ + CDataMember * AddressDef = NULL; + char NamePath[100]; + char * Address; + + // Address renamed? + sprintf( NamePath, "Application/Addresses/Rename/%s", SearchAddress ); + if (!(Address = (char*)Config->GetChStr( NamePath, NULL, false ))) { + Address = (char*)SearchAddress; + } + + // Get address def + AddressDef = AddressList->GetChild( Address ); + return AddressDef; +} +//--------------------------------------------------------------------------- + bool CApplication::Run( bool TerminateOnError ) { bool CleanTerminate = true; diff --git a/ApplicationCore.h b/ApplicationCore.h index ef630d6..24c6b7a 100644 --- a/ApplicationCore.h +++ b/ApplicationCore.h @@ -102,6 +102,8 @@ public: CFunctionCore * AddFunction( const char * Type, const char * Name ); CFunctionCore * GetFunction( const char * Name ); + CDataMember * GetAddress( const char * SearchAddress ); + // Run Application bool Run( bool TerminateOnError ); }; diff --git a/SelectableBare.cpp b/SelectableBare.cpp index 07e3994..931a70b 100644 --- a/SelectableBare.cpp +++ b/SelectableBare.cpp @@ -63,19 +63,10 @@ CSelectableBare::~CSelectableBare() CDataMember * CSelectableBare::GetHandleAddress( THandle * Handle, const char * HandleRef ) { CDataMember * AddressDef = NULL; - char NamePath[100]; - char * Address; - // Handle renamed? - sprintf( NamePath, "Application/Addresses/Rename/%s", HandleRef ); - if (!(Address = (char*)Application->Config->GetChStr( NamePath, NULL, false ))) { - Address = (char*)HandleRef; - } - - // Get address def - if ((AddressDef = Application->AddressList->GetChild( Address ))) { + if ((AddressDef = Application->GetAddress( HandleRef ))) { if (Log) Log->Message( LogLevel, dlMedium, "%s/%s: Handle '%s' - Use address '%s' ('%s')", - ProcessName, Name, Handle->Name, Address, HandleRef ); + ProcessName, Name, Handle->Name, AddressDef->GetName(), HandleRef ); } return AddressDef; } diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 62a6a6f..4336761 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -41,7 +41,7 @@ CFunctionCore * NewSelectableCore( const char * Name ) { } //--------------------------------------------------------------------------- -// Resolve action handlder +// Resolve action handler void ResolveHandler( int Signal, siginfo_t * SignalInfo, void * Context ) { TResolveReq * ResolveReq; @@ -107,7 +107,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) CDataMember * SerialConfig; THandle * Handle; char * Type; - char * Name; + char * PortName; char * Address; char * Port; char * ParityText; @@ -133,7 +133,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) Type = (char*)HandleConfig->GetChStr( "Type", "TCPclient", true ); if (!strcasecmp( Type, "Serial" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Port/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Port/Name", NULL )) && (AddressDef = Application->AddressList->GetChild( PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value } else { Address = (char*)HandleConfig->GetChStr( "Port/Address", NULL, true ); // Get default value @@ -177,7 +177,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } else if (!strcasecmp( Type, "LinePrinter" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Port/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Port/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value } else { Address = (char*)HandleConfig->GetChStr( "Port/Address", NULL, true ); // Get default value @@ -187,7 +187,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } else if (!strcasecmp( Type, "UNIXserver" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value } else { Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value @@ -198,7 +198,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } else if (!strcasecmp( Type, "UNIXclient" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value } else { Address = (char*)HandleConfig->GetChStr( "Socket/Address", NULL, true ); // Get default Address value @@ -208,7 +208,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } else if (!strcasecmp( Type, "UDPserver" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { @@ -220,7 +220,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } else if (!strcasecmp( Type, "UDPclient" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { @@ -232,7 +232,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } else if (!strcasecmp( Type, "TCPserver" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { @@ -245,7 +245,7 @@ bool CSelectableCore::Init( CDataMember * FunctionConfig ) } else if (!strcasecmp( Type, "TCPclient" )) { - if ((Name = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, Name ))) { + if ((PortName = (char*)HandleConfig->GetChStr( "Socket/Name", NULL )) && (AddressDef = GetHandleAddress( Handle, PortName ))) { Address = (char*)AddressDef->GetChStr( "Address", NULL, true ); // Get address list value Port = (char*)AddressDef->GetChStr( "Port", "0", true ); // Get AddressList Port value } else { From 7c77d564a760f9a4dfa823c5b3d2cb6ebeabed6f Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Sun, 6 Oct 2019 19:38:11 +0200 Subject: [PATCH 4/7] Minor Updates: - DateTimeCore: - Specify separator between date & time fof BiuildDateTimeStr(); - UtilCore: - Add UrlEncode() and UrlDecode() functions --- DateTimeCore.cpp | 8 +++-- DateTimeCore.h | 5 ++-- UtilCore.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ UtilCore.h | 7 +++++ 4 files changed, 91 insertions(+), 5 deletions(-) diff --git a/DateTimeCore.cpp b/DateTimeCore.cpp index 1aa388f..539bbdf 100644 --- a/DateTimeCore.cpp +++ b/DateTimeCore.cpp @@ -417,11 +417,12 @@ char const * BuildTimeStr( unsigned char Hours, unsigned char Minutes, unsigned char const * BuildDateTimeStr( unsigned char Day, unsigned char Month, unsigned Year, unsigned char Hours, unsigned char Minutes, unsigned char Seconds, - const char * DateSeparator, const char * TimeSeparator ) + const char * DateSeparator, const char * TimeSeparator, const char * Separator ) { // Build String - sprintf( ReturnStr, "%04d%s%02d%s%02d %02d%s%02d%s%02d", + sprintf( ReturnStr, "%04d%s%02d%s%02d%s%02d%s%02d%s%02d", Year, ((DateSeparator)? DateSeparator : ""), Month, ((DateSeparator)? DateSeparator : ""), Day, + Separator, Hours, ((TimeSeparator)? TimeSeparator : ""), Minutes, ((TimeSeparator)? TimeSeparator : ""), Seconds ); return (ReturnStr); @@ -457,7 +458,8 @@ char const * BuildTimeStr( const time_t EpochTime, bool LocalTime, const char * } //--------------------------------------------------------------------------- -char const * BuildDateTimeStr( const time_t EpochTime, bool LocalTime, const char * DateSeparator, const char * TimeSeparator ) +char const * BuildDateTimeStr( const time_t EpochTime, bool LocalTime, + const char * DateSeparator, const char * TimeSeparator, const char * Separator ) { unsigned char Day; unsigned char Month; diff --git a/DateTimeCore.h b/DateTimeCore.h index 1fe92ff..dcd9257 100644 --- a/DateTimeCore.h +++ b/DateTimeCore.h @@ -50,11 +50,12 @@ char const * BuildDateStr( unsigned char Day, unsigned char Month, unsigned Yea char const * BuildTimeStr( unsigned char Hours, unsigned char Minutes, unsigned char Seconds, const char * TimeSeparator = ":" ); char const * BuildDateTimeStr( unsigned char Day, unsigned char Month, unsigned Year, unsigned char Hours, unsigned char Minutes, unsigned char Seconds, - const char * DateSeparator = "/", const char * TimeSeparator = ":" ); + const char * DateSeparator = "/", const char * TimeSeparator = ":", const char * Separator = " " ); char const * BuildDateStr( const time_t EpochTime, bool LocalTime, const char * DateSeparator = "/" ); char const * BuildTimeStr( const time_t EpochTime, bool LocalTime, const char * TimeSeparator = ":" ); -char const * BuildDateTimeStr( const time_t EpochTime, bool LocalTime, const char * DateSeparator = "/", const char * TimeSeparator = ":" ); +char const * BuildDateTimeStr( const time_t EpochTime, bool LocalTime, + const char * DateSeparator = "/", const char * TimeSeparator = ":", const char * Separator = " " ); //--------------------------------------------------------------------------- diff --git a/UtilCore.cpp b/UtilCore.cpp index 29b14f6..beac708 100644 --- a/UtilCore.cpp +++ b/UtilCore.cpp @@ -213,3 +213,79 @@ char * StrSearch( const char * Haystack, const char * Needle, const int Haystac return NULL; } //--------------------------------------------------------------------------- + +bool UrlEncode( const char * Input, char * Output, char ** EndPos ) +{ + int c; + char h[] = "0123456789abcdef"; + char * Ipos = (char*)Input; + char * Opos = Output; + + if (!Ipos || !Opos) { + if (*EndPos) *EndPos = NULL; + return false; + } + + while ((c = *Ipos)) { + if ((('a' <= c) && (c <= 'z')) || + (('A' <= c) && (c <= 'Z')) || + (('0' <= c) && (c <= '9')) || + (c == '-') || (c == '_') || (c == '.')) { + *Opos = *Ipos; + Opos++; + } + else if (c == ' ') { + *Opos = '+'; + Opos++; + } + else { + Opos[0] = '%'; + Opos[1] = h[c >> 4]; + Opos[2] = h[c & 0x0f]; + Opos += 3; + } + Ipos++; + } + *Opos = 0; + if (EndPos) *EndPos = Opos; + return true; +} +//--------------------------------------------------------------------------- + +bool UrlDecode( const char * Input, char * Output, char ** EndPos ) +{ + char c, c1, c2; + char * Ipos = (char*)Input; + char * Opos = Output; + + if (!Ipos || !Opos) { + if (EndPos) *EndPos = Output; + return false; + } + + while ((c = *Ipos)) { + if (c == '%') { + if (!(c1 = tolower(Ipos[1])) || + !(c2 = tolower(Ipos[2])) || + !isxdigit(c1) || !isxdigit(c2)) + return false; + c1 = (c1 <= '9')? (c1 - '0') : (c1 - 'a' + 10); + c2 = (c2 <= '9')? (c2 - '0') : (c2 - 'a' + 10); + *Opos = 16*c1 + c2; + Ipos += 3; + } + else if (c == '+') { + *Opos = ' '; + Ipos++; + } + else { + *Opos = c; + Ipos++; + } + Opos++; + } + *Opos = 0; + if (EndPos) *EndPos = Opos; + return true; +} +//--------------------------------------------------------------------------- diff --git a/UtilCore.h b/UtilCore.h index 1a8f568..2e078d6 100644 --- a/UtilCore.h +++ b/UtilCore.h @@ -33,6 +33,8 @@ inline u_int8_t HexToInt( char Digit ) { char * HexStrToBytes( const char * Str, const int Len, const char * Separator = NULL, char * OutBuf = NULL ); char * BinStrToBytes( const char * Str, const int Len, const char * Separator = NULL, char * OutBuf = NULL ); +//--------------------------------------------------------------------------- + // Search string data char * StrSearch( const char * Haystack, const char * Needle, const int hLen = 0, const int nLen = 0 ); @@ -43,6 +45,11 @@ inline char * strlcase( char * Str ) { return Str; } +//--------------------------------------------------------------------------- + +// URL encoding & decoding +bool UrlEncode( const char * Input, char * Output, char ** EndPos = NULL ); +bool UrlDecode( const char * Input, char * Output, char ** EndPos = NULL ); //--------------------------------------------------------------------------- From b5912123ccb485002c0eeffcbc807643e2b2dc61 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Sun, 13 Oct 2019 23:18:50 +0200 Subject: [PATCH 5/7] Minor update: - Add separator between date/time for GetDateTimeStr() --- DateTimeCore.cpp | 5 +++-- DateTimeCore.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/DateTimeCore.cpp b/DateTimeCore.cpp index 539bbdf..6dade96 100644 --- a/DateTimeCore.cpp +++ b/DateTimeCore.cpp @@ -207,7 +207,7 @@ char const * GetTimeStr( const char * TimeSeparator ) } //--------------------------------------------------------------------------- -char const * GetDateTimeStr( const char * DateSeparator, const char * TimeSeparator ) +char const * GetDateTimeStr( const char * DateSeparator, const char * TimeSeparator, const char * Separator ) { unsigned char Day; unsigned char Month; @@ -221,8 +221,9 @@ char const * GetDateTimeStr( const char * DateSeparator, const char * TimeSepar GetTime( Hours, Minutes, Seconds ); // Build String - sprintf( ReturnStr, "%04d%s%02d%s%02d %02d%s%02d%s%02d", + sprintf( ReturnStr, "%04d%s%02d%s%02d%s%02d%s%02d%s%02d", Year, ((DateSeparator)? DateSeparator : ""), Month, ((DateSeparator)? DateSeparator : ""), Day, + Separator, Hours, ((TimeSeparator)? TimeSeparator : ""), Minutes, ((TimeSeparator)? TimeSeparator : ""), Seconds ); return (ReturnStr); diff --git a/DateTimeCore.h b/DateTimeCore.h index dcd9257..b744965 100644 --- a/DateTimeCore.h +++ b/DateTimeCore.h @@ -29,7 +29,7 @@ bool SetDateTime( unsigned char Day, unsigned char Month, unsigned Year, char const * GetDateStr( const char * DateSeparator = "/" ); char const * GetTimeStr( const char * TimeSeparator = ":" ); -char const * GetDateTimeStr( const char * DateSeparator = "/", const char * TimeSeparator = ":" ); +char const * GetDateTimeStr( const char * DateSeparator = "/", const char * TimeSeparator = ":", const char * Separator = " " ); //--------------------------------------------------------------------------- From d8f8d6851c094d4beb1fb4de6d0b58444043744d Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Mon, 4 Nov 2019 13:15:04 +0200 Subject: [PATCH 6/7] Important Update: - JSONparseCore: - Bug fix: Always shows "No content after root" error --- JSONparseCore.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index ef35ed0..b57be5e 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -364,7 +364,10 @@ bool CJSONparse::ReadFromBuffer( const char * BasePath ) // Ensure remainder of file is empty SkipWhiteSpace(); - if (*BufPos != 0) { + if (Error) { + return false; + } + else if (*BufPos != 0) { Error = true; CharNo += BufPos-Mark; sprintf( ErrorText, "No content expected after Root object on line %d:%d", LineNo, CharNo ); From 1b20ee4c1a12639a054cfc8a7c673e7d1e8fbc24 Mon Sep 17 00:00:00 2001 From: Charl Wentzel Date: Mon, 4 Nov 2019 13:29:53 +0200 Subject: [PATCH 7/7] Important Update: - JSONparseCore: - Bug Fix: Always report "First entry must be Object" error --- JSONparseCore.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index b57be5e..b879e8b 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -352,26 +352,21 @@ bool CJSONparse::ReadFromBuffer( const char * BasePath ) // Parse Root Object SkipWhiteSpace(); - if (!ParseObject( BaseMember ) && !Error && !ParseArray( BaseMember )) { - if (!Error) { - Error = true; - CharNo += BufPos-Mark; - sprintf( ErrorText, "First entry in file must be an Object or Array on line %d:%d", LineNo, CharNo ); - } - FreeBuffer(); + if (!ParseObject( BaseMember ) && !Error && !ParseArray( BaseMember ) && !Error) { + Error = true; + CharNo += BufPos-Mark; + sprintf( ErrorText, "First entry in file must be an Object or Array on line %d:%d", LineNo, CharNo ); + } + if (Error) { return false; } // Ensure remainder of file is empty SkipWhiteSpace(); - if (Error) { - return false; - } - else if (*BufPos != 0) { + if (*BufPos != 0) { Error = true; CharNo += BufPos-Mark; sprintf( ErrorText, "No content expected after Root object on line %d:%d", LineNo, CharNo ); - FreeBuffer(); return false; }