diff mbox series

[v2] Driver: Reject output filenames with source file suffixes [PR80182]

Message ID 20240504194324.25058-1-peter0x44@disroot.org
State New
Headers show
Series [v2] Driver: Reject output filenames with source file suffixes [PR80182] | expand

Commit Message

Peter0x44 May 4, 2024, 7:43 p.m. UTC
Currently, commands like:
gcc -o file.c -lm
will delete the user's code.

This patch checks the suffix of the output, and errors if the output ends in
any of the suffixes listed in default_compilers.

Unfortunately, I couldn't come up with a better heuristic to diagnose this case
more specifically, so it is now not possible to directly make executables with
said suffixes. I am unsure if any users are depending on this.

	PR driver/80182
	* gcc.cc (process_command): fatal_error if the output has the suffix of
	  a source file.
	(have_c): Change type to bool.
	(have_O): Change type to bool.
	(have_E): Change type to bool.
	(have_S): New global variable.
	(driver_handle_option): Assign have_S

Signed-off-by: Peter Damianov <peter0x44@disroot.org>
---
v2: use strrchr instead of lrealpath and strchr

 gcc/gcc.cc | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/gcc/gcc.cc b/gcc/gcc.cc
index 830a4700a87..1c4f7032091 100644
--- a/gcc/gcc.cc
+++ b/gcc/gcc.cc
@@ -2127,13 +2127,16 @@  static vec<const_char_p> at_file_argbuf;
 static bool in_at_file = false;
 
 /* Were the options -c, -S or -E passed.  */
-static int have_c = 0;
+static bool have_c = false;
 
 /* Was the option -o passed.  */
-static int have_o = 0;
+static bool have_o = false;
 
 /* Was the option -E passed.  */
-static int have_E = 0;
+static bool have_E = false;
+
+/* Was the option -S passed.  */
+static bool have_S = false;
 
 /* Pointer to output file name passed in with -o. */
 static const char *output_file = 0;
@@ -4593,6 +4596,10 @@  driver_handle_option (struct gcc_options *opts,
       have_E = true;
       break;
 
+    case OPT_S:
+      have_S = true;
+      break;
+
     case OPT_x:
       spec_lang = arg;
       if (!strcmp (spec_lang, "none"))
@@ -5058,6 +5065,21 @@  process_command (unsigned int decoded_options_count,
 		       output_file);
     }
 
+  /* Reject output file names that have the same suffix as a source
+     file. This is to catch mistakes like: gcc -o file.c -lm
+     that could delete the user's code. */
+  if (have_o && output_file != NULL && !have_E && !have_S)
+    {
+      const char* suffix = strrchr(output_file, '.');
+      if (suffix != NULL)
+	for (int i = 0; i < n_default_compilers; ++i)
+	  if (!strcmp(suffix, default_compilers[i].suffix))
+	    fatal_error (input_location,
+			 "output file suffix %qs could be a source file",
+			 suffix);
+    }
+
+
   if (output_file != NULL && output_file[0] == '\0')
     fatal_error (input_location, "output filename may not be empty");