MCPP fails to resolve symbolic links properly and segfaults as a result.
Steps to Reproduce:
mkdir -p /tmp/a/g /tmp/a/h /tmp/e
cd /tmp/a/g
ln -sf ../h /tmp/a/g/c
ln -sf /tmp/a/g /tmp/e/f
ln -sf /tmp/e/f /tmp/a/b
echo "- this is version VERSION of this file -" >/tmp/a/b/c/d.cpp
mcpp -DVERSION=1.2.3 /tmp/a/b/c/d.cpp
Can't open input file "/tmp/e/h/d.cpp".
./repro: line 9: 22620 Segmentation fault (core dumped) mcpp
-DVERSION=1.2.3 /tmp/a/b/c/d.cpp
Below is a possible patch which uses realpath() instead of readlink() and removes the deref_syml() function.
MCPP fails to resolve symbolic links properly and segfaults as a result.
Steps to Reproduce:
mkdir -p /tmp/a/g /tmp/a/h /tmp/e
cd /tmp/a/g
ln -sf ../h /tmp/a/g/c
ln -sf /tmp/a/g /tmp/e/f
ln -sf /tmp/e/f /tmp/a/b
echo "- this is version VERSION of this file -" >/tmp/a/b/c/d.cpp
mcpp -DVERSION=1.2.3 /tmp/a/b/c/d.cpp
Can't open input file "/tmp/e/h/d.cpp".
./repro: line 9: 22620 Segmentation fault (core dumped) mcpp
-DVERSION=1.2.3 /tmp/a/b/c/d.cpp
Below is a possible patch which uses realpath() instead of readlink() and removes the deref_syml() function.
-- a/src/main.c 2011-11-26 04:32:05.377872854 +1000
+++ a/src/main.c 2011-12-01 05:23:00.158478861 +1000
@@ -437,11 +437,11 @@
clear_symtable();
#endif
- if (fp_in != stdin)
+ if (fp_in && (fp_in != stdin))
fclose( fp_in);
- if (fp_out != stdout)
+ if (fp_out && (fp_out != stdout))
fclose( fp_out);
- if (fp_err != stderr)
+ if (fp_err && (fp_err != stderr))
fclose( fp_err);
if (mcpp_debug & MEMORY)
-- a/src/system.c 2011-12-01 06:39:27.118437985 +1000
+++ a/src/system.c 2011-12-01 06:46:55.763451557 +1000
@@ -145,10 +145,6 @@
/* Normalize include directory path */
static char * norm_path( const char * dir, const char * fname, int inf
, int hmap); /* Normalize pathname to compare */
-#if SYS_FAMILY == SYS_UNIX
-static void deref_syml( char * slbuf1, char * slbuf2, char * chk_start);
- /* Dereference symbolic linked directory and file */
-#endif
#if COMPILER == GNUC
static void init_gcc_macro( void);
/* Predefine GCC-specific macros */
@@ -2491,40 +2487,21 @@
return NULL;
}
#endif
- if (! fname) {
- slbuf1 = PATH_DELIM; /* Append PATH_DELIM */
- slbuf1 = EOS;
- }
#if SYS_FAMILY == SYS_UNIX
/* Dereference symbolic linked directory or file, if any */
- slbuf1 = EOS; /* Truncate PATH_DELIM and 'fname' part, if any */
slbuf2 = EOS;
- if (*dir && ! fname) { /* Registering include directory */
- /* Symbolic link check of directories are required */
- deref_syml( slbuf1, slbuf2, slbuf1);
- } else if (fname) { /* Regular file */
- len = strlen( slbuf1);
- strcat( slbuf1, fname);
- deref_syml( slbuf1, slbuf2, slbuf1 + len);
- /* Symbolic link check of directory */
- if ((len = readlink( slbuf1, slbuf2, PATHMAX)) > 0) {
- /* Dereference symbolic linked file (not directory) */
- *(slbuf2 + len) = EOS;
- cp1 = slbuf1;
- if (slbuf2 != PATH_DELIM) { /* Relative path */
- cp2 = strrchr( slbuf1, PATH_DELIM);
- if (cp2) /* Append to the source directory */
- cp1 = cp2 + 1;
- }
- strcpy( cp1, slbuf2);
+ if((realpath(slbuf1, slbuf2) != NULL) && strcmp(slbuf1,slbuf2)) {
+ if (inf) {
+ mcpp_fprintf( DBG, "Dereferenced \"%s\" to \"%s\"\n"
+ , slbuf1, slbuf2);
}
- }
- if (inf) {
- if (slbuf2)
- mcpp_fprintf( DBG, "Dereferenced \"%s%s\" to \"%s\"\n"
- , dir, fname ? fname : null, slbuf1);
+ strcpy(slbuf1,slbuf2);
}
#endif
+ if (! fname) {
+ slbuf1 = PATH_DELIM; /* Append PATH_DELIM */
+ slbuf1 = EOS;
+ }
len = strlen( slbuf1);
start = norm_name = xmalloc( len + 1); /* Need a new buffer */
strcpy( norm_name, slbuf1);
@@ -2668,43 +2645,6 @@
return norm_name;
}
-#if SYS_FAMILY == SYS_UNIX
-static void deref_syml(
- char * slbuf1, /* Original path-list */
- char * slbuf2, /* Working buffer */
- char * chk_start /* Pointer into slbuf1 */
-)
-/* Dereference symbolic linked directory */
-{
- char * cp2;
- int len; /* Should be int, not size_t */
-
- while ((chk_start = strchr( chk_start, PATH_DELIM)) != NULL) {
- *chk_start = EOS;
- if ((len = readlink( slbuf1, slbuf2, PATHMAX)) > 0) {
- /* Dereference symbolic linked directory */
- cp2 = strrchr( slbuf1, PATH_DELIM); /* Previous delimiter */
- *chk_start = PATH_DELIM;
- strcpy( slbuf2 + len, chk_start);
- if (slbuf2 == PATH_DELIM) { /* Absolute path */
- strcpy( slbuf1, slbuf2);
- chk_start = slbuf1 + len + 1;
- } else {
- if (cp2)
- chk_start = cp2 + 1;
- else
- chk_start = slbuf1;
- strcpy( chk_start, slbuf2); /* Rewrite the path */
- chk_start += len;
- }
- } else {
- *chk_start++ = PATH_DELIM;
- }
- }
-}
-#endif
-
#if COMPILER == GNUC
static void init_gcc_macro( void)