Port the security fixes to Windows. Thanks to PXEGeek for much patience and testing...
authorpabs <pabs@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Thu, 27 Dec 2007 07:34:47 +0000 (07:34 +0000)
committerpabs <pabs@1f10aa63-cdf2-0310-b900-c93c546f37ac>
Thu, 27 Dec 2007 07:34:47 +0000 (07:34 +0000)
git-svn-id: http://svn.voria.com/code@1237 1f10aa63-cdf2-0310-b900-c93c546f37ac

synfig-core/trunk/configure.ac
synfig-core/trunk/src/modules/mod_dv/trgt_dv.cpp
synfig-core/trunk/src/modules/mod_ffmpeg/mptr_ffmpeg.cpp
synfig-core/trunk/src/modules/mod_ffmpeg/trgt_ffmpeg.cpp
synfig-core/trunk/src/modules/mod_imagemagick/mptr_imagemagick.cpp
synfig-core/trunk/src/modules/mod_imagemagick/trgt_imagemagick.cpp

index 52eb846..aec847f 100644 (file)
@@ -472,6 +472,9 @@ esac
 
 # -- H E A D E R S --------------------------------------------
 
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([process.h io.h fcntl.h])
+
 # -- T Y P E S & S T R U C T S --------------------------------
 
 # -- F U N C T I O N S ----------------------------------------
@@ -483,6 +486,10 @@ dnl ])
 AC_CHECK_FUNCS([fork])
 AC_CHECK_FUNCS([kill])
 AC_CHECK_FUNCS([pipe])
