diff --git a/src/main/main.cpp b/src/main/main.cpp index 3c2f321..a7981a9 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -48,7 +48,7 @@ #include "../../lib/rt64/src/contrib/stb/stb_image.h" -const std::string version_string = "1.2.0-rc3"; +const std::string version_string = "1.2.0-rc2"; template void exit_error(const char* str, Ts ...args) { diff --git a/src/ui/elements/ui_element.cpp b/src/ui/elements/ui_element.cpp index c2bd990..b1525f2 100644 --- a/src/ui/elements/ui_element.cpp +++ b/src/ui/elements/ui_element.cpp @@ -355,16 +355,30 @@ bool Element::is_enabled() const { return enabled && !disabled_from_parent; } +// Adapted from RmlUi's `EncodeRml`. +std::string escape_rml(std::string_view string) +{ + std::string result; + result.reserve(string.size()); + for (char c : string) + { + switch (c) + { + case '<': result += "<"; break; + case '>': result += ">"; break; + case '&': result += "&"; break; + case '"': result += """; break; + case '\n': result += "
"; break; + default: result += c; break; + } + } + return result; +} + void Element::set_text(std::string_view text) { if (can_set_text) { - if (text_element == nullptr) { - Rml::ElementPtr text_element_owning = get_current_context().get_document()->CreateTextNode(std::string{text}); - text_element = rmlui_static_cast(text_element_owning.get()); - base->AppendChild(std::move(text_element_owning)); - } - else { - text_element->SetText(std::string{text}); - } + // Escape the string into Rml to prevent element injection. + base->SetInnerRML(escape_rml(text)); } else { assert(false && "Attempted to set text of an element that cannot have its text set."); diff --git a/src/ui/elements/ui_element.h b/src/ui/elements/ui_element.h index 551a7ec..6e2ce16 100644 --- a/src/ui/elements/ui_element.h +++ b/src/ui/elements/ui_element.h @@ -25,7 +25,6 @@ class Element : public Style, public Rml::EventListener { friend class ContextId; // To allow ContextId to call the handle_event method directly. private: Rml::Element *base = nullptr; - Rml::ElementText *text_element = nullptr; Rml::ElementPtr base_owning = {}; uint32_t events_enabled = 0; std::vector