From: Tom Tromey Date: Fri, 8 Mar 2019 20:59:27 +0000 (-0700) Subject: Avoid a crash in source_cache::extract_lines X-Git-Tag: gdb-8.3-release~86 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=655aeea04784cdc3e4dfbc0801e7be56f9a1ec11;p=external%2Fbinutils.git 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. 2019-03-14 Tom Tromey * source-cache.h (class source_cache) : 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ac198a9..2315067 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2019-03-14 Tom Tromey + * source-cache.h (class source_cache) : 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. + +2019-03-14 Tom Tromey + * NEWS: Add item for "style sources" commands. * source-cache.c (source_cache::get_source_lines): Check source_styling. 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; } } } diff --git a/gdb/source-cache.h b/gdb/source-cache.h index dd23266..e2e25a1 100644 --- a/gdb/source-cache.h +++ b/gdb/source-cache.h @@ -65,9 +65,10 @@ private: int last_line, std::string *lines_out); /* A helper function for get_plain_source_lines that extracts the desired source lines from TEXT, putting them into LINES_OUT. The - arguments and return value are as for get_source_lines. */ - bool extract_lines (const struct source_text &text, int first_line, - int last_line, std::string *lines_out); + arguments are as for get_source_lines. The return value is the + desired lines. */ + std::string extract_lines (const struct source_text &text, int first_line, + int last_line); /* The contents of the cache. */ std::vector m_source_map;