ZipArchive problem with png, pdf and jpeg

More of a PHP issue than a Sugar issue...

I have a custom module is based on the Documents template, so it's basically a copy of documents with uploads.

I have a custom action on the subpanel to "Download All" or "Download Selected" (based on some checkboxes etc).

The API called by the custom subpanel action would take all files linked to that record, or the ones selected in the subpanel, and zip them and download them.

This worked well since v6.x and was neglected for a while. Of course with the recent changes to the uploads dir this needed work.

And came across a problem: certain file types like png, jpeg, and pdf, are getting corrupted in the zip process and either can't be opened or are mangled after download.

If I click the filename to open them individually from the subpanel they download fine (Sugar default behavior). So the files themselves are fine.

To get the Zipped archive I basically create an array of the file path/name for the files selected/all files related to the parent Bean:

      foreach($file_ids as $file_id){
        $fileBean = BeanFactory::retrieveBean($document_module, $file_id);
        $path = UploadFile::realpath(UploadFile::get_upload_path($fileBean->id));
        $files[$fileBean->id] = array(
          'path' => $path,
          'filename' => $fileBean->filename,
        );
      }

Then using that array I add each file into the ZipArchive and return the Archive to be downloaded:

    if (!empty($files)) {
      // open zip
      $time = time();
      if(!is_dir(sugar_cached('temp'))){
        sugar_mkdir(sugar_cached('temp'));
      }
      $zip_path = sugar_cached("temp/{$prefix}download_{$time}.zip");
      $zip = new ZipArchive();
      $added_names = array();
      $count = 1;
      if($zip->open($zip_path, ZIPARCHIVE::CREATE) == TRUE){
        foreach ($files as $file ) {
          if(file_exists($file['path']) && is_readable($file['path'])){
            $filename = $file['filename'];
            if(in_array($filename, $added_names)){
              $filename = $count.$filename;
              $count++;
            }
            $added_names[] = $filename;
            $zip->addFile($file['path'],$filename);
          }
        }
        $zip->close();
        return($sugar_config['site_url'].'/'.$zip_path);
      }
    }
  }

Files like .nb, .jpg, .xlsx download just fine, but png, pdf, and jpeg inside the same archive are corrupted.

I also tried using addFromString instead of addFIle, but the result is the same.

Any thoughts on why certain filetypes would be corrupted and how to avoid it?

Thanks,
FrancescaS

Parents
  • Hi  

    Back in 2022 or 2023 (I can double-check the exact date), we started implementing additional security measures. As part of that, we added a class called FilePhpEntriesConverter in src/Util/Files/FilePhpEntriesConverter.php.

    This class is designed to sanitize files that might have potential vulnerabilities. The issue you're encountering is related to this class.

    Now that we've explained the reason behind it, let's move on to the solution.

    In your code, after retrieving the package, you'll need to revert it to an uncorrupted version. You can do this by using the revert function of the FilePhpEntriesConverter class. This function will create the file in the system's temp folder, and then you'll need to move it to your desired location.

    Let me know if you have any other questions.Slight smile

    Thanks.
    Tevfik Tümer
    Sr. Developer Support Engineer  

Reply
  • Hi  

    Back in 2022 or 2023 (I can double-check the exact date), we started implementing additional security measures. As part of that, we added a class called FilePhpEntriesConverter in src/Util/Files/FilePhpEntriesConverter.php.

    This class is designed to sanitize files that might have potential vulnerabilities. The issue you're encountering is related to this class.

    Now that we've explained the reason behind it, let's move on to the solution.

    In your code, after retrieving the package, you'll need to revert it to an uncorrupted version. You can do this by using the revert function of the FilePhpEntriesConverter class. This function will create the file in the system's temp folder, and then you'll need to move it to your desired location.

    Let me know if you have any other questions.Slight smile

    Thanks.
    Tevfik Tümer
    Sr. Developer Support Engineer  

Children