+AC_CHECK_FUNCS([waitpid])
+AC_CHECK_FUNCS([_spawnlp])
+AC_CHECK_FUNCS([_pipe])
+AC_CHECK_FUNCS([cwait])
 
 AC_CHECK_FUNCS(
        [isnan],
index a820c33..d4b7440 100644 (file)
 #include "trgt_dv.h"
 #include <stdio.h>
 #include <sys/types.h>
-#include <sys/wait.h>
+#if HAVE_SYS_WAIT_H
+ #include <sys/wait.h>
+#endif
+#if HAVE_IO_H
+ #include <io.h>
+#endif
+#if HAVE_PROCESS_H
+ #include <process.h>
+#endif
+#if HAVE_FCNTL_H
+ #include <fcntl.h>
+#endif
 #include <unistd.h>
 #include <algorithm>
 #include <functional>
@@ -51,6 +62,12 @@ using namespace synfig;
 using namespace std;
 using namespace etl;
 
+#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)
+ #define UNIX_PIPE_TO_PROCESSES
+#elif defined(HAVE__SPAWNLP) && defined(HAVE__PIPE) && defined(HAVE_CWAIT)
+ #define WIN32_PIPE_TO_PROCESSES
+#endif
+
 /* === G L O B A L S ======================================================= */
 
 SYNFIG_TARGET_INIT(dv_trgt);
@@ -79,7 +96,11 @@ dv_trgt::~dv_trgt()
        if(file){
                fclose(file);
                int status;
+#if defined(WIN32_PIPE_TO_PROCESSES)
+               cwait(&status,pid,0);
+#elif defined(UNIX_PIPE_TO_PROCESSES)
                waitpid(pid,&status,0);
+#endif
        }
        file=NULL;
        delete [] buffer;
@@ -127,6 +148,66 @@ dv_trgt::init()
 {
        imagecount=desc.get_frame_start();
 
+#if defined(WIN32_PIPE_TO_PROCESSES)
+
+       int p[2];
+       int stdin_fileno, stdout_fileno;
+
+       if(_pipe(p, 512, O_BINARY | O_NOINHERIT) < 0) {
+               synfig::error(_("Unable to open pipe to encodedv"));
+               return false;
+       }
+
+       // Save stdin/stdout so we can restore them later
+       stdin_fileno  = _dup(_fileno(stdin));
+       stdout_fileno = _dup(_fileno(stdout));
+
+       // encodedv should read from the pipe
+       if(_dup2(p[0], _fileno(stdin)) != 0) {
+               synfig::error(_("Unable to open pipe to encodedv"));
+               return false;
+       }
+
+       FILE* outfile = fopen(filename.c_str(),"wb");
+       if( outfile == NULL ){
+               synfig::error(_("Unable to open pipe to encodedv"));
+               return false;
+       }
+       if(_dup2(_fileno(outfile), _fileno(stdout)) != 0) {
+               synfig::error(_("Unable to open pipe to encodedv"));
+               return false;
+       }
+
+       if(wide_aspect)
+               pid = _spawnlp(_P_NOWAIT, "encodedv", "encodedv", "-w", "1", "-", (const char *)NULL);
+       else
+               pid = _spawnlp(_P_NOWAIT, "encodedv", "encodedv", "-", (const char *)NULL);
+
+       if( pid < 0) {
+               synfig::error(_("Unable to open pipe to encodedv"));
+               return false;
+       }
+
+       // Restore stdin/stdout
+       if(_dup2(stdin_fileno, _fileno(stdin)) != 0) {
+               synfig::error(_("Unable to open pipe to encodedv"));
+               return false;
+       }
+       if(_dup2(stdout_fileno, _fileno(stdout)) != 0) {
+               synfig::error(_("Unable to open pipe to encodedv"));
+               return false;
+       }
+       close(stdin_fileno);
+       close(stdout_fileno);
+
+       // Close the pipe read end - encodedv uses it
+       close(p[0]);
+       
+       // We write data to the write end of the pipe
+       file = fdopen(p[1], "wb");
+
+#elif defined(UNIX_PIPE_TO_PROCESSES)
+
        int p[2];
   
        if (pipe(p)) {
@@ -187,6 +268,11 @@ dv_trgt::init()
                }
        }
 
+#else
+       #error There are no known APIs for creating child processes
+#endif
+
+
        // Sleep for a moment to let the pipe catch up
        etl::clock().sleep(0.25f);
 
index f1f7e0b..827a527 100644 (file)
 #include "mptr_ffmpeg.h"
 #include <stdio.h>
 #include <sys/types.h>
-#include <sys/wait.h>
+#if HAVE_SYS_WAIT_H
+ #include <sys/wait.h>
+#endif
+#if HAVE_IO_H
+ #include <io.h>
+#endif
+#if HAVE_PROCESS_H
+ #include <process.h>
+#endif
+#if HAVE_FCNTL_H
+ #include <fcntl.h>
+#endif
 #include <unistd.h>
 #include <iostream>
 #include <algorithm>
@@ -49,6 +60,12 @@ using namespace synfig;
 using namespace std;
 using namespace etl;
 
+#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)
+ #define UNIX_PIPE_TO_PROCESSES
+#elif defined(HAVE__SPAWNLP) && defined(HAVE__PIPE) && defined(HAVE_CWAIT)
+ #define WIN32_PIPE_TO_PROCESSES
+#endif
+
 /* === G L O B A L S ======================================================= */
 
 SYNFIG_IMPORTER_INIT(ffmpeg_mptr);
@@ -68,9 +85,67 @@ ffmpeg_mptr::seek_to(int frame)
                {
                        fclose(file);
                        int status;
-                       waitpid(pid,&status,0);
+#if defined(WIN32_PIPE_TO_PROCESSES)
+               cwait(&status,pid,0);
+#elif defined(UNIX_PIPE_TO_PROCESSES)
+               waitpid(pid,&status,0);
+#endif
                }
 
+#if defined(WIN32_PIPE_TO_PROCESSES)
+
+       int p[2];
+       int stdin_fileno, stdout_fileno;
+
+       if(_pipe(p, 512, O_BINARY | O_NOINHERIT) < 0) {
+               cerr<<"Unable to open pipe to ffmpeg"<<endl;
+               return false;
+       }
+
+       // Save stdin/stdout so we can restore them later
+       stdin_fileno  = _dup(_fileno(stdin));
+       stdout_fileno = _dup(_fileno(stdout));
+
+       // ffmpeg should write to the pipe
+       if(_dup2(p[1], _fileno(stdout)) != 0) {
+               cerr<<"Unable to open pipe to ffmpeg"<<endl;
+               return false;
+       }
+
+       /*
+       ffmpeg accepts the input filename on the command-line
+       if(_dup2(_fileno(input), _fileno(stdin)) != 0) {
+               synfig::error(_("Unable to open pipe to ffmpeg"));
+               return false;
+       }
+       */
+
+       pid = _spawnlp(_P_NOWAIT, "ffmpeg", "ffmpeg", "-i", filename.c_str(), "-an", "-f", "image2pipe", "-vcodec", "ppm", "-", (const char *)NULL);
+       if( pid < 0) {
+               cerr<<"Unable to open pipe to ffmpeg"<<endl;
+               return false;
+       }
+
+       // Restore stdin/stdout
+       if(_dup2(stdin_fileno, _fileno(stdin)) != 0) {
+               cerr<<"Unable to open pipe to ffmpeg"<<endl;
+               return false;
+       }
+       if(_dup2(stdout_fileno, _fileno(stdout)) != 0) {
+               cerr<<"Unable to open pipe to ffmpeg"<<endl;
+               return false;
+       }
+       close(stdin_fileno);
+       close(stdout_fileno);
+
+       // Close the pipe write end - ffmpeg uses it
+       close(p[1]);
+       
+       // We read data from the read end of the pipe
+       file = fdopen(p[0], "rb");
+
+#elif defined(UNIX_PIPE_TO_PROCESSES)
+
                int p[2];
          
                if (pipe(p)) {
@@ -108,6 +183,10 @@ ffmpeg_mptr::seek_to(int frame)
                        file = fdopen(p[0], "rb");
                }
 
+#else
+       #error There are no known APIs for creating child processes
+#endif
+
                if(!file)
                {
                        cerr<<"Unable to open pipe to ffmpeg"<<endl;
@@ -200,7 +279,11 @@ ffmpeg_mptr::~ffmpeg_mptr()
        {
                fclose(file);
                int status;
+#if defined(WIN32_PIPE_TO_PROCESSES)
+               cwait(&status,pid,0);
+#elif defined(UNIX_PIPE_TO_PROCESSES)
                waitpid(pid,&status,0);
+#endif
        }
 #ifdef HAVE_TERMIOS_H
        tcsetattr(0,TCSANOW,&oldtty);
index 1832ccd..c5e1cf3 100644 (file)
 #include "trgt_ffmpeg.h"
 #include <stdio.h>
 #include <sys/types.h>
-#include <sys/wait.h>
+#if HAVE_SYS_WAIT_H
+ #include <sys/wait.h>
+#endif
+#if HAVE_IO_H
+ #include <io.h>
+#endif
+#if HAVE_PROCESS_H
+ #include <process.h>
+#endif
+#if HAVE_FCNTL_H
+ #include <fcntl.h>
+#endif
 #include <unistd.h>
 #include <algorithm>
 #include <functional>
@@ -51,6 +62,12 @@ using namespace synfig;
 using namespace std;
 using namespace etl;
 
+#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)
+ #define UNIX_PIPE_TO_PROCESSES
+#elif defined(HAVE__SPAWNLP) && defined(HAVE__PIPE) && defined(HAVE_CWAIT)
+ #define WIN32_PIPE_TO_PROCESSES
+#endif
+
 /* === G L O B A L S ======================================================= */
 
 SYNFIG_TARGET_INIT(ffmpeg_trgt);
@@ -80,7 +97,11 @@ ffmpeg_trgt::~ffmpeg_trgt()
                sleep(1);
                fclose(file);
                int status;
+#if defined(WIN32_PIPE_TO_PROCESSES)
+               cwait(&status,pid,0);
+#elif defined(UNIX_PIPE_TO_PROCESSES)
                waitpid(pid,&status,0);
+#endif
        }
        file=NULL;
        delete [] buffer;
@@ -131,6 +152,64 @@ ffmpeg_trgt::init()
        if(desc.get_frame_end()-desc.get_frame_start()>0)
                multi_image=true;
 
+#if defined(WIN32_PIPE_TO_PROCESSES)
+
+       int p[2];
+       int stdin_fileno, stdout_fileno;
+
+       if(_pipe(p, 512, O_BINARY | O_NOINHERIT) < 0) {
+               synfig::error(_("Unable to open pipe to ffmpeg"));
+               return false;
+       }
+
+       // Save stdin/stdout so we can restore them later
+       stdin_fileno  = _dup(_fileno(stdin));
+       stdout_fileno = _dup(_fileno(stdout));
+
+       // ffmpeg should read from the pipe
+       if(_dup2(p[0], _fileno(stdin)) != 0) {
+               synfig::error(_("Unable to open pipe to ffmpeg"));
+               return false;
+       }
+
+       /*
+       ffmpeg accepts the output filename on the command-line
+       if(_dup2(_fileno(output), _fileno(stdout)) != 0) {
+               synfig::error(_("Unable to open pipe to ffmpeg"));
+               return false;
+       }
+       */
+
+       if( filename.c_str()[0] == '-' )
+               pid = _spawnlp(_P_NOWAIT, "ffmpeg", "ffmpeg", "-f", "image2pipe", "-vcodec", "ppm", "-an", "-r", strprintf("%f", desc.get_frame_rate()).c_str(), "-i", "pipe:", "-loop", "-hq", "-title", get_canvas()->get_name().c_str(), "-vcodec", "mpeg1video", "-y", "--", filename.c_str(), (const char *)NULL);
+       else
+               pid = _spawnlp(_P_NOWAIT, "ffmpeg", "ffmpeg", "-f", "image2pipe", "-vcodec", "ppm", "-an", "-r", strprintf("%f", desc.get_frame_rate()).c_str(), "-i", "pipe:", "-loop", "-hq", "-title", get_canvas()->get_name().c_str(), "-vcodec", "mpeg1video", "-y", filename.c_str(), (const char *)NULL);
+
+       if( pid < 0) {
+               synfig::error(_("Unable to open pipe to ffmpeg"));
+               return false;
+       }
+
+       // Restore stdin/stdout
+       if(_dup2(stdin_fileno, _fileno(stdin)) != 0) {
+               synfig::error(_("Unable to open pipe to ffmpeg"));
+               return false;
+       }
+       if(_dup2(stdout_fileno, _fileno(stdout)) != 0) {
+               synfig::error(_("Unable to open pipe to ffmpeg"));
+               return false;
+       }
+       close(stdin_fileno);
+       close(stdout_fileno);
+
+       // Close the pipe read end - ffmpeg uses it
+       close(p[0]);
+       
+       // We write data to the write end of the pipe
+       file = fdopen(p[1], "wb");
+
+#elif defined(UNIX_PIPE_TO_PROCESSES)
+
        int p[2];
   
        if (pipe(p)) {
@@ -171,6 +250,10 @@ ffmpeg_trgt::init()
                file = fdopen(p[1], "wb");
        }
 
+#else
+       #error There are no known APIs for creating child processes
+#endif
+
        // etl::yield();
 
        if(!file)
index 4d7ca20..c945ee5 100644 (file)
 #include "mptr_imagemagick.h"
 #include <stdio.h>
 #include <sys/types.h>
-#include <sys/wait.h>
+#if HAVE_SYS_WAIT_H
+ #include <sys/wait.h>
+#endif
+#if HAVE_IO_H
+ #include <io.h>
+#endif
+#if HAVE_PROCESS_H
+ #include <process.h>
+#endif
+#if HAVE_FCNTL_H
+ #include <fcntl.h>
+#endif
 #include <unistd.h>
 #include <algorithm>
 #include <functional>
@@ -50,6 +61,12 @@ using namespace synfig;
 using namespace std;
 using namespace etl;
 
+#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)
+ #define UNIX_PIPE_TO_PROCESSES
+#elif defined(HAVE__SPAWNLP) && defined(HAVE__PIPE) && defined(HAVE_CWAIT)
+ #define WIN32_PIPE_TO_PROCESSES
+#endif
+
 /* === G L O B A L S ======================================================= */
 
 SYNFIG_IMPORTER_INIT(imagemagick_mptr);
@@ -89,6 +106,15 @@ imagemagick_mptr::get_frame(synfig::Surface &surface,Time /*time*/, synfig::Prog
        string temp_file="/tmp/deleteme.png";
        string output="png32:"+temp_file;
 
+#if defined(WIN32_PIPE_TO_PROCESSES)
+
+       if(filename.find("psd")!=String::npos)
+               _spawnlp(_P_WAIT, "convert", "convert", filename.c_str(), "-flatten", output.c_str(), (const char *)NULL);
+       else
+               _spawnlp(_P_WAIT, "convert", "convert", filename.c_str(), output.c_str(), (const char *)NULL);
+
+#elif defined(UNIX_PIPE_TO_PROCESSES)
+
        pid_t pid = fork();
   
        if (pid == -1) {
@@ -110,6 +136,10 @@ imagemagick_mptr::get_frame(synfig::Surface &surface,Time /*time*/, synfig::Prog
        if( (WIFEXITED(status) && WEXITSTATUS(status) != 0) || !WIFEXITED(status) )
                return false;
 
+#else
+       #error There are no known APIs for creating child processes
+#endif
+
        Importer::Handle importer(Importer::open(temp_file));
 
        DEBUGPOINT();
index bfd8f59..f33b98f 100644 (file)
 #include "trgt_imagemagick.h"
 #include <stdio.h>
 #include <sys/types.h>
-#include <sys/wait.h>
+#if HAVE_SYS_WAIT_H
+ #include <sys/wait.h>
+#endif
+#if HAVE_IO_H
+ #include <io.h>
+#endif
+#if HAVE_PROCESS_H
+ #include <process.h>
+#endif
+#if HAVE_FCNTL_H
+ #include <fcntl.h>
+#endif
 #include <unistd.h>
 #include <algorithm>
 #include <functional>
@@ -52,6 +63,12 @@ using namespace synfig;
 using namespace std;
 using namespace etl;
 
+#if defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)
+ #define UNIX_PIPE_TO_PROCESSES
+#elif defined(HAVE__SPAWNLP) && defined(HAVE__PIPE) && defined(HAVE_CWAIT)
+ #define WIN32_PIPE_TO_PROCESSES
+#endif
+
 /* === G L O B A L S ======================================================= */
 
 SYNFIG_TARGET_INIT(imagemagick_trgt);
@@ -77,7 +94,11 @@ imagemagick_trgt::~imagemagick_trgt()
        if(file){
                fclose(file);
                int status;
+#if defined(WIN32_PIPE_TO_PROCESSES)
+               cwait(&status,pid,0);
+#elif defined(UNIX_PIPE_TO_PROCESSES)
                waitpid(pid,&status,0);
+#endif
        }
        file=NULL;
        delete [] buffer;
@@ -119,7 +140,11 @@ imagemagick_trgt::end_frame()
                fflush(file);
                fclose(file);
                int status;
+#if defined(WIN32_PIPE_TO_PROCESSES)
+               cwait(&status,pid,0);
+#elif defined(UNIX_PIPE_TO_PROCESSES)
                waitpid(pid,&status,0);
+#endif
        }
        file=NULL;
        imagecount++;
@@ -139,6 +164,73 @@ imagemagick_trgt::start_frame(synfig::ProgressCallback *cb)
        else
                newfilename = filename;
 
+#if defined(WIN32_PIPE_TO_PROCESSES)
+
+       int p[2];
+       int stdin_fileno, stdout_fileno;
+
+       if(_pipe(p, 512, O_BINARY | O_NOINHERIT) < 0) {
+               if(cb) cb->error(N_(msg));
+               else synfig::error(N_(msg));
+               return false;
+       }
+
+       // Save stdin/stdout so we can restore them later
+       stdin_fileno  = _dup(_fileno(stdin));
+       stdout_fileno = _dup(_fileno(stdout));
+
+       // convert should read from the pipe
+       if(_dup2(p[0], _fileno(stdin)) != 0) {
+               if(cb) cb->error(N_(msg));
+               else synfig::error(N_(msg));
+               return false;
+       }
+
+       /*
+       convert accepts the output filename on the command-line
+       if(_dup2(_fileno(output), _fileno(stdout)) != 0) {
+               if(cb) cb->error(N_(msg));
+               else synfig::error(N_(msg));
+               return false;
+       }
+       */
+
+       pid = _spawnlp(_P_NOWAIT, "convert", "convert",
+               "-depth", "8",
+               "-size", strprintf("%dx%d", desc.get_w(), desc.get_h()).c_str(),
+               ((channels(pf) == 4) ? "rgba:-[0]" : "rgb:-[0]"),
+               "-density", strprintf("%dx%d", round_to_int(desc.get_x_res()/39.3700787402), round_to_int(desc.get_y_res()/39.3700787402)).c_str(),
+               newfilename.c_str(),
+               (const char *)NULL);
+
+       if( pid < 0) {
+               if(cb) cb->error(N_(msg));
+               else synfig::error(N_(msg));
+               return false;
+       }
+
+       // Restore stdin/stdout
+       if(_dup2(stdin_fileno, _fileno(stdin)) != 0) {
+               if(cb) cb->error(N_(msg));
+               else synfig::error(N_(msg));
+               return false;
+       }
+       if(_dup2(stdout_fileno, _fileno(stdout)) != 0) {
+               if(cb) cb->error(N_(msg));
+               else synfig::error(N_(msg));
+               return false;
+       }
+       close(stdin_fileno);
+       close(stdout_fileno);
+
+       // Close the pipe read end - convert uses it
+       close(p[0]);
+       
+       // We write data to the write end of the pipe
+       file = fdopen(p[1], "wb");
+
+#elif defined(UNIX_PIPE_TO_PROCESSES)
+
        int p[2];
   
        if (pipe(p)) {
@@ -186,6 +278,10 @@ imagemagick_trgt::start_frame(synfig::ProgressCallback *cb)
                file = fdopen(p[1], "wb");
        }
 
+#else
+       #error There are no known APIs for creating child processes
+#endif
+
        if(!file)
        {
                if(cb)cb->error(N_(msg));