Commit a3d1fb1c authored by Daniel Salzman's avatar Daniel Salzman

zscanner: fix segfault during final block deinitialization

parent 521a519d
...@@ -146,7 +146,8 @@ int zs_init( ...@@ -146,7 +146,8 @@ int zs_init(
} }
static void input_deinit( static void input_deinit(
zs_scanner_t *s) zs_scanner_t *s,
bool keep_filename)
{ {
// Deinit the file input. // Deinit the file input.
if (s->file.descriptor != -1) { if (s->file.descriptor != -1) {
...@@ -159,6 +160,10 @@ static void input_deinit( ...@@ -159,6 +160,10 @@ static void input_deinit(
// Close the opened file. // Close the opened file.
close(s->file.descriptor); close(s->file.descriptor);
s->file.descriptor = -1; s->file.descriptor = -1;
}
// Keep file name for possible trailing error report.
if (!keep_filename) {
free(s->file.name); free(s->file.name);
s->file.name = NULL; s->file.name = NULL;
} }
...@@ -178,7 +183,7 @@ void zs_deinit( ...@@ -178,7 +183,7 @@ void zs_deinit(
return; return;
} }
input_deinit(s); input_deinit(s, false);
free(s->path); free(s->path);
} }
...@@ -197,20 +202,14 @@ static int set_input_string( ...@@ -197,20 +202,14 @@ static int set_input_string(
return -1; return -1;
} }
// Keep previous input file context if final block parsing. // Deinit possibly opened file.
if (!final_block) { input_deinit(s, final_block);
// Deinit possibly opened file.
input_deinit(s);
}
// Set the scanner input limits. // Set the scanner input limits.
s->input.start = input; s->input.start = input;
s->input.current = input; s->input.current = input;
s->input.end = input + size; s->input.end = input + size;
s->input.eof = final_block;
if (final_block) {
s->input.eof = true;
}
return 0; return 0;
} }
...@@ -239,7 +238,7 @@ int zs_set_input_file( ...@@ -239,7 +238,7 @@ int zs_set_input_file(
} }
// Deinit possibly opened file. // Deinit possibly opened file.
input_deinit(s); input_deinit(s, false);
// Try to open the file. // Try to open the file.
s->file.descriptor = open(file_name, O_RDONLY); s->file.descriptor = open(file_name, O_RDONLY);
...@@ -253,7 +252,7 @@ int zs_set_input_file( ...@@ -253,7 +252,7 @@ int zs_set_input_file(
if (fstat(s->file.descriptor, &file_stat) == -1 || if (fstat(s->file.descriptor, &file_stat) == -1 ||
!S_ISREG(file_stat.st_mode)) { !S_ISREG(file_stat.st_mode)) {
ERR(ZS_FILE_INVALID); ERR(ZS_FILE_INVALID);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
...@@ -264,7 +263,7 @@ int zs_set_input_file( ...@@ -264,7 +263,7 @@ int zs_set_input_file(
s->file.descriptor, 0); s->file.descriptor, 0);
if (start == MAP_FAILED) { if (start == MAP_FAILED) {
ERR(ZS_FILE_MMAP); ERR(ZS_FILE_MMAP);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
...@@ -285,19 +284,19 @@ int zs_set_input_file( ...@@ -285,19 +284,19 @@ int zs_set_input_file(
free(full_name); free(full_name);
if (s->path == NULL) { if (s->path == NULL) {
ERR(ZS_ENOMEM); ERR(ZS_ENOMEM);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
} else { } else {
ERR(ZS_FILE_PATH); ERR(ZS_FILE_PATH);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
s->file.name = strdup(file_name); s->file.name = strdup(file_name);
if (s->file.name == NULL) { if (s->file.name == NULL) {
ERR(ZS_ENOMEM); ERR(ZS_ENOMEM);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
...@@ -5354,7 +5354,8 @@ int zs_init( ...@@ -5354,7 +5354,8 @@ int zs_init(
} }
static void input_deinit( static void input_deinit(
zs_scanner_t *s) zs_scanner_t *s,
bool keep_filename)
{ {
// Deinit the file input. // Deinit the file input.
if (s->file.descriptor != -1) { if (s->file.descriptor != -1) {
...@@ -5367,6 +5368,10 @@ static void input_deinit( ...@@ -5367,6 +5368,10 @@ static void input_deinit(
// Close the opened file. // Close the opened file.
close(s->file.descriptor); close(s->file.descriptor);
s->file.descriptor = -1; s->file.descriptor = -1;
}
// Keep file name for possible trailing error report.
if (!keep_filename) {
free(s->file.name); free(s->file.name);
s->file.name = NULL; s->file.name = NULL;
} }
...@@ -5386,7 +5391,7 @@ void zs_deinit( ...@@ -5386,7 +5391,7 @@ void zs_deinit(
return; return;
} }
input_deinit(s); input_deinit(s, false);
free(s->path); free(s->path);
} }
...@@ -5405,20 +5410,14 @@ static int set_input_string( ...@@ -5405,20 +5410,14 @@ static int set_input_string(
return -1; return -1;
} }
// Keep previous input file context if final block parsing. // Deinit possibly opened file.
if (!final_block) { input_deinit(s, final_block);
// Deinit possibly opened file.
input_deinit(s);
}
// Set the scanner input limits. // Set the scanner input limits.
s->input.start = input; s->input.start = input;
s->input.current = input; s->input.current = input;
s->input.end = input + size; s->input.end = input + size;
s->input.eof = final_block;
if (final_block) {
s->input.eof = true;
}
return 0; return 0;
} }
...@@ -5447,7 +5446,7 @@ int zs_set_input_file( ...@@ -5447,7 +5446,7 @@ int zs_set_input_file(
} }
// Deinit possibly opened file. // Deinit possibly opened file.
input_deinit(s); input_deinit(s, false);
// Try to open the file. // Try to open the file.
s->file.descriptor = open(file_name, O_RDONLY); s->file.descriptor = open(file_name, O_RDONLY);
...@@ -5461,7 +5460,7 @@ int zs_set_input_file( ...@@ -5461,7 +5460,7 @@ int zs_set_input_file(
if (fstat(s->file.descriptor, &file_stat) == -1 || if (fstat(s->file.descriptor, &file_stat) == -1 ||
!S_ISREG(file_stat.st_mode)) { !S_ISREG(file_stat.st_mode)) {
ERR(ZS_FILE_INVALID); ERR(ZS_FILE_INVALID);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
...@@ -5472,7 +5471,7 @@ int zs_set_input_file( ...@@ -5472,7 +5471,7 @@ int zs_set_input_file(
s->file.descriptor, 0); s->file.descriptor, 0);
if (start == MAP_FAILED) { if (start == MAP_FAILED) {
ERR(ZS_FILE_MMAP); ERR(ZS_FILE_MMAP);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
...@@ -5493,19 +5492,19 @@ int zs_set_input_file( ...@@ -5493,19 +5492,19 @@ int zs_set_input_file(
free(full_name); free(full_name);
if (s->path == NULL) { if (s->path == NULL) {
ERR(ZS_ENOMEM); ERR(ZS_ENOMEM);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
} else { } else {
ERR(ZS_FILE_PATH); ERR(ZS_FILE_PATH);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
s->file.name = strdup(file_name); s->file.name = strdup(file_name);
if (s->file.name == NULL) { if (s->file.name == NULL) {
ERR(ZS_ENOMEM); ERR(ZS_ENOMEM);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
......
...@@ -147,7 +147,8 @@ int zs_init( ...@@ -147,7 +147,8 @@ int zs_init(
} }
static void input_deinit( static void input_deinit(
zs_scanner_t *s) zs_scanner_t *s,
bool keep_filename)
{ {
// Deinit the file input. // Deinit the file input.
if (s->file.descriptor != -1) { if (s->file.descriptor != -1) {
...@@ -160,6 +161,10 @@ static void input_deinit( ...@@ -160,6 +161,10 @@ static void input_deinit(
// Close the opened file. // Close the opened file.
close(s->file.descriptor); close(s->file.descriptor);
s->file.descriptor = -1; s->file.descriptor = -1;
}
// Keep file name for possible trailing error report.
if (!keep_filename) {
free(s->file.name); free(s->file.name);
s->file.name = NULL; s->file.name = NULL;
} }
...@@ -179,7 +184,7 @@ void zs_deinit( ...@@ -179,7 +184,7 @@ void zs_deinit(
return; return;
} }
input_deinit(s); input_deinit(s, false);
free(s->path); free(s->path);
} }
...@@ -198,20 +203,14 @@ static int set_input_string( ...@@ -198,20 +203,14 @@ static int set_input_string(
return -1; return -1;
} }
// Keep previous input file context if final block parsing. // Deinit possibly opened file.
if (!final_block) { input_deinit(s, final_block);
// Deinit possibly opened file.
input_deinit(s);
}
// Set the scanner input limits. // Set the scanner input limits.
s->input.start = input; s->input.start = input;
s->input.current = input; s->input.current = input;
s->input.end = input + size; s->input.end = input + size;
s->input.eof = final_block;
if (final_block) {
s->input.eof = true;
}
return 0; return 0;
} }
...@@ -240,7 +239,7 @@ int zs_set_input_file( ...@@ -240,7 +239,7 @@ int zs_set_input_file(
} }
// Deinit possibly opened file. // Deinit possibly opened file.
input_deinit(s); input_deinit(s, false);
// Try to open the file. // Try to open the file.
s->file.descriptor = open(file_name, O_RDONLY); s->file.descriptor = open(file_name, O_RDONLY);
...@@ -254,7 +253,7 @@ int zs_set_input_file( ...@@ -254,7 +253,7 @@ int zs_set_input_file(
if (fstat(s->file.descriptor, &file_stat) == -1 || if (fstat(s->file.descriptor, &file_stat) == -1 ||
!S_ISREG(file_stat.st_mode)) { !S_ISREG(file_stat.st_mode)) {
ERR(ZS_FILE_INVALID); ERR(ZS_FILE_INVALID);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
...@@ -265,7 +264,7 @@ int zs_set_input_file( ...@@ -265,7 +264,7 @@ int zs_set_input_file(
s->file.descriptor, 0); s->file.descriptor, 0);
if (start == MAP_FAILED) { if (start == MAP_FAILED) {
ERR(ZS_FILE_MMAP); ERR(ZS_FILE_MMAP);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
...@@ -286,19 +285,19 @@ int zs_set_input_file( ...@@ -286,19 +285,19 @@ int zs_set_input_file(
free(full_name); free(full_name);
if (s->path == NULL) { if (s->path == NULL) {
ERR(ZS_ENOMEM); ERR(ZS_ENOMEM);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
} else { } else {
ERR(ZS_FILE_PATH); ERR(ZS_FILE_PATH);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
s->file.name = strdup(file_name); s->file.name = strdup(file_name);
if (s->file.name == NULL) { if (s->file.name == NULL) {
ERR(ZS_ENOMEM); ERR(ZS_ENOMEM);
input_deinit(s); input_deinit(s, false);
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment