From 48d4668575fe63285efcedcb7efb18ed9387cd1a Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sat, 22 Sep 2018 09:47:11 -0400 Subject: [PATCH] Ensure all read utilities yield constant string pointers for safety. --- platform-independent/c/cli/src/mpw-cli-util.c | 12 ++++++------ platform-independent/c/cli/src/mpw-cli-util.h | 6 +++--- platform-independent/c/cli/src/mpw-cli.c | 4 ++-- platform-independent/c/core/src/mpw-util.h | 4 ++++ 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/platform-independent/c/cli/src/mpw-cli-util.c b/platform-independent/c/cli/src/mpw-cli-util.c index 2608165d..a42a4f90 100644 --- a/platform-independent/c/cli/src/mpw-cli-util.c +++ b/platform-independent/c/cli/src/mpw-cli-util.c @@ -43,7 +43,7 @@ const char *mpw_getenv(const char *variableName) { return envBuf? mpw_strdup( envBuf ): NULL; } -char *mpw_askpass(const char *prompt) { +const char *mpw_askpass(const char *prompt) { const char *askpass = mpw_getenv( MP_ENV_askpass ); if (!askpass) @@ -74,7 +74,7 @@ char *mpw_askpass(const char *prompt) { } close( pipes[1] ); - char *answer = mpw_read_fd( pipes[0] ); + const char *answer = mpw_read_fd( pipes[0] ); close( pipes[0] ); int status; if (waitpid( pid, &status, 0 ) == ERR) { @@ -86,7 +86,7 @@ char *mpw_askpass(const char *prompt) { if (WIFEXITED( status ) && WEXITSTATUS( status ) == EXIT_SUCCESS && answer && strlen( answer )) { // Remove trailing newline. if (answer[strlen( answer ) - 1] == '\n') - answer[strlen( answer ) - 1] = '\0'; + mpw_replace_string( answer, mpw_strndup( answer, strlen( answer ) - 1 ) ); return answer; } @@ -97,7 +97,7 @@ char *mpw_askpass(const char *prompt) { static const char *_mpw_getline(const char *prompt, bool silent) { // Get answer from askpass. - char *answer = mpw_askpass( prompt ); + const char *answer = mpw_askpass( prompt ); if (answer) return answer; @@ -250,7 +250,7 @@ bool mpw_mkdirs(const char *filePath) { return success; } -char *mpw_read_fd(int fd) { +const char *mpw_read_fd(int fd) { char *buf = NULL; size_t blockSize = 4096, bufSize = 0, bufOffset = 0; @@ -263,7 +263,7 @@ char *mpw_read_fd(int fd) { return buf; } -char *mpw_read_file(FILE *file) { +const char *mpw_read_file(FILE *file) { if (!file) return NULL; diff --git a/platform-independent/c/cli/src/mpw-cli-util.h b/platform-independent/c/cli/src/mpw-cli-util.h index 1641a8ab..357d28fb 100644 --- a/platform-independent/c/cli/src/mpw-cli-util.h +++ b/platform-independent/c/cli/src/mpw-cli-util.h @@ -36,7 +36,7 @@ const char *mpw_getenv(const char *variableName); /** Use the askpass program to prompt the user. * @return A newly allocated string or NULL if askpass is not supported or an error occurred. */ -char *mpw_askpass(const char *prompt); +const char *mpw_askpass(const char *prompt); /** Ask the user a question. * @return A newly allocated string or NULL if an error occurred trying to read from the user. */ @@ -58,11 +58,11 @@ bool mpw_mkdirs(const char *filePath); /** Read until EOF from the given file descriptor. * @return A newly allocated string or NULL the read buffer couldn't be allocated. */ -char *mpw_read_fd(int fd); +const char *mpw_read_fd(int fd); /** Read the file contents of a given file. * @return A newly allocated string or NULL the read buffer couldn't be allocated. */ -char *mpw_read_file(FILE *file); +const char *mpw_read_file(FILE *file); /** Encode a visual fingerprint for a user. * @return A newly allocated string. */ diff --git a/platform-independent/c/cli/src/mpw-cli.c b/platform-independent/c/cli/src/mpw-cli.c index ad3e90e0..306a81d3 100644 --- a/platform-independent/c/cli/src/mpw-cli.c +++ b/platform-independent/c/cli/src/mpw-cli.c @@ -476,8 +476,8 @@ void cli_user(Arguments *args, Operation *operation) { else { // Read file. - char *sitesInputData = mpw_read_file( sitesFile ); - if (ferror( sitesFile )) + const char *sitesInputData = mpw_read_file( sitesFile ); + if (!sitesInputData || ferror( sitesFile )) wrn( "Error while reading configuration file:\n %s: %d", operation->sitesPath, ferror( sitesFile ) ); fclose( sitesFile ); diff --git a/platform-independent/c/core/src/mpw-util.h b/platform-independent/c/core/src/mpw-util.h index eb8a3c8b..fefb75e6 100644 --- a/platform-independent/c/core/src/mpw-util.h +++ b/platform-independent/c/core/src/mpw-util.h @@ -144,6 +144,10 @@ bool __mpw_free_string( ({ __typeof__(strings) _s = strings; const char *__s = *_s; (void)__s; __mpw_free_strings( (char **)_s, __VA_ARGS__ ); }) bool __mpw_free_strings( char **strings, ...); +/** Free a string after zero'ing its contents, then set the reference to the replacement string. + * The replacement string is generated before the original is freed; it may be a derivative of the original. */ +#define mpw_replace_string(string, replacement) \ + do { const char *replacement_ = replacement; mpw_free_string( &string ); string = replacement_; } while (0) #ifdef _MSC_VER #undef mpw_realloc #define mpw_realloc(buffer, bufferSize, deltaSize) \