fix(string): fix a potential error in the TCString due to short-circuit evaluation
This commit is contained in:
parent
790b7fd5e6
commit
d52f0c4df8
@ -40,9 +40,9 @@ struct TCString
|
|||||||
/** Copies one string to another. The size is used only for buffer safety and will not append null characters to the destination. */
|
/** Copies one string to another. The size is used only for buffer safety and will not append null characters to the destination. */
|
||||||
FORCEINLINE static CharType* Copy(CharType* Destination, size_t DestinationSize, const CharType* Source, size_t SourceSize)
|
FORCEINLINE static CharType* Copy(CharType* Destination, size_t DestinationSize, const CharType* Source, size_t SourceSize)
|
||||||
{
|
{
|
||||||
checkf(Destination && Source, "Read access violation. Destination and source must not be nullptr.");
|
checkf(Destination && Source, TEXT("Read access violation. Destination and source must not be nullptr."));
|
||||||
|
|
||||||
checkf(DestinationSize != 0 && SourceSize != 0, "Illegal buffer size. DestinationSize and SourceSize must not be zero.");
|
checkf(DestinationSize != 0 && SourceSize != 0, TEXT("Illegal buffer size. DestinationSize and SourceSize must not be zero."));
|
||||||
|
|
||||||
if (DestinationSize == IGNORE_SIZE && SourceSize == IGNORE_SIZE)
|
if (DestinationSize == IGNORE_SIZE && SourceSize == IGNORE_SIZE)
|
||||||
{
|
{
|
||||||
@ -73,9 +73,9 @@ struct TCString
|
|||||||
/** Concatenates two strings. The size is used only for buffer safety and will not append null characters to the destination. */
|
/** Concatenates two strings. The size is used only for buffer safety and will not append null characters to the destination. */
|
||||||
FORCEINLINE static CharType* Cat(CharType* Destination, size_t DestinationSize, const CharType* Source, size_t SourceSize)
|
FORCEINLINE static CharType* Cat(CharType* Destination, size_t DestinationSize, const CharType* Source, size_t SourceSize)
|
||||||
{
|
{
|
||||||
checkf(Destination && Source, "Read access violation. Destination and source must not be nullptr.");
|
checkf(Destination && Source, TEXT("Read access violation. Destination and source must not be nullptr."));
|
||||||
|
|
||||||
checkf(DestinationSize != 0 && SourceSize != 0, "Illegal buffer size. DestinationSize and SourceSize must not be zero.");
|
checkf(DestinationSize != 0 && SourceSize != 0, TEXT("Illegal buffer size. DestinationSize and SourceSize must not be zero."));
|
||||||
|
|
||||||
if (DestinationSize == IGNORE_SIZE && SourceSize == IGNORE_SIZE)
|
if (DestinationSize == IGNORE_SIZE && SourceSize == IGNORE_SIZE)
|
||||||
{
|
{
|
||||||
@ -99,9 +99,9 @@ struct TCString
|
|||||||
/** @return The length of a given string. The maximum length is the buffer size. */
|
/** @return The length of a given string. The maximum length is the buffer size. */
|
||||||
NODISCARD FORCEINLINE static size_t Length(const CharType* InString, size_t SourceSize)
|
NODISCARD FORCEINLINE static size_t Length(const CharType* InString, size_t SourceSize)
|
||||||
{
|
{
|
||||||
checkf(InString, "Read access violation. InString must not be nullptr.");
|
checkf(InString, TEXT("Read access violation. InString must not be nullptr."));
|
||||||
|
|
||||||
checkf(SourceSize != 0, "Illegal buffer size. SourceSize must not be zero.");
|
checkf(SourceSize != 0, TEXT("Illegal buffer size. SourceSize must not be zero."));
|
||||||
|
|
||||||
if (SourceSize == IGNORE_SIZE)
|
if (SourceSize == IGNORE_SIZE)
|
||||||
{
|
{
|
||||||
@ -117,9 +117,11 @@ struct TCString
|
|||||||
|
|
||||||
size_t Result = 0;
|
size_t Result = 0;
|
||||||
|
|
||||||
while (*InString++ != LITERAL(CharType, '\0') && SourceSize--)
|
while (*InString != LITERAL(CharType, '\0') && SourceSize != 0)
|
||||||
{
|
{
|
||||||
++Result;
|
++Result;
|
||||||
|
++InString;
|
||||||
|
--SourceSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
@ -128,9 +130,9 @@ struct TCString
|
|||||||
/** Compares two strings. The size is used only for buffer safety not for comparison. */
|
/** Compares two strings. The size is used only for buffer safety not for comparison. */
|
||||||
NODISCARD FORCEINLINE static strong_ordering Compare(const CharType* LHS, size_t LHSSize, const CharType* RHS, size_t RHSSize)
|
NODISCARD FORCEINLINE static strong_ordering Compare(const CharType* LHS, size_t LHSSize, const CharType* RHS, size_t RHSSize)
|
||||||
{
|
{
|
||||||
checkf(LHS && RHS, "Read access violation. LHS and RHS must not be nullptr.");
|
checkf(LHS && RHS, TEXT("Read access violation. LHS and RHS must not be nullptr."));
|
||||||
|
|
||||||
checkf(LHSSize != 0 && RHSSize != 0, "Illegal buffer size. LHSSize and RHSSize must not be zero.");
|
checkf(LHSSize != 0 && RHSSize != 0, TEXT("Illegal buffer size. LHSSize and RHSSize must not be zero."));
|
||||||
|
|
||||||
if (LHSSize == IGNORE_SIZE && RHSSize == IGNORE_SIZE)
|
if (LHSSize == IGNORE_SIZE && RHSSize == IGNORE_SIZE)
|
||||||
{
|
{
|
||||||
@ -144,37 +146,48 @@ struct TCString
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (LHSSize-- && RHSSize--)
|
while (LHSSize != 0 && RHSSize != 0)
|
||||||
{
|
{
|
||||||
if (*LHS != *RHS)
|
if (*LHS != *RHS)
|
||||||
{
|
{
|
||||||
return *LHS <=> *RHS;
|
return *LHS <=> *RHS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*LHS++ == LITERAL(CharType, '\0') || *RHS++ == LITERAL(CharType, '\0')) break;
|
if (*LHS == LITERAL(CharType, '\0') && *RHS == LITERAL(CharType, '\0'))
|
||||||
|
{
|
||||||
|
return strong_ordering::equal;
|
||||||
|
}
|
||||||
|
|
||||||
|
++LHS;
|
||||||
|
++RHS;
|
||||||
|
--LHSSize;
|
||||||
|
--RHSSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return strong_ordering::equal;
|
return LHSSize <=> RHSSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Finds the first or last occurrence of a character that satisfies the predicate. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character that satisfies the predicate. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
||||||
template <CPredicate<CharType> F>
|
template <CPredicate<CharType> F>
|
||||||
NODISCARD FORCEINLINE static const CharType* Find(const CharType* InString, size_t BufferSize, F&& InPredicate, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static const CharType* Find(const CharType* InString, size_t BufferSize, F&& InPredicate, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString, "Read access violation. InString must not be nullptr.");
|
checkf(InString, TEXT("Read access violation. InString must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0, "Illegal buffer size. BufferSize must not be zero.");
|
checkf(BufferSize != 0, TEXT("Illegal buffer size. BufferSize must not be zero."));
|
||||||
|
|
||||||
if (SearchDirection == ESearchDirection::FromStart)
|
if (SearchDirection == ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
while (BufferSize--)
|
while (BufferSize != 0)
|
||||||
{
|
{
|
||||||
if (InvokeResult<bool>(Forward<F>(InPredicate), *InString))
|
if (InvokeResult<bool>(Forward<F>(InPredicate), *InString))
|
||||||
{
|
{
|
||||||
return InString;
|
return InString;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*InString++ == LITERAL(CharType, '\0')) break;
|
if (*InString == LITERAL(CharType, '\0')) break;
|
||||||
|
|
||||||
|
++InString;
|
||||||
|
--BufferSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -190,7 +203,9 @@ struct TCString
|
|||||||
return InString + Index;
|
return InString + Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Index--) break;
|
if (Index == 0) break;
|
||||||
|
|
||||||
|
--Index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,9 +216,9 @@ struct TCString
|
|||||||
template <CPredicate<CharType> F>
|
template <CPredicate<CharType> F>
|
||||||
NODISCARD FORCEINLINE static CharType* Find( CharType* InString, size_t BufferSize, F&& InPredicate, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static CharType* Find( CharType* InString, size_t BufferSize, F&& InPredicate, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString, "Read access violation. InString must not be nullptr.");
|
checkf(InString, TEXT("Read access violation. InString must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0, "Illegal buffer size. BufferSize must not be zero.");
|
checkf(BufferSize != 0, TEXT("Illegal buffer size. BufferSize must not be zero."));
|
||||||
|
|
||||||
check_no_recursion();
|
check_no_recursion();
|
||||||
|
|
||||||
@ -213,9 +228,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static const CharType* FindChar(const CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static const CharType* FindChar(const CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString, "Read access violation. InString must not be nullptr.");
|
checkf(InString, TEXT("Read access violation. InString must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0, "Illegal buffer size. BufferSize must not be zero.");
|
checkf(BufferSize != 0, TEXT("Illegal buffer size. BufferSize must not be zero."));
|
||||||
|
|
||||||
if (BufferSize == IGNORE_SIZE)
|
if (BufferSize == IGNORE_SIZE)
|
||||||
{
|
{
|
||||||
@ -235,9 +250,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static CharType* FindChar( CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static CharType* FindChar( CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString, "Read access violation. InString must not be nullptr.");
|
checkf(InString, TEXT("Read access violation. InString must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0, "Illegal buffer size. BufferSize must not be zero.");
|
checkf(BufferSize != 0, TEXT("Illegal buffer size. BufferSize must not be zero."));
|
||||||
|
|
||||||
check_no_recursion();
|
check_no_recursion();
|
||||||
|
|
||||||
@ -247,9 +262,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character in a charset. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character in a charset. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static const CharType* FindChar(const CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static const CharType* FindChar(const CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString && Charset, "Read access violation. InString and Charset must not be nullptr.");
|
checkf(InString && Charset, TEXT("Read access violation. InString and Charset must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0 && CharsetSize != 0, "Illegal buffer size. BufferSize and CharsetSize must not be zero.");
|
checkf(BufferSize != 0 && CharsetSize != 0, TEXT("Illegal buffer size. BufferSize and CharsetSize must not be zero."));
|
||||||
|
|
||||||
if (BufferSize == IGNORE_SIZE && CharsetSize == IGNORE_SIZE && SearchDirection == ESearchDirection::FromStart)
|
if (BufferSize == IGNORE_SIZE && CharsetSize == IGNORE_SIZE && SearchDirection == ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
@ -278,9 +293,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character in a charset. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character in a charset. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static CharType* FindChar( CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static CharType* FindChar( CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString && Charset, "Read access violation. InString and Charset must not be nullptr.");
|
checkf(InString && Charset, TEXT("Read access violation. InString and Charset must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0 && CharsetSize != 0, "Illegal buffer size. BufferSize and CharsetSize must not be zero.");
|
checkf(BufferSize != 0 && CharsetSize != 0, TEXT("Illegal buffer size. BufferSize and CharsetSize must not be zero."));
|
||||||
|
|
||||||
check_no_recursion();
|
check_no_recursion();
|
||||||
|
|
||||||
@ -290,9 +305,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character that is not the given character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character that is not the given character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static const CharType* FindNotChar(const CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static const CharType* FindNotChar(const CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString, "Read access violation. InString must not be nullptr.");
|
checkf(InString, TEXT("Read access violation. InString must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0, "Illegal buffer size. BufferSize must not be zero.");
|
checkf(BufferSize != 0, TEXT("Illegal buffer size. BufferSize must not be zero."));
|
||||||
|
|
||||||
if (Character == LITERAL(CharType, '\0') && SearchDirection == ESearchDirection::FromStart)
|
if (Character == LITERAL(CharType, '\0') && SearchDirection == ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
@ -319,9 +334,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character that is not the given character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character that is not the given character. The terminating null character is considered to be a part of the string. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static CharType* FindNotChar( CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static CharType* FindNotChar( CharType* InString, size_t BufferSize, CharType Character, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString, "Read access violation. InString must not be nullptr.");
|
checkf(InString, TEXT("Read access violation. InString must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0, "Illegal buffer size. BufferSize must not be zero.");
|
checkf(BufferSize != 0, TEXT("Illegal buffer size. BufferSize must not be zero."));
|
||||||
|
|
||||||
check_no_recursion();
|
check_no_recursion();
|
||||||
|
|
||||||
@ -331,9 +346,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character that is not in the given charset. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character that is not in the given charset. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static const CharType* FindNotChar(const CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static const CharType* FindNotChar(const CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString && Charset, "Read access violation. InString and Charset must not be nullptr.");
|
checkf(InString && Charset, TEXT("Read access violation. InString and Charset must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0 && CharsetSize != 0, "Illegal buffer size. BufferSize and CharsetSize must not be zero.");
|
checkf(BufferSize != 0 && CharsetSize != 0, TEXT("Illegal buffer size. BufferSize and CharsetSize must not be zero."));
|
||||||
|
|
||||||
if (BufferSize == IGNORE_SIZE && CharsetSize == IGNORE_SIZE && SearchDirection == ESearchDirection::FromStart)
|
if (BufferSize == IGNORE_SIZE && CharsetSize == IGNORE_SIZE && SearchDirection == ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
@ -355,9 +370,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a character that is not in the given charset. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a character that is not in the given charset. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static CharType* FindNotChar( CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static CharType* FindNotChar( CharType* InString, size_t BufferSize, const CharType* Charset, size_t CharsetSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString && Charset, "Read access violation. InString and Charset must not be nullptr.");
|
checkf(InString && Charset, TEXT("Read access violation. InString and Charset must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0 && CharsetSize != 0, "Illegal buffer size. BufferSize and CharsetSize must not be zero.");
|
checkf(BufferSize != 0 && CharsetSize != 0, TEXT("Illegal buffer size. BufferSize and CharsetSize must not be zero."));
|
||||||
|
|
||||||
check_no_recursion();
|
check_no_recursion();
|
||||||
|
|
||||||
@ -365,11 +380,11 @@ struct TCString
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Finds the first or last occurrence of a substring. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a substring. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static const CharType* FindString(const CharType* InString, size_t BufferSize, const CharType* Substring, size_t SubstringSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD static const CharType* FindString(const CharType* InString, size_t BufferSize, const CharType* Substring, size_t SubstringSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString && Substring, "Read access violation. InString and Substring must not be nullptr.");
|
checkf(InString && Substring, TEXT("Read access violation. InString and Substring must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0 && SubstringSize != 0, "Illegal buffer size. BufferSize and SubstringSize must not be zero.");
|
checkf(BufferSize != 0 && SubstringSize != 0, TEXT("Illegal buffer size. BufferSize and SubstringSize must not be zero."));
|
||||||
|
|
||||||
if (*Substring == LITERAL(CharType, '\0'))
|
if (*Substring == LITERAL(CharType, '\0'))
|
||||||
{
|
{
|
||||||
@ -423,9 +438,9 @@ struct TCString
|
|||||||
/** Finds the first or last occurrence of a substring. The size is used only for buffer safety. */
|
/** Finds the first or last occurrence of a substring. The size is used only for buffer safety. */
|
||||||
NODISCARD FORCEINLINE static CharType* FindString( CharType* InString, size_t BufferSize, const CharType* Substring, size_t SubstringSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
NODISCARD FORCEINLINE static CharType* FindString( CharType* InString, size_t BufferSize, const CharType* Substring, size_t SubstringSize, ESearchDirection SearchDirection = ESearchDirection::FromStart)
|
||||||
{
|
{
|
||||||
checkf(InString && Substring, "Read access violation. InString and Substring must not be nullptr.");
|
checkf(InString && Substring, TEXT("Read access violation. InString and Substring must not be nullptr."));
|
||||||
|
|
||||||
checkf(BufferSize != 0 && SubstringSize != 0, "Illegal buffer size. BufferSize and SubstringSize must not be zero.");
|
checkf(BufferSize != 0 && SubstringSize != 0, TEXT("Illegal buffer size. BufferSize and SubstringSize must not be zero."));
|
||||||
|
|
||||||
check_no_recursion();
|
check_no_recursion();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user