Imported Upstream version 7.59.0
[platform/upstream/curl.git] / src / tool_cb_wrt.c
index 0413457..6716ba5 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -72,11 +72,13 @@ bool tool_create_output_file(struct OutStruct *outs)
 ** callback for CURLOPT_WRITEFUNCTION
 */
 
-size_t tool_write_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
+size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
 {
   size_t rc;
   struct OutStruct *outs = userdata;
   struct OperationConfig *config = outs->config;
+  size_t bytes = sz * nmemb;
+  bool is_tty = config->global->isatty;
 
   /*
    * Once that libcurl has called back tool_write_cb() the returned value
@@ -84,21 +86,26 @@ size_t tool_write_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
    * it does not match then it fails with CURLE_WRITE_ERROR. So at this
    * point returning a value different from sz*nmemb indicates failure.
    */
-  const size_t failure = (sz * nmemb) ? 0 : 1;
-
-  if(!config)
-    return failure;
+  const size_t failure = bytes ? 0 : 1;
 
 #ifdef DEBUGBUILD
+  {
+    char *tty = curlx_getenv("CURL_ISATTY");
+    if(tty) {
+      is_tty = TRUE;
+      curl_free(tty);
+    }
+  }
+
   if(config->include_headers) {
-    if(sz * nmemb > (size_t)CURL_MAX_HTTP_HEADER) {
+    if(bytes > (size_t)CURL_MAX_HTTP_HEADER) {
       warnf(config->global, "Header data size exceeds single call write "
             "limit!\n");
       return failure;
     }
   }
   else {
-    if(sz * nmemb > (size_t)CURL_MAX_WRITE_SIZE) {
+    if(bytes > (size_t)CURL_MAX_WRITE_SIZE) {
       warnf(config->global, "Data size exceeds single call write limit!\n");
       return failure;
     }
@@ -137,11 +144,22 @@ size_t tool_write_cb(void *buffer, size_t sz, size_t nmemb, void *userdata)
   if(!outs->stream && !tool_create_output_file(outs))
     return failure;
 
+  if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) {
+    /* binary output to terminal? */
+    if(memchr(buffer, 0, bytes)) {
+      warnf(config->global, "Binary output can mess up your terminal. "
+            "Use \"--output -\" to tell curl to output it to your terminal "
+            "anyway, or consider \"--output <FILE>\" to save to a file.\n");
+      config->synthetic_error = ERR_BINARY_TERMINAL;
+      return failure;
+    }
+  }
+
   rc = fwrite(buffer, sz, nmemb, outs->stream);
 
-  if((sz * nmemb) == rc)
+  if(bytes == rc)
     /* we added this amount of data to the output */
-    outs->bytes += (sz * nmemb);
+    outs->bytes += bytes;
 
   if(config->readbusy) {
     config->readbusy = FALSE;