Fix segfaults when using filename paths greater than 1024 characters in length - use String * and heap instead of fixed size static char array buffers.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@13904 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2012-11-18 00:45:18 +00:00
commit d918bddfc0
12 changed files with 100 additions and 78 deletions

View file

@ -5,7 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 2.0.9 (in progress) Version 2.0.9 (in progress)
=========================== ===========================
2012-11-14: [ccache-swig] Apply patch #3586392 from Frederik Deweerdt to fix some error cases - incorrectly using 2012-11-17: wsfulton
Fix segfaults when using filename paths greater than 1024 characters in length.
2012-11-14: wsfulton
[ccache-swig] Apply patch #3586392 from Frederik Deweerdt to fix some error cases - incorrectly using
memory after it has been deleted. memory after it has been deleted.
2012-11-09: vzeitlin 2012-11-09: vzeitlin

View file

@ -405,8 +405,11 @@ public:
Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, "/* ---------------------------------------------------\n");
Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * C++ director class methods\n");
Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n");
if (outfile_h) if (outfile_h) {
Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); String *filename = Swig_file_filename(outfile_h);
Printf(f_directors, "#include \"%s\"\n\n", filename);
Delete(filename);
}
} }
Printf(f_runtime, "\n"); Printf(f_runtime, "\n");

View file

@ -490,8 +490,11 @@ public:
Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, "/* ---------------------------------------------------\n");
Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * C++ director class methods\n");
Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n");
if (outfile_h) if (outfile_h) {
Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); String *filename = Swig_file_filename(outfile_h);
Printf(f_directors, "#include \"%s\"\n\n", filename);
Delete(filename);
}
} }
Printf(f_runtime, "\n"); Printf(f_runtime, "\n");

View file

@ -371,7 +371,9 @@ private:
Printf(f_c_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module); Printf(f_c_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
Printf(f_c_directors, "\n// C++ director class methods.\n"); Printf(f_c_directors, "\n// C++ director class methods.\n");
Printf(f_c_directors, "#include \"%s\"\n\n", Swig_file_filename(c_filename_h)); String *filename = Swig_file_filename(c_filename_h);
Printf(f_c_directors, "#include \"%s\"\n\n", filename);
Delete(filename);
} }
Swig_banner(f_go_begin); Swig_banner(f_go_begin);

View file

@ -417,8 +417,11 @@ public:
Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, "/* ---------------------------------------------------\n");
Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * C++ director class methods\n");
Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n");
if (outfile_h) if (outfile_h) {
Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); String *filename = Swig_file_filename(outfile_h);
Printf(f_directors, "#include \"%s\"\n\n", filename);
Delete(filename);
}
} }
Printf(f_runtime, "\n"); Printf(f_runtime, "\n");

View file

