| @@ -49,10 +49,16 @@ | ||
| 49 | 49 | private Spreadsheet $spreadsheet; |
| 50 | 50 | |
| 51 | 51 | private ReferenceHelper $referenceHelper; |
| 52 | 52 | |
| 53 | - /** @var array{'dataType': string[]} */ | |
| 54 | - public static array $mappings = [ | |
| 53 | + /** | |
| 54 | + * @deprecated 5.10.0 No longer used, replaced by const which is not user-accessible. | |
| 55 | + * | |
| 56 | + * @var array{'dataType': string[]} | |
| 57 | + */ | |
| 58 | + public static array $mappings = self::MAPPINGS; | |
| 59 | + | |
| 60 | + private const MAPPINGS = [ | |
| 55 | 61 | 'dataType' => [ |
| 56 | 62 | '10' => DataType::TYPE_NULL, |
| 57 | 63 | '20' => DataType::TYPE_BOOL, |
| 58 | 64 | '30' => DataType::TYPE_NUMERIC, // Integer doesn't exist in Excel |
| @@ -63,8 +69,16 @@ | ||
| 63 | 69 | //'80': // Array |
| 64 | 70 | ], |
| 65 | 71 | ]; |
| 66 | 72 | |
| 73 | + protected int $maxLength; | |
| 74 | + | |
| 75 | + private const LENGTH_MULTIPLIER = [ | |
| 76 | + 'G' => 1024 * 1024 * 1024, | |
| 77 | + 'M' => 1024 * 1024, | |
| 78 | + 'K' => 1024, | |
| 79 | + ]; | |
| 80 | + | |
| 67 | 81 | /** |
| 68 | 82 | * Create a new Gnumeric. |
| 69 | 83 | */ |
| 70 | 84 | public function __construct() |
| @@ -71,10 +85,24 @@ | ||
| 71 | 85 | { |
| 72 | 86 | parent::__construct(); |
| 73 | 87 | $this->referenceHelper = ReferenceHelper::getInstance(); |
| 74 | 88 | $this->securityScanner = XmlScanner::getInstance($this); |
| 89 | + $limit = ini_get('memory_limit') ?: '128M'; | |
| 90 | + $limit = trim(str_replace('-1', '128M', $limit)); | |
| 91 | + $unit = strtoupper(substr($limit, -1)); | |
| 92 | + $limit = (int) $limit; | |
| 93 | + $multiplier = self::LENGTH_MULTIPLIER[$unit] ?? 1; | |
| 94 | + $limit *= $multiplier; | |
| 95 | + $this->maxLength = intdiv($limit, 4); | |
| 75 | 96 | } |
| 76 | 97 | |
| 98 | + public function setMaxLength(int $maxLength): self | |
| 99 | + { | |
| 100 | + $this->maxLength = $maxLength; | |
| 101 | + | |
| 102 | + return $this; | |
| 103 | + } | |
| 104 | + | |
| 77 | 105 | /** |
| 78 | 106 | * Can the current IReader read the file? |
| 79 | 107 | */ |
| 80 | 108 | public function canRead(string $filename): bool |
| @@ -191,9 +219,9 @@ | ||
| 191 | 219 | if ($contents !== false) { |
| 192 | 220 | if (str_starts_with($contents, "\x1f\x8b")) { |
| 193 | 221 | // Check if gzlib functions are available |
| 194 | 222 | if (function_exists('gzdecode')) { |
| 195 | - $contents = @gzdecode($contents); | |
| 223 | + $contents = @gzdecode($contents, $this->maxLength); | |
| 196 | 224 | if ($contents !== false) { |
| 197 | 225 | $data = $contents; |
| 198 | 226 | } |
| 199 | 227 | } |
| @@ -207,12 +235,16 @@ | ||
| 207 | 235 | |
| 208 | 236 | return $data; |
| 209 | 237 | } |
| 210 | 238 | |
| 211 | - /** @return mixed[] */ | |
| 239 | + /** | |
| 240 | + * @return mixed[] | |
| 241 | + * | |
| 242 | + * @internal | |
| 243 | + */ | |
| 212 | 244 | public static function gnumericMappings(): array |
| 213 | 245 | { |
| 214 | - return array_merge(self::$mappings, Styles::$mappings); | |
| 246 | + return array_merge(self::MAPPINGS, Styles::MAPPINGS); | |
| 215 | 247 | } |
| 216 | 248 | |
| 217 | 249 | private function processComments(SimpleXMLElement $sheet): void |
| 218 | 250 | { |
| @@ -262,10 +294,9 @@ | ||
| 262 | 294 | } |
| 263 | 295 | |
| 264 | 296 | $gFileData = $this->gzfileGetContents($filename); |
| 265 | 297 | |
| 266 | - /** @var XmlScanner */ | |
| 267 | - $securityScanner = $this->securityScanner; | |
| 298 | + $securityScanner = $this->getSecurityScannerOrThrow(); | |
| 268 | 299 | $xml2 = simplexml_load_string($securityScanner->scan($gFileData)); |
| 269 | 300 | $xml = self::testSimpleXml($xml2); |
| 270 | 301 | |
| 271 | 302 | $gnmXML = $xml->children(self::NAMESPACE_GNM); |
| @@ -313,9 +344,9 @@ | ||
| 313 | 344 | |
| 314 | 345 | $column = Coordinate::stringFromColumnIndex($column + 1); |
| 315 | 346 | |
| 316 | 347 | // Read cell? |
| 317 | - if (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) { | |
| 348 | + if (!$this->readFilter->readCell($column, $row, $worksheetName)) { | |
| 318 | 349 | continue; |
| 319 | 350 | } |
| 320 | 351 | |
| 321 | 352 | $this->loadCell($cell, $worksheetName, $cellAttributes, $column, $row); |
| @@ -591,10 +622,10 @@ | ||
| 591 | 622 | } |
| 592 | 623 | $type = DataType::TYPE_FORMULA; |
| 593 | 624 | } elseif ($isArrayFormula === false) { |
| 594 | 625 | $vtype = (string) $ValueType; |
| 595 | - if (array_key_exists($vtype, self::$mappings['dataType'])) { | |
| 596 | - $type = self::$mappings['dataType'][$vtype]; | |
| 626 | + if (array_key_exists($vtype, self::MAPPINGS['dataType'])) { | |
| 627 | + $type = self::MAPPINGS['dataType'][$vtype]; | |
| 597 | 628 | } |
| 598 | 629 | if ($vtype === '20') { // Boolean |
| 599 | 630 | $cell = $cell == 'TRUE'; |
| 600 | 631 | } |