From e8423f9ce1507c749c559f1ac1847fa433e66c45 Mon Sep 17 00:00:00 2001 From: Jay Satiro Date: Mon, 1 Jun 2015 03:20:18 -0400 Subject: curl_setup: Add macros for FOPEN_READTEXT, FOPEN_WRITETEXT - Change fopen calls to use FOPEN_READTEXT instead of "r" or "rt" - Change fopen calls to use FOPEN_WRITETEXT instead of "w" or "wt" This change is to explicitly specify when we need to read/write text. Unfortunately 't' is not part of POSIX fopen so we can't specify it directly. Instead we now have FOPEN_READTEXT, FOPEN_WRITETEXT. Prior to this change we had an issue on Windows if an application that uses libcurl overrides the default file mode to binary. The default file mode in Windows is normally text mode (translation mode) and that's what libcurl expects. Bug: https://github.com/bagder/curl/pull/258#issuecomment-107093055 Reported-by: Orgad Shaneh --- lib/cookie.c | 4 ++-- lib/curl_setup.h | 20 ++++++++++++++++++++ lib/memdebug.c | 2 +- lib/netrc.c | 6 +----- lib/vtls/gtls.c | 2 +- lib/vtls/openssl.c | 2 +- src/tool_cb_dbg.c | 2 +- src/tool_easysrc.c | 2 +- src/tool_getparam.c | 4 ++-- src/tool_parsecfg.c | 4 ++-- 10 files changed, 32 insertions(+), 16 deletions(-) diff --git a/lib/cookie.c b/lib/cookie.c index 012792605..fd7ed4168 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -914,7 +914,7 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, fp = NULL; } else - fp = file?fopen(file, "r"):NULL; + fp = file?fopen(file, FOPEN_READTEXT):NULL; c->newsession = newsession; /* new session? */ @@ -1262,7 +1262,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) use_stdout=TRUE; } else { - out = fopen(dumphere, "w"); + out = fopen(dumphere, FOPEN_WRITETEXT); if(!out) return 1; /* failure */ } diff --git a/lib/curl_setup.h b/lib/curl_setup.h index 9c7cc07eb..cbec34f26 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -707,4 +707,24 @@ int netware_init(void); #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) #endif +/* In Windows the default file mode is text but an application can override it. +Therefore we specify it explicitly. https://github.com/bagder/curl/pull/258 +*/ +#if defined(WIN32) +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "wt" +#elif defined(__CYGWIN__) +/* Cygwin has specific behavior we need to address when WIN32 is not defined. +https://cygwin.com/cygwin-ug-net/using-textbinary.html +For write we want our output to have line endings of LF and be compatible with +other Cygwin utilities. For read we want to handle input that may have line +endings either CRLF or LF so 't' is appropriate. +*/ +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "w" +#else +#define FOPEN_READTEXT "r" +#define FOPEN_WRITETEXT "w" +#endif + #endif /* HEADER_CURL_SETUP_H */ diff --git a/lib/memdebug.c b/lib/memdebug.c index 3b38a7492..dd8889b2d 100644 --- a/lib/memdebug.c +++ b/lib/memdebug.c @@ -112,7 +112,7 @@ void curl_memdebug(const char *logname) { if(!logfile) { if(logname && *logname) - logfile = fopen(logname, "w"); + logfile = fopen(logname, FOPEN_WRITETEXT); else logfile = stderr; #ifdef MEMDEBUG_LOG_SYNC diff --git a/lib/netrc.c b/lib/netrc.c index 97a07b88e..06f8ea15a 100644 --- a/lib/netrc.c +++ b/lib/netrc.c @@ -109,11 +109,7 @@ int Curl_parsenetrc(const char *host, netrc_alloc = TRUE; } -#ifdef __CYGWIN__ - file = fopen(netrcfile, "rt"); -#else - file = fopen(netrcfile, "r"); -#endif + file = fopen(netrcfile, FOPEN_READTEXT); if(netrc_alloc) free(netrcfile); if(file) { diff --git a/lib/vtls/gtls.c b/lib/vtls/gtls.c index d6eb6c445..1db31e40c 100644 --- a/lib/vtls/gtls.c +++ b/lib/vtls/gtls.c @@ -231,7 +231,7 @@ static gnutls_datum_t load_file (const char *file) long filelen; void *ptr; - if(!(f = fopen(file, "r"))) + if(!(f = fopen(file, "rb"))) return loaded_file; if(fseek(f, 0, SEEK_END) != 0 || (filelen = ftell(f)) < 0 diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c index 96a7d6e89..eb2cf5bf5 100644 --- a/lib/vtls/openssl.c +++ b/lib/vtls/openssl.c @@ -2725,7 +2725,7 @@ static CURLcode servercert(struct connectdata *conn, /* e.g. match issuer name with provided issuer certificate */ if(data->set.str[STRING_SSL_ISSUERCERT]) { - fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], "r"); + fp = fopen(data->set.str[STRING_SSL_ISSUERCERT], FOPEN_READTEXT); if(!fp) { if(strict) failf(data, "SSL: Unable to open issuer cert (%s)", diff --git a/src/tool_cb_dbg.c b/src/tool_cb_dbg.c index 0fe0f1347..f52714683 100644 --- a/src/tool_cb_dbg.c +++ b/src/tool_cb_dbg.c @@ -79,7 +79,7 @@ int tool_debug_cb(CURL *handle, curl_infotype type, /* Ok, this is somewhat hackish but we do it undocumented for now */ config->trace_stream = config->errors; /* aka stderr */ else { - config->trace_stream = fopen(config->trace_dump, "w"); + config->trace_stream = fopen(config->trace_dump, FOPEN_WRITETEXT); config->trace_fopened = TRUE; } } diff --git a/src/tool_easysrc.c b/src/tool_easysrc.c index e1336c3d9..0482ef6ae 100644 --- a/src/tool_easysrc.c +++ b/src/tool_easysrc.c @@ -176,7 +176,7 @@ void dumpeasysrc(struct GlobalConfig *config) FILE *out; bool fopened = FALSE; if(strcmp(o, "-")) { - out = fopen(o, "w"); + out = fopen(o, FOPEN_WRITETEXT); fopened = TRUE; } else diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 62283a5dd..c86e6b4b1 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -681,7 +681,7 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ case 'v': /* --stderr */ if(strcmp(nextarg, "-")) { - FILE *newfile = fopen(nextarg, "wt"); + FILE *newfile = fopen(nextarg, FOPEN_WRITETEXT); if(!newfile) warnf(global, "Failed to open %s!\n", nextarg); else { @@ -1748,7 +1748,7 @@ ParameterError getparameter(char *flag, /* f or -long-flag */ } else { fname = nextarg; - file = fopen(nextarg, "r"); + file = fopen(nextarg, FOPEN_READTEXT); } err = file2string(&config->writeout, file); if(file && (file != stdin)) diff --git a/src/tool_parsecfg.c b/src/tool_parsecfg.c index 4c25ddbd5..39b43eef4 100644 --- a/src/tool_parsecfg.c +++ b/src/tool_parsecfg.c @@ -69,7 +69,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) /* Check if the file exists - if not, try CURLRC in the same * directory as our executable */ - file = fopen(filebuffer, "r"); + file = fopen(filebuffer, FOPEN_READTEXT); if(file != NULL) { fclose(file); filename = filebuffer; @@ -115,7 +115,7 @@ int parseconfig(const char *filename, struct GlobalConfig *global) } if(strcmp(filename, "-")) - file = fopen(filename, "r"); + file = fopen(filename, FOPEN_READTEXT); else file = stdin; -- cgit v1.2.3