@ -199,22 +199,24 @@ static List *libfiles = 0;
static List *all_output_files = 0; static List *all_output_files = 0;
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* check_suffix() * check_extension()
* *
* Checks the suffix of a file to see if we should emit extern declarations. * Checks the extension of a file to see if we should emit extern declarations.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
static int check_suffix(String *filename) { static bool check_extension(String *filename) {
bool wanted = false;
const char *name = Char(filename); const char *name = Char(filename);
const char *c;
if (!name) if (!name)
return 0; return 0;
c = Swig_file_suffix(name); String *extension = Swig_file_extension(name);
const char *c = Char(extension);
if ((strcmp(c, ".c") == 0) || if ((strcmp(c, ".c") == 0) ||
(strcmp(c, ".C") == 0) || (strcmp(c, ".cc") == 0) || (strcmp(c, ".cxx") == 0) || (strcmp(c, ".c++") == 0) || (strcmp(c, ".cpp") == 0)) { (strcmp(c, ".C") == 0) || (strcmp(c, ".cc") == 0) || (strcmp(c, ".cxx") == 0) || (strcmp(c, ".c++") == 0) || (strcmp(c, ".cpp") == 0)) {
return 1; wanted = true;
} }
return 0; Delete(extension);
return wanted;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -283,15 +285,16 @@ static unsigned int decode_numbers_list(String *numlist) {
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Sets the output directory for language specific (proxy) files if not set and * Sets the output directory for language specific (proxy) files from the
* corrects the directory name and adds trailing file separator if necessary. * C wrapper file if not set and corrects the directory name and adds a trailing
* file separator if necessary.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
static void configure_outdir(const String *c_wrapper_file_dir) { static void configure_outdir(const String *c_wrapper_outfile) {
// Use the C wrapper file's directory if the output directory has not been set by user // Use the C wrapper file's directory if the output directory has not been set by user
if (!outdir || Len(outdir) == 0) if (!outdir || Len(outdir) == 0)
outdir = NewString(c_wrapper_file_dir); outdir = Swig_file_dirname(c_wrapper_outfile);
Swig_filename_correct(outdir); Swig_filename_correct(outdir);
@ -1068,7 +1071,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
String *outfile; String *outfile;
File *f_dependencies_file = 0; File *f_dependencies_file = 0;
char *basename = Swig_file_basename(outcurrentdir ? Swig_file_filename(input_file): Char(input_file)); String *inputfile_filename = outcurrentdir ? Swig_file_filename(input_file): Copy(input_file);
String *basename = Swig_file_basename(inputfile_filename);
if (!outfile_name) { if (!outfile_name) {
if (CPlusPlus || lang->cplus_runtime_mode()) { if (CPlusPlus || lang->cplus_runtime_mode()) {
outfile = NewStringf("%s_wrap.%s", basename, cpp_extension); outfile = NewStringf("%s_wrap.%s", basename, cpp_extension);
@ -1113,6 +1117,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Delete(f_dependencies_file); Delete(f_dependencies_file);
if (depend_only) if (depend_only)
SWIG_exit(EXIT_SUCCESS); SWIG_exit(EXIT_SUCCESS);
Delete(inputfile_filename);
Delete(basename);
} else { } else {
Printf(stderr, "Cannot generate dependencies with -nopreprocess\n"); Printf(stderr, "Cannot generate dependencies with -nopreprocess\n");
// Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse // Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse
@ -1220,7 +1226,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file
Setattr(top, "inputfile", input_file); Setattr(top, "inputfile", input_file);
char *basename = Swig_file_basename(outcurrentdir ? Swig_file_filename(infile): Char(infile)); String *infile_filename = outcurrentdir ? Swig_file_filename(infile): Copy(infile);
String *basename = Swig_file_basename(infile_filename);
if (!outfile_name) { if (!outfile_name) {
if (CPlusPlus || lang->cplus_runtime_mode()) { if (CPlusPlus || lang->cplus_runtime_mode()) {
Setattr(top, "outfile", NewStringf("%s_wrap.%s", basename, cpp_extension)); Setattr(top, "outfile", NewStringf("%s_wrap.%s", basename, cpp_extension));
@ -1235,19 +1242,21 @@ int SWIG_main(int argc, char *argv[], Language *l) {
} else { } else {
Setattr(top, "outfile_h", outfile_name_h); Setattr(top, "outfile_h", outfile_name_h);
} }
configure_outdir(Swig_file_dirname(Getattr(top, "outfile"))); configure_outdir(Getattr(top, "outfile"));
if (Swig_contract_mode_get()) { if (Swig_contract_mode_get()) {
Swig_contracts(top); Swig_contracts(top);
} }
// Check the suffix for a c/c++ file. If so, we're going to declare everything we see as "extern" // Check the extension for a c/c++ file. If so, we're going to declare everything we see as "extern"
ForceExtern = check_suffix(input_file); ForceExtern = check_extension(input_file);
lang->top(top); lang->top(top);
if (browse) { if (browse) {
Swig_browser(top, 0); Swig_browser(top, 0);
} }
Delete(infile_filename);
Delete(basename);
} }
} }
if (dump_lang_symbols) { if (dump_lang_symbols) {

View file

@ -354,7 +354,9 @@ public:
Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", cap_module); Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", cap_module);
Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", cap_module); Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", cap_module);
Printf(f_directors, "\n#include \"%s\"\n\n", Swig_file_filename(outfile_h)); String *filename = Swig_file_filename(outfile_h);
Printf(f_directors, "\n#include \"%s\"\n\n", filename);
Delete(filename);
} }
/* PHP module file */ /* PHP module file */

View file

@ -763,8 +763,11 @@ public:
Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, "/* ---------------------------------------------------\n");
Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * C++ director class methods\n");
Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n");
if (outfile_h) if (outfile_h) {
Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); String *filename = Swig_file_filename(outfile_h);
Printf(f_directors, "#include \"%s\"\n\n", filename);
Delete(filename);
}
} }
/* If shadow classing is enabled, we're going to change the module name to "_module" */ /* If shadow classing is enabled, we're going to change the module name to "_module" */

View file

@ -1142,8 +1142,11 @@ public:
Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, "/* ---------------------------------------------------\n");
Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * C++ director class methods\n");
Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n");
if (outfile_h) if (outfile_h) {
Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); String *filename = Swig_file_filename(outfile_h);
Printf(f_directors, "#include \"%s\"\n\n", filename);
Delete(filename);
}
Delete(module_macro); Delete(module_macro);
} }

