Skip to content

LABEL: out-of-bounds read for labels shorter than 19 characters #95

Description

@Boscop

Problem

LABELDisplay::drawLayer() always indexes the first 20 bytes of the label string:

std::string fD = module ? module->fileDesc : "Right clic to write";
std::string to_display = "";
for (int i = 0; i < 20; i++)
    to_display = to_display + fD[i];

Source:

cf/src/LABEL.cpp

Lines 73 to 84 in 9509b74

shared_ptr<Font> font = APP->window->loadFont(asset::plugin(pluginInstance, "res/LEDCalculator.ttf"));
std::string fD= module ? module->fileDesc : "Right clic to write";
std::string to_display = "";
for (int i=0; i<20; i++) to_display = to_display + fD[i];
nvgFontSize(args.vg, 24);
nvgFontFaceId(args.vg, font->handle);
nvgTextLetterSpacing(args.vg, 0);
nvgFillColor(args.vg, nvgRGBA(0x4c, 0xc7, 0xf3, 0xff));
nvgRotate(args.vg, -M_PI / 2.0f);
nvgTextBox(args.vg, 5, 5,350, to_display.c_str(), NULL);
}
Widget::drawLayer(args, layer);

For std::string::operator[], index size() yields the terminating null character, but indexes greater than size() are out of bounds. Therefore, any entered label shorter than 19 characters causes out-of-bounds reads on every display draw.

For example, with "BASS", indexes 0–3 contain characters, index 4 is the terminator, and indexes 5–19 are out of bounds.

This is undefined behavior. It may appear harmless depending on memory layout, but sanitizers can detect it, and it could potentially cause incorrect output or a crash.

Expected behavior

Display at most 20 bytes without reading beyond the string.

Suggested fix

std::string to_display = fD.substr(0, 20);

This preserves the current 20-byte limit while avoiding out-of-bounds access.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions