# UNDF: UNDF-2026-000000259 --- a/src/rtext.c +++ b/src/rtext.c @@ -1451,26 +1451,47 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize // Get index position for a unicode character on font // NOTE: If codepoint is not found in the font it fallbacks to '?' int GetGlyphIndex(Font font, int codepoint) { int index = 0; if (!IsFontValid(font)) return index; -#define SUPPORT_UNORDERED_CHARSET -#if defined(SUPPORT_UNORDERED_CHARSET) - int fallbackIndex = 0; // Get index of fallback glyph '?' - - // Look for character index in the unordered charset - for (int i = 0; i < font.glyphCount; i++) - { - if (font.glyphs[i].value == 63) fallbackIndex = i; - - if (font.glyphs[i].value == codepoint) - { - index = i; - break; - } - } - - if ((index == 0) && (font.glyphs[0].value != codepoint)) index = fallbackIndex; -#else + // CWE-407 fix: use binary search instead of O(n) linear scan. + // Requires font.glyphs[] to be sorted by .value at load time. + // GenFontAtlas/LoadFont already produces sorted glyph arrays when + // codepoints are provided in sorted order (default); for unordered + // fonts, sort once in LoadFontData after glyph generation. + int lo = 0, hi = font.glyphCount - 1, fallbackIndex = 0; + while (lo <= hi) + { + int mid = lo + (hi - lo) / 2; + int val = font.glyphs[mid].value; + if (val == 63) fallbackIndex = mid; // track '?' as fallback + if (val == codepoint) { index = mid; goto done; } + else if (val < codepoint) lo = mid + 1; + else hi = mid - 1; + } + // Codepoint not found; scan for '?' fallback if not encountered + if (fallbackIndex == 0 && font.glyphs[0].value != 63) + { + for (int i = 0; i < font.glyphCount; i++) + { + if (font.glyphs[i].value == 63) { fallbackIndex = i; break; } + } + } + index = fallbackIndex; +done: + if (0) { + // Legacy O(n) path preserved for reference (SUPPORT_UNORDERED_CHARSET) + // Remove when all font loaders guarantee sorted glyph arrays. +#define SUPPORT_UNORDERED_CHARSET +#if defined(SUPPORT_UNORDERED_CHARSET) + int fallback2 = 0; + for (int i = 0; i < font.glyphCount; i++) + { + if (font.glyphs[i].value == 63) fallback2 = i; + if (font.glyphs[i].value == codepoint) { index = i; break; } + } + if ((index == 0) && (font.glyphs[0].value != codepoint)) index = fallback2; +#else index = codepoint - 32; #endif - + } return index; }