aboutsummaryrefslogtreecommitdiff
path: root/gdb/source-cache.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2019-03-08 13:59:27 -0700
committerTom Tromey <tromey@adacore.com>2019-03-14 05:47:11 -0600
commit3b336828de914a39741339b5341b88aa003d7225 (patch)
tree78239e64e7f5b42b525f31c45c9deeed2a64489a /gdb/source-cache.c
parentd085f98901ccd6c9764b93d3983f3c7797addc4f (diff)
downloadgdb-3b336828de914a39741339b5341b88aa003d7225.zip
gdb-3b336828de914a39741339b5341b88aa003d7225.tar.gz
gdb-3b336828de914a39741339b5341b88aa003d7225.tar.bz2
Avoid a crash in source_cache::extract_lines
If the first requested line is larger than the number of lines in the source buffer, source_cache::extract_lines could crash, because it would try to pass string::npos" to string::substr. This patch avoids the crash by checking for this case. This version of the patch changes get_source_lines to return std::string. gdb/ChangeLog 2019-03-14 Tom Tromey <tromey@adacore.com> * source-cache.h (class source_cache) <get_source_lines>: Return std::string. * source-cache.c (source_cache::extract_lines): Handle case where first_pos==npos. Return std::string. (source_cache::get_source_lines): Update.
Diffstat (limited to 'gdb/source-cache.c')
-rw-r--r--gdb/source-cache.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/gdb/source-cache.c b/gdb/source-cache.c
index 3b15b3f..1ed2601 100644
--- a/gdb/source-cache.c
+++ b/gdb/source-cache.c
@@ -84,9 +84,9 @@ source_cache::get_plain_source_lines (struct symtab *s, int first_line,
/* See source-cache.h. */
-bool
+std::string
source_cache::extract_lines (const struct source_text &text, int first_line,
- int last_line, std::string *lines)
+ int last_line)
{
int lineno = 1;
std::string::size_type pos = 0;
@@ -102,16 +102,17 @@ source_cache::extract_lines (const struct source_text &text, int first_line,
pos = new_pos;
if (lineno == last_line || pos == std::string::npos)
{
+ if (first_pos == std::string::npos)
+ return {};
if (pos == std::string::npos)
pos = text.contents.size ();
- *lines = text.contents.substr (first_pos, pos - first_pos);
- return true;
+ return text.contents.substr (first_pos, pos - first_pos);
}
++lineno;
++pos;
}
- return false;
+ return {};
}
#ifdef HAVE_SOURCE_HIGHLIGHT
@@ -187,7 +188,10 @@ source_cache::get_source_lines (struct symtab *s, int first_line,
for (const auto &item : m_source_map)
{
if (item.fullname == fullname)
- return extract_lines (item, first_line, last_line, lines);
+ {
+ *lines = extract_lines (item, first_line, last_line);
+ return true;
+ }
}
const char *lang_name = get_language_name (SYMTAB_LANGUAGE (s));
@@ -208,8 +212,9 @@ source_cache::get_source_lines (struct symtab *s, int first_line,
if (m_source_map.size () > MAX_ENTRIES)
m_source_map.erase (m_source_map.begin ());
- return extract_lines (m_source_map.back (), first_line,
- last_line, lines);
+ *lines = extract_lines (m_source_map.back (), first_line,
+ last_line);
+ return true;
}
}
}