Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid crashing when SetText is called with a 2GB large string #990

Merged
merged 2 commits into from
Jul 6, 2024
Merged

Conversation

jengelh
Copy link
Contributor

@jengelh jengelh commented Jul 1, 2024

The expression const int newAllocated = cap * 2; easily causes overflow, as soon as the input is 1.0 GiB. This goes unnoticed because release builds of tinyxml2 do not have active assertions.

The change in commit 9.0.0-20-g8fd6cc6 did not do anything useful; the signed multiplication overflow (and thus undefined behavior) still occurs.

Using int in this class is really archaic, because it limits the class to a gigabyte even on 64-bit platforms.

The multiplication overflow check also needs to include sizeof(T), otherwise you can run into unsigned multiplication overflow (defined, but undesirable) in the memcpy() call.

testcase:

int main()
{
        tinyxml2::XMLDocument doc;
        doc.InsertEndChild(doc.NewDeclaration());
        auto root = doc.NewElement("root");
        size_t sz = 0x80000001;
        auto blank = new char[sz];
        memset(blank, ' ', sz);
        blank[sz-1]='\0';
        root->SetText(blank);
        doc.InsertEndChild(root);
        tinyxml2::XMLPrinter printer(nullptr);
        doc.Print(&printer);
}

The expression ``const int newAllocated = cap * 2;`` easily causes
overflow, as soon as the input is 1.0 GiB. This goes unnoticed because
release builds of tinyxml2 do not have active assertions.

The change in commit 9.0.0-20-g8fd6cc6 did not do anything useful;
the signed multiplication overflow (and thus undefined behavior)
still occurs.

Using ``int`` in this class is really archaic, because it limits the
class to a gigabyte even on 64-bit platforms.

The multiplication overflow check also needs to include sizeof(T),
otherwise you can run into unsigned multiplication overflow (defined,
but undesirable) in the memcpy() call.

testcase:

int main()
{
        tinyxml2::XMLDocument doc;
        doc.InsertEndChild(doc.NewDeclaration());
        auto root = doc.NewElement("root");
        size_t sz = 0x80000001;
        auto blank = new char[sz];
        memset(blank, ' ', sz);
        blank[sz-1]='\0';
        root->SetText(blank);
        doc.InsertEndChild(root);
        tinyxml2::XMLPrinter printer(nullptr);
        doc.Print(&printer);
}
@leethomason
Copy link
Owner

Nice, thanks

@leethomason leethomason merged commit 8a519a5 into leethomason:master Jul 6, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants