Commit 04b5aace authored by Ole Christian Eidheim's avatar Ole Christian Eidheim
Browse files

Fixes #440: segmentation fault when running regex on very long lines. Also...

Fixes #440: segmentation fault when running regex on very long lines. Also minor cleanup of Terminall::find_link, and added extra Termina::find_link tests.
parent 2074b03b
Pipeline #192157283 passed with stages
in 16 minutes and 52 seconds
......@@ -373,7 +373,10 @@ bool Terminal::on_motion_notify_event(GdkEventMotion *event) {
return Gtk::TextView::on_motion_notify_event(event);
}
boost::optional<Terminal::Link> Terminal::find_link(const std::string &line, size_t pos, size_t length) {
boost::optional<Terminal::Link> Terminal::find_link(const std::string &line) {
if(line.size() >= 1000) // Due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164
return {};
const static std::regex link_regex("^([A-Z]:)?([^:]+):([0-9]+):([0-9]+): .*$|" // C/C++ compile warning/error/rename usages
"^In file included from ([A-Z]:)?([^:]+):([0-9]+)[:,]$|" // C/C++ extra compile warning/error info
"^ from ([A-Z]:)?([^:]+):([0-9]+)[:,]$|" // C/C++ extra compile warning/error info (gcc)
......@@ -385,12 +388,10 @@ boost::optional<Terminal::Link> Terminal::find_link(const std::string &line, siz
"^ +at .*?\\(([A-Z]:)?([^:]+):([0-9]+):([0-9]+)\\).*$|" // Node.js stack trace
"^ +at ([A-Z]:)?([^:]+):([0-9]+):([0-9]+).*$|" // Node.js stack trace
"^ File \"([A-Z]:)?([^\"]+)\", line ([0-9]+), in .*$|" // Python
"^.*?([A-Z]:)?([a-zA-Z0-9._\\\\/][a-zA-Z0-9._\\-\\\\/]*):([0-9]+):([0-9]+).*$", // Posix file:line:column
"^.*?([A-Z]:)?([a-zA-Z0-9._\\\\/][a-zA-Z0-9._\\-\\\\/]*):([0-9]+):([0-9]+).*$", // Posix path:line:column
std::regex::optimize);
std::smatch sm;
if(std::regex_match(line.cbegin() + pos,
line.cbegin() + (length == std::string::npos ? line.size() : std::min(pos + length, line.size())),
sm, link_regex)) {
if(std::regex_match(line, sm, link_regex)) {
for(size_t sub = 1; sub < link_regex.mark_count();) {
size_t subs = (sub == 1 ||
sub == 1 + 4 + 3 + 3 ||
......
......@@ -57,7 +57,7 @@ private:
std::string path;
int line, line_index;
};
boost::optional<Link> find_link(const std::string &line, size_t pos = 0, size_t length = std::string::npos);
static boost::optional<Link> find_link(const std::string &line);
Mutex processes_mutex;
std::vector<std::shared_ptr<TinyProcessLib::Process>> processes GUARDED_BY(processes_mutex);
......
......@@ -26,7 +26,7 @@ int main() {
// Testing links
{
auto link = terminal.find_link("~/test/test.cc:7:41: error: expected ';' after expression.");
auto link = Terminal::find_link("~/test/test.cc:7:41: error: expected ';' after expression.");
assert(link);
assert(link->start_pos == 0);
assert(link->end_pos == 19);
......@@ -35,7 +35,34 @@ int main() {
assert(link->line_index == 41);
}
{
auto link = terminal.find_link("Assertion failed: (false), function main, file ~/test/test.cc, line 15.");
auto link = Terminal::find_link("In file included from ./test/test.cc:2,");
assert(link);
assert(link->start_pos == 22);
assert(link->end_pos == 38);
assert(link->path == "./test/test.cc");
assert(link->line == 2);
assert(link->line_index == 1);
}
{
auto link = Terminal::find_link(" from ./test/test.cc:2:");
assert(link);
assert(link->start_pos == 22);
assert(link->end_pos == 38);
assert(link->path == "./test/test.cc");
assert(link->line == 2);
assert(link->line_index == 1);
}
{
auto link = Terminal::find_link(" --> src/main.rs:16:4");
assert(link);
assert(link->start_pos == 6);
assert(link->end_pos == 22);
assert(link->path == "src/main.rs");
assert(link->line == 16);
assert(link->line_index == 4);
}
{
auto link = Terminal::find_link("Assertion failed: (false), function main, file ~/test/test.cc, line 15.");
assert(link);
assert(link->start_pos == 47);
assert(link->end_pos == 70);
......@@ -44,7 +71,7 @@ int main() {
assert(link->line_index == 1);
}
{
auto link = terminal.find_link("test: ~/examples/main.cpp:17: int main(int, char**): Assertion `false' failed.");
auto link = Terminal::find_link("test: ~/examples/main.cpp:17: int main(int, char**): Assertion `false' failed.");
assert(link);
assert(link->start_pos == 6);
assert(link->end_pos == 28);
......@@ -53,7 +80,7 @@ int main() {
assert(link->line_index == 1);
}
{
auto link = terminal.find_link("ERROR:~/test/test.cc:36:int main(): assertion failed: (false)");
auto link = Terminal::find_link("ERROR:~/test/test.cc:36:int main(): assertion failed: (false)");
assert(link);
assert(link->start_pos == 6);
assert(link->end_pos == 23);
......@@ -62,16 +89,34 @@ int main() {
assert(link->line_index == 1);
}
{
auto link = terminal.find_link(" --> src/main.rs:16:4");
auto link = Terminal::find_link("/test/test.js:10");
assert(link);
assert(link->start_pos == 6);
assert(link->end_pos == 22);
assert(link->path == "src/main.rs");
assert(link->start_pos == 0);
assert(link->end_pos == 16);
assert(link->path == "/test/test.js");
assert(link->line == 10);
assert(link->line_index == 1);
}
{
auto link = Terminal::find_link(" at something (src/main.js:16:4)");
assert(link);
assert(link->start_pos == 16);
assert(link->end_pos == 32);
assert(link->path == "src/main.js");
assert(link->line == 16);
assert(link->line_index == 4);
}
{
auto link = Terminal::find_link(" at src/main.js:16:4");
assert(link);
assert(link->start_pos == 5);
assert(link->end_pos == 21);
assert(link->path == "src/main.js");
assert(link->line == 16);
assert(link->line_index == 4);
}
{
auto link = terminal.find_link(R"( File "/home/test/test.py", line 4, in <module>)");
auto link = Terminal::find_link(R"( File "/home/test/test.py", line 4, in <module>)");
assert(link);
assert(link->start_pos == 8);
assert(link->end_pos == 35);
......@@ -79,6 +124,22 @@ int main() {
assert(link->line == 4);
assert(link->line_index == 1);
}
{
auto link = Terminal::find_link("Testing ./posix_path/test.txt:10:20 here");
assert(link);
assert(link->start_pos == 8);
assert(link->end_pos == 35);
assert(link->path == "./posix_path/test.txt");
assert(link->line == 10);
assert(link->line_index == 20);
}
{
// Avoid https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164
std::string long_line;
for(size_t i = 0; i < 50000; ++i)
long_line += "x";
assert(!Terminal::find_link("/home/test/test.txt:1:1: " + long_line));
}
// Testing print
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment