summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorchocolate42 <[email protected]>2023-04-06 11:34:37 +0100
committerGitHub <[email protected]>2023-04-06 12:34:37 +0200
commit8367abad1a925fc7cf60fd8e71b5f6dbf6250ddb (patch)
tree5fc176a58895f00f1e832b7fe901f732025dad18 /src
parent17c443ee6db0a111d111e766bb517657204c3574 (diff)
downloadraylib-8367abad1a925fc7cf60fd8e71b5f6dbf6250ddb.tar.gz
raylib-8367abad1a925fc7cf60fd8e71b5f6dbf6250ddb.zip
[rtext] Fix GetCodepointNext() to return default value on invalid input with size=0 (#2997)
* Fix GetCodepointNext to return default value with size=0 on invalid input. Modify LoadCodepoints to work when GetCodepointNext returns a size of 0. All internal use of GetCodepointNext and GetCodepointPrev checked. This fix may break external code dealing with invalid input as the old code erroneously never returned a size of 0, external code that doesn't properly check for size=0 may endlessly loop or overflow a buffer on invalid input. * Change default behaviour of GetCodepointNext to return a size of 1 instead of 0. This matches existing prod behaviour and guarantees size 1..4 is returned. Simplify internal code that uses GetCodepointNext that previously had to account for size=0. * Simplified progressing through a UTF-8 string in ImageTextEx and MeasureTextEx. This change matches existing precedent in DrawTextEx * GetCodepointNext: Add 10xxxxxx checks to multibyte encodings. --------- Co-authored-by: anon <anon>
Diffstat (limited to 'src')
-rw-r--r--src/rtext.c21
-rw-r--r--src/rtextures.c8
2 files changed, 10 insertions, 19 deletions
diff --git a/src/rtext.c b/src/rtext.c
index 2d01360e..dda99487 100644
--- a/src/rtext.c
+++ b/src/rtext.c
@@ -1071,10 +1071,6 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
int codepoint = GetCodepointNext(&text[i], &codepointByteCount);
int index = GetGlyphIndex(font, codepoint);
- // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
- // but we need to draw all the bad bytes using the '?' symbol moving one byte
- if (codepoint == 0x3f) codepointByteCount = 1;
-
if (codepoint == '\n')
{
// NOTE: Fixed line spacing of 1.5 line-height
@@ -1205,7 +1201,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
int letter = 0; // Current character
int index = 0; // Index position in sprite font
- for (int i = 0; i < size; i++)
+ for (int i = 0; i < size;)
{
byteCounter++;
@@ -1213,10 +1209,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
letter = GetCodepointNext(&text[i], &next);
index = GetGlyphIndex(font, letter);
- // NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
- // but we need to draw all the bad bytes using the '?' symbol so to not skip any we set next = 1
- if (letter == 0x3f) next = 1;
- i += next - 1;
+ i += next;
if (letter != '\n')
{
@@ -1734,8 +1727,7 @@ int GetCodepointCount(const char *text)
int next = 0;
int letter = GetCodepointNext(ptr, &next);
- if (letter == 0x3f) ptr += 1;
- else ptr += next;
+ ptr += next;
length++;
}
@@ -1896,28 +1888,31 @@ int GetCodepointNext(const char *text, int *codepointSize)
{
const char *ptr = text;
int codepoint = 0x3f; // Codepoint (defaults to '?')
- *codepointSize = 0;
+ *codepointSize = 1;
// Get current codepoint and bytes processed
if (0xf0 == (0xf8 & ptr[0]))
{
// 4 byte UTF-8 codepoint
+ if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80) || ((ptr[3] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
*codepointSize = 4;
}
else if (0xe0 == (0xf0 & ptr[0]))
{
// 3 byte UTF-8 codepoint */
+ if(((ptr[1] & 0xC0) ^ 0x80) || ((ptr[2] & 0xC0) ^ 0x80)) { return codepoint; } //10xxxxxx checks
codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
*codepointSize = 3;
}
else if (0xc0 == (0xe0 & ptr[0]))
{
// 2 byte UTF-8 codepoint
+ if((ptr[1] & 0xC0) ^ 0x80) { return codepoint; } //10xxxxxx checks
codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
*codepointSize = 2;
}
- else
+ else if (0x00 == (0x80 & ptr[0]))
{
// 1 byte UTF-8 codepoint
codepoint = ptr[0];
diff --git a/src/rtextures.c b/src/rtextures.c
index fb63f2ff..bd652e6b 100644
--- a/src/rtextures.c
+++ b/src/rtextures.c
@@ -1266,17 +1266,13 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
// Create image to store text
imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
- for (int i = 0; i < size; i++)
+ for (int i = 0; i < size;)
{
// Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0;
int codepoint = GetCodepointNext(&text[i], &codepointByteCount); // WARNING: Module required: rtext
int index = GetGlyphIndex(font, codepoint); // WARNING: Module required: rtext
- // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
- // but we need to draw all the bad bytes using the '?' symbol moving one byte
- if (codepoint == 0x3f) codepointByteCount = 1;
-
if (codepoint == '\n')
{
// NOTE: Fixed line spacing of 1.5 line-height
@@ -1296,7 +1292,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
else textOffsetX += font.glyphs[index].advanceX + (int)spacing;
}
- i += (codepointByteCount - 1); // Move text bytes counter to next codepoint
+ i += codepointByteCount; // Move text bytes counter to next codepoint
}
// Scale image depending on text size