Avoid a crash in source_cache::extract_lines
[deliverable/binutils-gdb.git] / gdb / source-cache.c
index 56851806e441b5b14c18be0c2b472d13888c661a..1ed2601c61459a96e1500abf4302bb07437e49a0 100644 (file)
@@ -1,5 +1,5 @@
 /* Cache of styled source file text
-   Copyright (C) 2018 Free Software Foundation, Inc.
+   Copyright (C) 2018-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "cli/cli-style.h"
 
 #ifdef HAVE_SOURCE_HIGHLIGHT
+/* If Gnulib redirects 'open' and 'close' to its replacements
+   'rpl_open' and 'rpl_close' via cpp macros, including <fstream>
+   below with those macros in effect will cause unresolved externals
+   when GDB is linked.  Happens, e.g., in the MinGW build.  */
+#undef open
+#undef close
 #include <fstream>
 #include <sstream>
 #include <srchilite/sourcehighlight.h>
@@ -78,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;
@@ -96,18 +102,21 @@ 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
+
 /* Return the Source Highlight language name, given a gdb language
    LANG.  Returns NULL if the language is not known.  */
 
@@ -160,6 +169,8 @@ get_language_name (enum language lang)
   return nullptr;
 }
 
+#endif /* HAVE_SOURCE_HIGHLIGHT */
+
 /* See source-cache.h.  */
 
 bool
@@ -170,14 +181,17 @@ source_cache::get_source_lines (struct symtab *s, int first_line,
     return false;
 
 #ifdef HAVE_SOURCE_HIGHLIGHT
-  if (can_emit_style_escape (gdb_stdout))
+  if (source_styling && can_emit_style_escape (gdb_stdout))
     {
       const char *fullname = symtab_to_fullname (s);
 
       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));
@@ -198,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;
            }
        }
     }
This page took 0.025933 seconds and 4 git commands to generate.