Diff for /parser3/src/main/pa_exec.C between versions 1.74 and 1.85

version 1.74, 2009/07/06 08:47:10 version 1.85, 2015/10/26 01:21:58
Line 1 Line 1
 /** @file  /** @file
         Parser: program executing for different OS-es.          Parser: program executing for different OS-es.
   
         Copyright(c) 2000-2009 ArtLebedev Group(http://www.artlebedev.com)          Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com)
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
         @todo setrlimit          @todo setrlimit
 */  */
   
 static const char * const IDENT_EXEC_C="$Date$";  
   
 #include "pa_config_includes.h"  #include "pa_config_includes.h"
   
 #include "pa_exec.h"  #include "pa_exec.h"
 #include "pa_exception.h"  #include "pa_exception.h"
 #include "pa_common.h"  #include "pa_common.h"
   
 #ifdef WIN32  volatile const char * IDENT_PA_EXEC_C="$Id$" IDENT_PA_EXEC_H;
 #       include <windows.h>  
 #else  
 #       include <signal.h>  
 #       include <sys/types.h>  
 #       include <sys/wait.h>  
 #endif  
   
 #ifdef WIN32  #ifdef _MSC_VER
   
   #include <windows.h>
   
 /// this func from http://www.ccas.ru/~posp/popov/spawn.htm  /// this func from http://www.ccas.ru/~posp/popov/spawn.htm
 static DWORD CreateHiddenConsoleProcess(LPCTSTR szCmdLine,  static DWORD CreateHiddenConsoleProcess(LPCTSTR szCmdLine,
Line 113  error: Line 107  error:
   
 static void read_pipe(String& result, HANDLE hOutRead, String::Language lang){  static void read_pipe(String& result, HANDLE hOutRead, String::Language lang){
         while(true) {          while(true) {
                 char *buf=new(PointerFreeGC) char[MAX_STRING];                  char *buf=new(PointerFreeGC) char[MAX_STRING+1];
                 unsigned long size;                  DWORD size=0;
                 if(!ReadFile(hOutRead, buf, MAX_STRING-1, &size, NULL) || !size)                   if(!ReadFile(hOutRead, buf, MAX_STRING, &size, NULL) || !size) 
                         break;                          break;
                 buf[size]=0;                  buf[size]=0;
                 result.append_know_length(buf, size, lang);                  result.append_know_length(buf, size, lang);
Line 124  static void read_pipe(String& result, HA Line 118  static void read_pipe(String& result, HA
   
 static void read_pipe(File_read_result& result, HANDLE hOutRead){  static void read_pipe(File_read_result& result, HANDLE hOutRead){
   
         char *buf=new(PointerFreeGC) char[MAX_STRING];          char *buf=(char*)pa_malloc(MAX_STRING+1);
           DWORD bufsize = MAX_STRING;
         unsigned long size = 0;  
         unsigned long bufsize = 0;  
         unsigned long newsize = 0;  
   
         result.headers = 0;          result.headers = 0;
         result.length = 0;          result.length = 0;
Line 136  static void read_pipe(File_read_result& Line 127  static void read_pipe(File_read_result&
         result.success = false;          result.success = false;
   
         while(true) {          while(true) {
                 if(!ReadFile(hOutRead, buf, MAX_STRING-1, &size, NULL) || !size)                   DWORD size=0;
                   if(!ReadFile(hOutRead, buf + result.length, bufsize - result.length, &size, NULL) || !size)
                         break;                          break;
                 newsize = (size + result.length);                  result.length += size;
                 if(newsize > bufsize){                  if(result.length >= bufsize){
                         bufsize = (size==MAX_STRING-1)?newsize*2:newsize;                          bufsize *= 2;
                         char *tmp = new(PointerFreeGC) char[bufsize];                          buf=(char*)pa_realloc(buf, bufsize+1);
                         if(result.str)  
                                 memcpy(tmp, result.str, result.length);  
                         memcpy(tmp+result.length, buf, size);  
                         result.str = tmp;  
                 }else{  
                         memcpy(result.str+result.length, buf, size);  
                 }                  }
                 result.length = newsize;                  result.str=buf;
         }          }
 }  }
   
Line 312  static int get_exit_status(int pid) { Line 298  static int get_exit_status(int pid) {
   
 static void read_pipe(String& result, int file, String::Language lang){  static void read_pipe(String& result, int file, String::Language lang){
         while(true) {          while(true) {
                 char *buf=new(PointerFreeGC) char[MAX_STRING];                  char *buf=new(PointerFreeGC) char[MAX_STRING+1];
                 ssize_t length=read(file, buf, MAX_STRING-1);                  ssize_t length=read(file, buf, MAX_STRING);
                 if(length<=0)                  if(length<=0)
                         break;                          break;
                 buf[length]=0;                  buf[length]=0;
Line 322  static void read_pipe(String& result, in Line 308  static void read_pipe(String& result, in
 }  }
   
 static void read_pipe(File_read_result& result, int file){  static void read_pipe(File_read_result& result, int file){
         char *buf=new(PointerFreeGC) char[MAX_STRING];          char *buf=(char*)pa_malloc(MAX_STRING+1);
           ssize_t bufsize = MAX_STRING;
         unsigned long bufsize = 0;  
         unsigned long newsize = 0;  
   
         result.headers = 0;          result.headers = 0;
         result.length = 0;          result.length = 0;
Line 333  static void read_pipe(File_read_result& Line 317  static void read_pipe(File_read_result&
         result.success = false;          result.success = false;
   
         while(true) {          while(true) {
                 ssize_t size=read(file, buf, MAX_STRING-1);                  ssize_t size=read(file, buf + result.length, bufsize - result.length);
                 if(size <= 0)                  if(size <= 0)
                         break;                          break;
                 newsize = (size + result.length);                  result.length += size;
                 if(newsize > bufsize){                  if(result.length >= bufsize){
                         bufsize = (size==MAX_STRING-1)?newsize*2:newsize;                          bufsize *= 2;
                         char *tmp = new(PointerFreeGC) char[bufsize];                          buf=(char*)pa_realloc(buf, bufsize+1);
                         if(result.str)  
                                 memcpy(tmp, result.str, result.length);  
                         memcpy(tmp+result.length, buf, size);  
                         result.str = tmp;  
                 }else{  
                         memcpy(result.str+result.length, buf, size);  
                 }                  }
                 result.length = newsize;                  result.str=buf;
         }          }
 }  }
   
Line 355  static void read_pipe(File_read_result& Line 333  static void read_pipe(File_read_result&
   
 #ifndef DOXYGEN  #ifndef DOXYGEN
 struct Append_env_pair_info {  struct Append_env_pair_info {
 #ifdef WIN32  #ifdef _MSC_VER
         String::Body& body;          String::Body& body;
         Append_env_pair_info(String::Body& abody): body(abody) {}          Append_env_pair_info(String::Body& abody): body(abody) {}
 #else  #else
Line 363  struct Append_env_pair_info { Line 341  struct Append_env_pair_info {
 #endif  #endif
 };  };
 #endif  #endif
 ///@test maybe here and at argv construction --- cstr(String::L_UNSPECIFIED  
   ///@test maybe here and at argv construction --- untaint_cstr(String::L_AS_IS
 static void append_env_pair(HashStringString::key_type key, HashStringString::value_type value,  static void append_env_pair(HashStringString::key_type key, HashStringString::value_type value,
                 Append_env_pair_info *info) {                  Append_env_pair_info *info) {
 #ifdef WIN32  #ifdef _MSC_VER
         info->body << key << "=" << value;          info->body << key << "=" << value;
         info->body.append_know_length("\1", 1); // placeholder for of zero byte          info->body.append_know_length("\1", 1); // placeholder for of zero byte
 #else  #else
Line 378  static void append_env_pair(HashStringSt Line 357  static void append_env_pair(HashStringSt
 }  }
   
 PA_exec_result pa_exec(  PA_exec_result pa_exec(
                         bool                           bool forced_allow,
 #if defined(NO_PA_EXEC) || defined(PA_SAFE_MODE)  
                         forced_allow  
 #endif  
                         ,   
                         const String& file_spec,                           const String& file_spec, 
                         const HashStringString* env,                           const HashStringString* env, 
                         const ArrayString& argv,                           const ArrayString& argv, 
Line 396  PA_exec_result pa_exec( Line 371  PA_exec_result pa_exec(
                         "parser execs are disabled [recompile parser without --disable-execs configure option]");                          "parser execs are disabled [recompile parser without --disable-execs configure option]");
 #endif  #endif
   
 #ifdef WIN32  #ifdef _MSC_VER
   
         PROCESS_INFORMATION pi;           PROCESS_INFORMATION pi; 
         HANDLE hInWrite, hOutRead, hErrRead;          HANDLE hInWrite, hOutRead, hErrRead;
         const char* script_spec_cstr=file_spec.cstr_taint(String::L_FILE_SPEC);          const char* script_spec_cstr=file_spec.taint_cstr(String::L_FILE_SPEC);
         const char* cmd=buildCommand(script_spec_cstr, argv);          const char* cmd=buildCommand(script_spec_cstr, argv);
         char* env_cstr=0;          char* env_cstr=0;
         if(env) {          if(env) {
Line 437  PA_exec_result pa_exec( Line 412  PA_exec_result pa_exec(
                 CloseHandle(hInWrite);                  CloseHandle(hInWrite);
                 read_pipe(result.out, hOutRead);                  read_pipe(result.out, hOutRead);
                 CloseHandle(hOutRead);                  CloseHandle(hOutRead);
                 read_pipe(result.err, hErrRead, String::L_TAINTED);                               read_pipe(result.err, hErrRead, String::L_TAINTED);
                 CloseHandle(hErrRead);                  CloseHandle(hErrRead);
 /*                        // We must close the handles to the new process and its main thread
 from http://www.apache.org/websrc/cvsweb.cgi/apache-1.3/src/main/util_script.c?rev=1.151&content-type=text/vnd.viewcvs-markup                  // to prevent handle and memory leaks.
   
         * We must close the handles to the new process and its main thread  
         * to prevent handle and memory leaks.  
 */        
                 CloseHandle(pi.hProcess);                  CloseHandle(pi.hProcess);
                 CloseHandle(pi.hThread);                  CloseHandle(pi.hThread);
         }          }
Line 452  from http://www.apache.org/websrc/cvsweb Line 423  from http://www.apache.org/websrc/cvsweb
 #else  #else
   
         // execve needs non const          // execve needs non const
         char* file_spec_cstr=file_spec.cstrm(String::L_FILE_SPEC);           char* file_spec_cstr=file_spec.taint_cstrm(String::L_FILE_SPEC); 
   
         int pipe_write, pipe_read, pipe_err;          int pipe_write, pipe_read, pipe_err;
   
 #ifdef PA_SAFE_MODE  
         if(!forced_allow) {          if(!forced_allow) {
                 struct stat finfo;                  struct stat finfo;
                 if(stat(file_spec_cstr, &finfo)!=0)                  if(stat(file_spec_cstr, &finfo)!=0)
Line 467  from http://www.apache.org/websrc/cvsweb Line 437  from http://www.apache.org/websrc/cvsweb
   
                 check_safe_mode(finfo, file_spec, file_spec_cstr);                  check_safe_mode(finfo, file_spec, file_spec_cstr);
         }          }
 #endif  
   
         char* argv_cstrs[1+50+1]={file_spec_cstr, 0};          char* argv_cstrs[1+100+1]={file_spec_cstr, 0};
         const int argv_size=argv.count();          const int argv_size=argv.count();
         const int argv_max=sizeof(argv_cstrs)/sizeof(argv_cstrs[0])-1-1;          const int argv_max=sizeof(argv_cstrs)/sizeof(argv_cstrs[0])-1-1;
         if(argv_size>argv_max)          if(argv_size>argv_max)

Removed from v.1.74  
changed lines
  Added in v.1.85


E-mail: