]> git.saurik.com Git - apt.git/commitdiff
don't leak FD in AutoProxyDetect command return parsing
authorDavid Kalnischkies <david@kalnischkies.de>
Thu, 9 Jun 2016 22:01:46 +0000 (00:01 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Fri, 10 Jun 2016 08:49:41 +0000 (10:49 +0200)
Just closing the fd would be enough, but while we are at it we can also
use the Popen interface to have an easier time with this.

apt-pkg/contrib/proxy.cc

index 0c753131da31cf934bc886e2c8cad0c3c205dd5b..cbe640634cd73e36caaf8fdddf86740cb4a37904 100644 (file)
@@ -16,9 +16,9 @@
 #include <unistd.h>
 
 #include "proxy.h"
+                                                                       /*}}}*/
 
-
-// AutoDetectProxy - auto detect proxy                                 /*{{{*/
+// AutoDetectProxy - auto detect proxy                                 /*{{{*/
 // ---------------------------------------------------------------------
 /* */
 bool AutoDetectProxy(URI &URL)
@@ -41,45 +41,30 @@ bool AutoDetectProxy(URI &URL)
    if (Debug)
       std::clog << "Using auto proxy detect command: " << AutoDetectProxyCmd << std::endl;
 
-   int Pipes[2] = {-1,-1};
-   if (pipe(Pipes) != 0)
-      return _error->Errno("pipe", "Failed to create Pipe");
-
-   pid_t Process = ExecFork();
-   if (Process == 0)
-   {
-      close(Pipes[0]);
-      dup2(Pipes[1],STDOUT_FILENO);
-      SetCloseExec(STDOUT_FILENO,false);
-
-      std::string foo = URL;
-      const char *Args[4];
-      Args[0] = AutoDetectProxyCmd.c_str();
-      Args[1] = foo.c_str();
-      Args[2] = 0;
-      execv(Args[0],(char **)Args);
-      std::cerr << "Failed to exec method " << Args[0] << std::endl;
-      _exit(100);
-   }
+   std::string const urlstring = URL;
+   std::vector<const char *> Args;
+   Args.push_back(AutoDetectProxyCmd.c_str());
+   Args.push_back(urlstring.c_str());
+   Args.push_back(nullptr);
+   FileFd PipeFd;
+   pid_t Child;
+   if(Popen(&Args[0], PipeFd, Child, FileFd::ReadOnly) == false)
+      return _error->Error("ProxyAutoDetect command '%s' failed!", AutoDetectProxyCmd.c_str());
    char buf[512];
-   int InFd = Pipes[0];
-   close(Pipes[1]);
-   int res = read(InFd, buf, sizeof(buf)-1);
-   ExecWait(Process, "ProxyAutoDetect", true);
+   if (PipeFd.ReadLine(buf, sizeof(buf)) == nullptr)
+      return _error->Error("Failed to read in AutoDetectProxy");
+   PipeFd.Close();
+   ExecWait(Child, "ProxyAutoDetect", true);
+   auto const cleanedbuf = _strstrip(buf);
 
-   if (res < 0)
-      return _error->Errno("read", "Failed to read");
-   if (res == 0)
+   if (cleanedbuf[0] == '\0')
       return _error->Warning("ProxyAutoDetect returned no data");
 
-   // add trailing \0
-   buf[res] = 0;
-
    if (Debug)
-      std::clog << "auto detect command returned: '" << buf << "'" << std::endl;
+      std::clog << "auto detect command returned: '" << cleanedbuf << "'" << std::endl;
 
-   if (strstr(buf, URL.Access.c_str()) == buf)
-      _config->Set("Acquire::"+URL.Access+"::proxy::"+URL.Host, _strstrip(buf));
+   if (strstr(cleanedbuf, URL.Access.c_str()) == cleanedbuf)
+      _config->Set("Acquire::"+URL.Access+"::proxy::"+URL.Host, cleanedbuf);
 
    return true;
 }