View file

@ -1706,7 +1706,7 @@ String *Preprocessor_parse(String *s) {
} else if (Equal(id, kpp_include)) { } else if (Equal(id, kpp_include)) {
if (((include_all) || (import_all)) && (allow)) { if (((include_all) || (import_all)) && (allow)) {
String *s1, *s2, *fn; String *s1, *s2, *fn;
char *dirname; String *dirname;
int sysfile = 0; int sysfile = 0;
if (include_all && import_all) { if (include_all && import_all) {
Swig_warning(WARN_PP_INCLUDEALL_IMPORTALL, Getfile(s), Getline(id), "Both includeall and importall are defined: using includeall.\n"); Swig_warning(WARN_PP_INCLUDEALL_IMPORTALL, Getfile(s), Getline(id), "Both includeall and importall are defined: using includeall.\n");
@ -1725,10 +1725,13 @@ String *Preprocessor_parse(String *s) {
/* See if the filename has a directory component */ /* See if the filename has a directory component */
dirname = Swig_file_dirname(Swig_last_file()); dirname = Swig_file_dirname(Swig_last_file());
if (sysfile || !strlen(dirname)) if (sysfile || !Len(dirname)) {
Delete(dirname);
dirname = 0; dirname = 0;
}
if (dirname) { if (dirname) {
dirname[strlen(dirname) - 1] = 0; /* Kill trailing directory delimiter */ int len = Len(dirname);
Delslice(dirname, len - 1, len); /* Kill trailing directory delimiter */
Swig_push_directory(dirname); Swig_push_directory(dirname);
} }
s2 = Preprocessor_parse(s1); s2 = Preprocessor_parse(s1);
@ -1741,6 +1744,7 @@ String *Preprocessor_parse(String *s) {
pop_imported(); pop_imported();
} }
Delete(s2); Delete(s2);
Delete(dirname);
Delete(s1); Delete(s1);
} }
Delete(fn); Delete(fn);
@ -1858,7 +1862,7 @@ String *Preprocessor_parse(String *s) {
fn = get_filename(s, &sysfile); fn = get_filename(s, &sysfile);
s1 = cpp_include(fn, sysfile); s1 = cpp_include(fn, sysfile);
if (s1) { if (s1) {
char *dirname; String *dirname;
copy_location(s, chunk); copy_location(s, chunk);
add_chunk(ns, chunk, allow); add_chunk(ns, chunk, allow);
Printf(ns, "%sfile%s%s%s\"%s\" %%beginfile\n", decl, options_whitespace, opt, filename_whitespace, Swig_filename_escape(Swig_last_file())); Printf(ns, "%sfile%s%s%s\"%s\" %%beginfile\n", decl, options_whitespace, opt, filename_whitespace, Swig_filename_escape(Swig_last_file()));
@ -1866,10 +1870,13 @@ String *Preprocessor_parse(String *s) {
push_imported(); push_imported();
} }
dirname = Swig_file_dirname(Swig_last_file()); dirname = Swig_file_dirname(Swig_last_file());
if (sysfile || !strlen(dirname)) if (sysfile || !strlen(dirname)) {
Delete(dirname);
dirname = 0; dirname = 0;
}
if (dirname) { if (dirname) {
dirname[strlen(dirname) - 1] = 0; /* Kill trailing directory delimiter */ int len = Len(dirname);
Delslice(dirname, len - 1, len); /* Kill trailing directory delimiter */
Swig_push_directory(dirname); Swig_push_directory(dirname);
} }
s2 = Preprocessor_parse(s1); s2 = Preprocessor_parse(s1);
@ -1882,6 +1889,7 @@ String *Preprocessor_parse(String *s) {
addline(ns, s2, allow); addline(ns, s2, allow);
Append(ns, "%endoffile"); Append(ns, "%endoffile");
Delete(s2); Delete(s2);
Delete(dirname);
Delete(s1); Delete(s1);
} }
Delete(fn); Delete(fn);

View file

@ -317,58 +317,49 @@ File *Swig_filebyname(const_String_or_char_ptr filename) {
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_file_suffix() * Swig_file_extension()
* *
* Returns the suffix of a file * Returns the extension of a file
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
char *Swig_file_suffix(const_String_or_char_ptr filename) { String *Swig_file_extension(const_String_or_char_ptr filename) {
char *d; const char *d;
char *c = Char(filename); const char *c = Char(filename);
int len = Len(filename); int len = Len(filename);
if (strlen(c)) { if (strlen(c)) {
d = c + len - 1; d = c + len - 1;
while (d != c) { while (d != c) {
if (*d == '.') if (*d == '.')
return d; return NewString(d);
d--; d--;
} }
return c + len; return NewString(c + len);
} }
return c; return NewString(c);
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_file_basename() * Swig_file_basename()
* *
* Returns the filename with no suffix attached. * Returns the filename with the extension removed.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
char *Swig_file_basename(const_String_or_char_ptr filename) { String *Swig_file_basename(const_String_or_char_ptr filename) {
static char tmp[1024]; String *extension = Swig_file_extension(filename);
char *c; String *basename = DohNewStringWithSize(filename, Len(filename) - Len(extension));
strcpy(tmp, Char(filename)); Delete(extension);
c = Swig_file_suffix(tmp); return basename;
*c = 0;
return tmp;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_file_filename() * Swig_file_filename()
* *
* Return the file with any leading path stripped off * Return the file name with any leading path stripped off
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
char *Swig_file_filename(const_String_or_char_ptr filename) { String *Swig_file_filename(const_String_or_char_ptr filename) {
static char tmp[1024];
const char *delim = SWIG_FILE_DELIMITER; const char *delim = SWIG_FILE_DELIMITER;
char *c; const char *c = strrchr(Char(filename), *delim);
return c ? NewString(c + 1) : NewString(filename);
strcpy(tmp, Char(filename));
c = strrchr(tmp, *delim);
if (c)
return c + 1;
else
return tmp;
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
@ -376,19 +367,10 @@ char *Swig_file_filename(const_String_or_char_ptr filename) {
* *
* Return the name of the directory associated with a file * Return the name of the directory associated with a file
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
char *Swig_file_dirname(const_String_or_char_ptr filename) { String *Swig_file_dirname(const_String_or_char_ptr filename) {
static char tmp[1024];
const char *delim = SWIG_FILE_DELIMITER; const char *delim = SWIG_FILE_DELIMITER;
char *c; const char *c = strrchr(Char(filename), *delim);
strcpy(tmp, Char(filename)); return c ? NewStringWithSize(filename, c - Char(filename) + 1) : NewString("");
if (!strstr(tmp, delim)) {
return "";
}
c = tmp + strlen(tmp) - 1;
while (*c != *delim)
c--;
*(++c) = 0;
return tmp;
} }
/* /*

View file

@ -26,10 +26,10 @@ extern void Swig_set_push_dir(int dopush);
extern int Swig_get_push_dir(void); extern int Swig_get_push_dir(void);
extern void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile); extern void Swig_register_filebyname(const_String_or_char_ptr filename, File *outfile);
extern File *Swig_filebyname(const_String_or_char_ptr filename); extern File *Swig_filebyname(const_String_or_char_ptr filename);
extern char *Swig_file_suffix(const_String_or_char_ptr filename); extern String *Swig_file_extension(const_String_or_char_ptr filename);
extern char *Swig_file_basename(const_String_or_char_ptr filename); extern String *Swig_file_basename(const_String_or_char_ptr filename);
extern char *Swig_file_filename(const_String_or_char_ptr filename); extern String *Swig_file_filename(const_String_or_char_ptr filename);
extern char *Swig_file_dirname(const_String_or_char_ptr filename); extern String *Swig_file_dirname(const_String_or_char_ptr filename);
extern void Swig_file_debug_set(); extern void Swig_file_debug_set();
/* Delimiter used in accessing files and directories */ /* Delimiter used in accessing files and directories */