You are here

function PclZip::privExtractByRule in Quiz 6.6

Same name and namespace in other branches
  1. 6.5 includes/moodle/lib/pclzip/pclzip.lib.php \PclZip::privExtractByRule()
2 calls to PclZip::privExtractByRule()
PclZip::extract in includes/moodle/lib/pclzip/pclzip.lib.php
PclZip::extractByIndex in includes/moodle/lib/pclzip/pclzip.lib.php

File

includes/moodle/lib/pclzip/pclzip.lib.php, line 3114

Class

PclZip

Code

function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) {

  //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
  $v_result = 1;

  // ----- Magic quotes trick
  $this
    ->privDisableMagicQuotes();

  // ----- Check the path
  if ($p_path == "" || substr($p_path, 0, 1) != "/" && substr($p_path, 0, 3) != "../" && substr($p_path, 1, 2) != ":/") {
    $p_path = "./" . $p_path;
  }

  // ----- Reduce the path last (and duplicated) '/'
  if ($p_path != "./" && $p_path != "/") {

    // ----- Look for the path end '/'
    while (substr($p_path, -1) == "/") {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
      $p_path = substr($p_path, 0, strlen($p_path) - 1);

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
    }
  }

  // ----- Look for path to remove format (should end by /)
  if ($p_remove_path != "" && substr($p_remove_path, -1) != '/') {
    $p_remove_path .= '/';
  }
  $p_remove_path_size = strlen($p_remove_path);

  // ----- Open the zip file

  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  if (($v_result = $this
    ->privOpenFd('rb')) != 1) {
    $this
      ->privSwapBackMagicQuotes();

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    return $v_result;
  }

  // ----- Read the central directory informations
  $v_central_dir = array();
  if (($v_result = $this
    ->privReadEndCentralDir($v_central_dir)) != 1) {

    // ----- Close the zip file
    $this
      ->privCloseFd();
    $this
      ->privSwapBackMagicQuotes();

    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
    return $v_result;
  }

  // ----- Start at beginning of Central Dir
  $v_pos_entry = $v_central_dir['offset'];

  // ----- Read each entry
  $j_start = 0;
  for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");

    // ----- Read next Central dir entry

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
    @rewind($this->zip_fd);

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
    if (@fseek($this->zip_fd, $v_pos_entry)) {

      // ----- Close the zip file
      $this
        ->privCloseFd();
      $this
        ->privSwapBackMagicQuotes();

      // ----- Error log
      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');

      // ----- Return

      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
      return PclZip::errorCode();
    }

    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");

    // ----- Read the file header
    $v_header = array();
    if (($v_result = $this
      ->privReadCentralFileHeader($v_header)) != 1) {

      // ----- Close the zip file
      $this
        ->privCloseFd();
      $this
        ->privSwapBackMagicQuotes();

      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
      return $v_result;
    }

    // ----- Store the index
    $v_header['index'] = $i;

    // ----- Store the file position
    $v_pos_entry = ftell($this->zip_fd);

    // ----- Look for the specific extract rules
    $v_extract = false;

    // ----- Look for extract by name rule
    if (isset($p_options[PCLZIP_OPT_BY_NAME]) && $p_options[PCLZIP_OPT_BY_NAME] != 0) {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");

      // ----- Look if the filename is in the list
      for ($j = 0; $j < sizeof($p_options[PCLZIP_OPT_BY_NAME]) && !$v_extract; $j++) {

        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");

        // ----- Look for a directory
        if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {

          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");

          // ----- Look if the directory is in the filename path
          if (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]) && substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j]) {

            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
            $v_extract = true;
          }
        }
        elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {

          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
          $v_extract = true;
        }
      }
    }
    else {
      if (isset($p_options[PCLZIP_OPT_BY_EREG]) && $p_options[PCLZIP_OPT_BY_EREG] != "") {

        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
        if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {

          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
          $v_extract = true;
        }
      }
      else {
        if (isset($p_options[PCLZIP_OPT_BY_PREG]) && $p_options[PCLZIP_OPT_BY_PREG] != "") {

          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {

            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
            $v_extract = true;
          }
        }
        else {
          if (isset($p_options[PCLZIP_OPT_BY_INDEX]) && $p_options[PCLZIP_OPT_BY_INDEX] != 0) {

            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");

            // ----- Look if the index is in the list
            for ($j = $j_start; $j < sizeof($p_options[PCLZIP_OPT_BY_INDEX]) && !$v_extract; $j++) {

              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
              if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] && $i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {

                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
                $v_extract = true;
              }
              if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {

                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
                $j_start = $j + 1;
              }
              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) {

                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
                break;
              }
            }
          }
          else {

            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
            $v_extract = true;
          }
        }
      }
    }

    // ----- Check compression method
    if ($v_extract && ($v_header['compression'] != 8 && $v_header['compression'] != 0)) {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")");
      $v_header['status'] = 'unsupported_compression';

      // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
      if (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]) && $p_options[PCLZIP_OPT_STOP_ON_ERROR] === true) {

        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
        $this
          ->privSwapBackMagicQuotes();
        PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, "Filename '" . $v_header['stored_filename'] . "' is " . "compressed by an unsupported compression " . "method (" . $v_header['compression'] . ") ");

        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
        return PclZip::errorCode();
      }
    }

    // ----- Check encrypted files
    if ($v_extract && ($v_header['flag'] & 1) == 1) {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption");
      $v_header['status'] = 'unsupported_encryption';

      // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
      if (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]) && $p_options[PCLZIP_OPT_STOP_ON_ERROR] === true) {

        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
        $this
          ->privSwapBackMagicQuotes();
        PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, "Unsupported encryption for " . " filename '" . $v_header['stored_filename'] . "'");

        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
        return PclZip::errorCode();
      }
    }

    // ----- Look for real extraction
    if ($v_extract && $v_header['status'] != 'ok') {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract");
      $v_result = $this
        ->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++]);
      if ($v_result != 1) {
        $this
          ->privCloseFd();
        $this
          ->privSwapBackMagicQuotes();

        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
        return $v_result;
      }
      $v_extract = false;
    }

    // ----- Look for real extraction
    if ($v_extract) {

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");

      // ----- Go to the file position

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
      @rewind($this->zip_fd);

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
      if (@fseek($this->zip_fd, $v_header['offset'])) {

        // ----- Close the zip file
        $this
          ->privCloseFd();
        $this
          ->privSwapBackMagicQuotes();

        // ----- Error log
        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');

        // ----- Return

        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
        return PclZip::errorCode();
      }

      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");

      // ----- Look for extraction as string
      if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {

        // ----- Extracting the file
        $v_result1 = $this
          ->privExtractFileAsString($v_header, $v_string);
        if ($v_result1 < 1) {
          $this
            ->privCloseFd();
          $this
            ->privSwapBackMagicQuotes();

          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
          return $v_result1;
        }

        // ----- Get the only interesting attributes
        if (($v_result = $this
          ->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) {

          // ----- Close the zip file
          $this
            ->privCloseFd();
          $this
            ->privSwapBackMagicQuotes();

          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
          return $v_result;
        }

        // ----- Set the file content
        $p_file_list[$v_nb_extracted]['content'] = $v_string;

        // ----- Next extracted file
        $v_nb_extracted++;

        // ----- Look for user callback abort
        if ($v_result1 == 2) {
          break;
        }
      }
      elseif (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]) && $p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]) {

        // ----- Extracting the file in standard output
        $v_result1 = $this
          ->privExtractFileInOutput($v_header, $p_options);
        if ($v_result1 < 1) {
          $this
            ->privCloseFd();
          $this
            ->privSwapBackMagicQuotes();

          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
          return $v_result1;
        }

        // ----- Get the only interesting attributes
        if (($v_result = $this
          ->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
          $this
            ->privCloseFd();
          $this
            ->privSwapBackMagicQuotes();

          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
          return $v_result;
        }

        // ----- Look for user callback abort
        if ($v_result1 == 2) {
          break;
        }
      }
      else {

        // ----- Extracting the file
        $v_result1 = $this
          ->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options);
        if ($v_result1 < 1) {
          $this
            ->privCloseFd();
          $this
            ->privSwapBackMagicQuotes();

          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
          return $v_result1;
        }

        // ----- Get the only interesting attributes
        if (($v_result = $this
          ->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {

          // ----- Close the zip file
          $this
            ->privCloseFd();
          $this
            ->privSwapBackMagicQuotes();

          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
          return $v_result;
        }

        // ----- Look for user callback abort
        if ($v_result1 == 2) {
          break;
        }
      }
    }
  }

  // ----- Close the zip file
  $this
    ->privCloseFd();
  $this
    ->privSwapBackMagicQuotes();

  // ----- Return

  //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  return $v_result;
}