uclient-fetch: read_data_cb: fix a potential buffer overflow
[project/uclient.git] / uclient-fetch.c
index f65fab2..dff144b 100644 (file)
@@ -254,6 +254,7 @@ static void header_done_cb(struct uclient *cl)
 static void read_data_cb(struct uclient *cl)
 {
        char buf[256];
+       ssize_t n;
        int len;
 
        if (!no_output && output_fd < 0)
@@ -261,12 +262,15 @@ static void read_data_cb(struct uclient *cl)
 
        while (1) {
                len = uclient_read(cl, buf, sizeof(buf));
-               if (!len)
+               if (len <= 0)
                        return;
 
                out_bytes += len;
-               if (!no_output)
-                       write(output_fd, buf, len);
+               if (!no_output) {
+                       n = write(output_fd, buf, len);
+                       if (n < 0)
+                               return;
+               }
        }
 }
 
@@ -440,11 +444,11 @@ static int usage(const char *progname)
        fprintf(stderr,
                "Usage: %s [options] <URL>\n"
                "Options:\n"
-               "       -4:                             Use IPv4 only\n"
-               "       -6:                             Use IPv6 only\n"
-               "       -q:                             Turn off status messages\n"
-               "       -O <file>:                      Redirect output to file (use \"-\" for stdout)\n"
-               "       -P <dir>:                       Set directory for output files\n"
+               "       -4                              Use IPv4 only\n"
+               "       -6                              Use IPv6 only\n"
+               "       -q                              Turn off status messages\n"
+               "       -O <file>                       Redirect output to file (use \"-\" for stdout)\n"
+               "       -P <dir>                        Set directory for output files\n"
                "       --user=<user>                   HTTP authentication username\n"
                "       --password=<password>           HTTP authentication password\n"
                "       --user-agent|-U <str>           Set HTTP user agent\n"
@@ -454,8 +458,8 @@ static int usage(const char *progname)
                "       --proxy=on|off|-Y on|off        Enable/disable env var configured proxy\n"
                "\n"
                "HTTPS options:\n"
-               "       --ca-certificate=<cert>:        Load CA certificates from file <cert>\n"
-               "       --no-check-certificate:         don't validate the server's certificate\n"
+               "       --ca-certificate=<cert>         Load CA certificates from file <cert>\n"
+               "       --no-check-certificate          don't validate the server's certificate\n"
                "\n", progname);
        return 1;
 }
@@ -487,7 +491,12 @@ static void init_ustream_ssl(void)
 
 static int no_ssl(const char *progname)
 {
-       fprintf(stderr, "%s: SSL support not available, please install ustream-ssl\n", progname);
+       fprintf(stderr,
+               "%s: SSL support not available, please install one of the "
+               "libustream-ssl-* libraries as well as the ca-bundle and "
+               "ca-certificates packages.\n",
+               progname);
+
        return 1;
 }
 
@@ -503,6 +512,7 @@ enum {
        L_CONTINUE,
        L_PROXY,
        L_NO_PROXY,
+       L_QUIET,
 };
 
 static const struct option longopts[] = {
@@ -517,6 +527,7 @@ static const struct option longopts[] = {
        [L_CONTINUE] = { "continue", no_argument },
        [L_PROXY] = { "proxy", required_argument },
        [L_NO_PROXY] = { "no-proxy", no_argument },
+       [L_QUIET] = { "quiet", no_argument },
        {}
 };
 
@@ -584,6 +595,9 @@ int main(int argc, char **argv)
                        case L_NO_PROXY:
                                proxy = false;
                                break;
+                       case L_QUIET:
+                               quiet = true;
+                               break;
                        default:
                                return usage(progname);
                        }
@@ -650,9 +664,11 @@ int main(int argc, char **argv)
        uloop_init();
 
        if (username) {
-               if (password)
-                       asprintf(&auth_str, "%s:%s", username, password);
-               else
+               if (password) {
+                       rc = asprintf(&auth_str, "%s:%s", username, password);
+                       if (rc < 0)
+                               return rc;
+               } else
                        auth_str = username;
        }