PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
← All changes | libraries/vendor/PhpSpreadsheet/Reader/Xls.php +93 -83 3.3.1 → 3.4 View file →
@@ -99,8 +99,14 @@
99 99 */
100 100 protected Worksheet $phpSheet;
101 101
102 102 /**
103 + * Cached sheet title for the current sheet being parsed.
104 + * Avoids repeated getTitle() calls in per-cell read filter checks.
105 + */
106 + protected string $phpSheetTitle = '';
107 +
108 + /**
103 109 * BIFF version.
104 110 */
105 111 protected int $version = 0;
106 112
@@ -155,9 +161,9 @@
155 161
156 162 /**
157 163 * Defined names.
158 164 *
159 - * @var array{isBuiltInName: int, name: string, formula: string, scope: int}
165 + * @var array<int, array{isBuiltInName: int, name: string, formula: string, scope: int}>
160 166 */
161 167 protected array $definedname;
162 168
163 169 /**
@@ -379,9 +385,9 @@
379 385 $ole = new OLERead();
380 386 // get excel data,
381 387 $ole->read($filename);
382 388 // Get workbook data: workbook stream + sheet streams
383 - $this->data = $ole->getStream($ole->wrkbook); // @phpstan-ignore-line
389 + $this->data = $ole->getStream($ole->wrkbook) ?? '';
384 390 // Get summary information data
385 391 $this->summaryInformation = $ole->getStream($ole->summaryInformation);
386 392 // Get additional document summary information data
387 393 $this->documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation);
@@ -1950,9 +1956,9 @@
1950 1956 /** @var string $recordData */
1951 1957 $nm = self::getInt4d($recordData, 4);
1952 1958 $pos += 4;
1953 1959
1954 - // look up limit position
1960 + // look up limit position (last splice offset where pos fits)
1955 1961 foreach ($spliceOffsets as $spliceOffset) {
1956 1962 // it can happen that the string is empty, therefore we need
1957 1963 // <= and not just <
1958 1964 if ($pos <= $spliceOffset) {
@@ -1998,9 +2004,9 @@
1998 2004
1999 2005 // expected byte length of character array if not split
2000 2006 $len = ($isCompressed) ? $numChars : $numChars * 2;
2001 2007
2002 - // look up limit position - Check it again to be sure that no error occurs when parsing SST structure
2008 + // look up limit position - find the first splice offset at or beyond current pos
2003 2009 $limitpos = null;
2004 2010 foreach ($spliceOffsets as $spliceOffset) {
2005 2011 // it can happen that the string is empty, therefore we need
2006 2012 // <= and not just <
@@ -2031,9 +2037,9 @@
2031 2037 $pos = $limitpos;
2032 2038
2033 2039 // keep reading the characters
2034 2040 while ($charsLeft > 0) {
2035 - // look up next limit position, in case the string span more than one continue record
2041 + // look up next limit position, in case the string spans more than one continue record
2036 2042 foreach ($spliceOffsets as $spliceOffset) {
2037 2043 if ($pos < $spliceOffset) {
2038 2044 $limitpos = $spliceOffset;
2039 2045
@@ -2063,27 +2069,21 @@
2063 2069 $len = min($charsLeft * 2, $limitpos - $pos);
2064 2070 $retstr .= substr($recordData, $pos, $len);
2065 2071 $charsLeft -= $len / 2;
2066 2072 $isCompressed = false;
2067 - } elseif (!$isCompressed && ($option == 0)) {
2073 + } elseif (!$isCompressed /*&& ($option == 0)*/) {
2068 2074 // 1st fragment uncompressed
2069 2075 // this fragment compressed
2070 - $len = min($charsLeft, $limitpos - $pos);
2071 - for ($j = 0; $j < $len; ++$j) {
2072 - $retstr .= $recordData[$pos + $j]
2073 - . chr(0);
2074 - }
2076 + $len = (int) min($charsLeft, $limitpos - $pos);
2077 + // Pad each byte with a null byte to expand to UTF-16LE
2078 + $retstr .= chunk_split((string) substr($recordData, $pos, $len), 1, "\x00");
2075 2079 $charsLeft -= $len;
2076 2080 $isCompressed = false;
2077 2081 } else {
2078 2082 // 1st fragment compressed
2079 2083 // this fragment uncompressed
2080 - $newstr = '';
2081 - $jMax = strlen($retstr);
2082 - for ($j = 0; $j < $jMax; ++$j) {
2083 - $newstr .= $retstr[$j] . chr(0);
2084 - }
2085 - $retstr = $newstr;
2084 + // Pad existing compressed string bytes with null bytes
2085 + $retstr = chunk_split($retstr, 1, "\x00");
2086 2086 /** @var int */
2087 2087 $len = min($charsLeft * 2, $limitpos - $pos);
2088 2088 $retstr .= substr($recordData, $pos, $len);
2089 2089 $charsLeft -= $len / 2;
@@ -2732,11 +2732,12 @@
2732 2732
2733 2733 // offset: 2; size: 2; index to column
2734 2734 $column = self::getUInt2d($recordData, 2);
2735 2735 $columnString = Coordinate::stringFromColumnIndex($column + 1);
2736 + $cellCoordinate = $columnString . ($row + 1);
2736 2737
2737 2738 // Read cell?
2738 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
2739 + if ($this->readFilter->readCell($columnString, $row + 1, $this->phpSheetTitle)) {
2739 2740 // offset: 4; size: 2; index to XF record
2740 2741 $xfIndex = self::getUInt2d($recordData, 4);
2741 2742
2742 2743 // offset: 6; size: 4; RK value
@@ -2742,12 +2743,12 @@
2742 2743 // offset: 6; size: 4; RK value
2743 2744 $rknum = self::getInt4d($recordData, 6);
2744 2745 $numValue = self::getIEEE754($rknum);
2745 2746
2746 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
2747 + $cell = $this->phpSheet->getCell($cellCoordinate);
2747 2748 if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
2748 2749 // add style information
2749 - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
2750 + $cell->setXfIndexNoUpdate($this->mapCellXfIndex[$xfIndex]);
2750 2751 }
2751 2752
2752 2753 // add cell
2753 2754 $cell->setValueExplicit($numValue, DataType::TYPE_NUMERIC);
@@ -2776,12 +2777,12 @@
2776 2777
2777 2778 // offset: 2; size: 2; index to column
2778 2779 $column = self::getUInt2d($recordData, 2);
2779 2780 $columnString = Coordinate::stringFromColumnIndex($column + 1);
2781 + $cellCoordinate = $columnString . ($row + 1);
2780 2782
2781 - $cell = null;
2782 2783 // Read cell?
2783 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
2784 + if ($this->readFilter->readCell($columnString, $row + 1, $this->phpSheetTitle)) {
2784 2785 // offset: 4; size: 2; index to XF record
2785 2786 $xfIndex = self::getUInt2d($recordData, 4);
2786 2787
2787 2788 // offset: 6; size: 4; index to SST record
@@ -2786,14 +2787,20 @@
2786 2787
2787 2788 // offset: 6; size: 4; index to SST record
2788 2789 $index = self::getInt4d($recordData, 6);
2789 2790
2791 + // cache SST entry locally to avoid repeated array lookups
2792 + $sstValue = $this->sst[$index]['value'];
2793 + $fmtRuns = $this->sst[$index]['fmtRuns'];
2794 +
2790 2795 // add cell
2791 - if (($fmtRuns = $this->sst[$index]['fmtRuns']) && !$this->readDataOnly) {
2796 + if ($fmtRuns && !$this->readDataOnly) {
2792 2797 // then we should treat as rich text
2793 2798 $richText = new RichText();
2794 2799 $charPos = 0;
2795 - $sstCount = count($this->sst[$index]['fmtRuns']);
2800 + $sstCount = count($fmtRuns);
2801 + $sstValueLength = StringHelper::countCharacters($sstValue);
2802 + $lastFontIndex = count($this->objFonts) - 1;
2796 2803 for ($i = 0; $i <= $sstCount; ++$i) {
2797 2804 /** @var mixed[][] $fmtRuns */
2798 2805 if (isset($fmtRuns[$i])) {
2799 2806 /** @var int[] */
@@ -2799,12 +2806,12 @@
2799 2806 /** @var int[] */
2800 2807 $temp = $fmtRuns[$i];
2801 2808 $temp = $temp['charPos'];
2802 2809 /** @var int $charPos */
2803 - $text = StringHelper::substring($this->sst[$index]['value'], $charPos, $temp - $charPos);
2810 + $text = StringHelper::substring($sstValue, $charPos, $temp - $charPos);
2804 2811 $charPos = $temp;
2805 2812 } else {
2806 - $text = StringHelper::substring($this->sst[$index]['value'], $charPos, StringHelper::countCharacters($this->sst[$index]['value']));
2813 + $text = StringHelper::substring($sstValue, $charPos, $sstValueLength);
2807 2814 }
2808 2815
2809 2816 if (StringHelper::countCharacters($text) > 0) {
2810 2817 if ($i == 0) { // first text run, no style
@@ -2821,10 +2828,10 @@
2821 2828 /** @var int */
2822 2829 $temp = $fmtRuns[$i - 1]['fontIndex'];
2823 2830 $fontIndex = $temp - 1;
2824 2831 }
2825 - if (array_key_exists($fontIndex, $this->objFonts) === false) {
2826 - $fontIndex = count($this->objFonts) - 1;
2832 + if ($fontIndex > $lastFontIndex) {
2833 + $fontIndex = $lastFontIndex;
2827 2834 }
2828 2835 $textRun->setFont(clone $this->objFonts[$fontIndex]);
2829 2836 }
2830 2837 }
@@ -2830,22 +2837,23 @@
2830 2837 }
2831 2838 }
2832 2839 }
2833 2840 if ($this->readEmptyCells || trim($richText->getPlainText()) !== '') {
2834 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
2841 + $cell = $this->phpSheet->getCell($cellCoordinate);
2842 + if (isset($this->mapCellXfIndex[$xfIndex])) {
2843 + $cell->setXfIndexNoUpdate($this->mapCellXfIndex[$xfIndex]);
2844 + }
2835 2845 $cell->setValueExplicit($richText, DataType::TYPE_STRING);
2836 2846 }
2837 2847 } else {
2838 - if ($this->readEmptyCells || trim($this->sst[$index]['value']) !== '') {
2839 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
2840 - $cell->setValueExplicit($this->sst[$index]['value'], DataType::TYPE_STRING);
2848 + if ($this->readEmptyCells || trim($sstValue) !== '') {
2849 + $cell = $this->phpSheet->getCell($cellCoordinate);
2850 + if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
2851 + $cell->setXfIndexNoUpdate($this->mapCellXfIndex[$xfIndex]);
2852 + }
2853 + $cell->setValueExplicit($sstValue, DataType::TYPE_STRING);
2841 2854 }
2842 2855 }
2843 -
2844 - if (!$this->readDataOnly && $cell !== null && isset($this->mapCellXfIndex[$xfIndex])) {
2845 - // add style information
2846 - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
2847 - }
2848 2856 }
2849 2857 }
2850 2858
2851 2859 /**
@@ -2876,22 +2884,23 @@
2876 2884
2877 2885 // offset within record data
2878 2886 $offset = 4;
2879 2887
2888 + $rowIndex = $row + 1;
2880 2889 for ($i = 1; $i <= $columns; ++$i) {
2881 2890 $columnString = Coordinate::stringFromColumnIndex($colFirst + $i);
2882 2891
2883 2892 // Read cell?
2884 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
2893 + if ($this->readFilter->readCell($columnString, $rowIndex, $this->phpSheetTitle)) {
2885 2894 // offset: var; size: 2; index to XF record
2886 2895 $xfIndex = self::getUInt2d($recordData, $offset);
2887 2896
2888 2897 // offset: var; size: 4; RK value
2889 2898 $numValue = self::getIEEE754(self::getInt4d($recordData, $offset + 2));
2890 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
2899 + $cell = $this->phpSheet->getCell($columnString . $rowIndex);
2891 2900 if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
2892 2901 // add style
2893 - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
2902 + $cell->setXfIndexNoUpdate($this->mapCellXfIndex[$xfIndex]);
2894 2903 }
2895 2904
2896 2905 // add cell value
2897 2906 $cell->setValueExplicit($numValue, DataType::TYPE_NUMERIC);
@@ -2922,20 +2931,21 @@
2922 2931
2923 2932 // offset: 2; size 2; index to column
2924 2933 $column = self::getUInt2d($recordData, 2);
2925 2934 $columnString = Coordinate::stringFromColumnIndex($column + 1);
2935 + $cellCoordinate = $columnString . ($row + 1);
2926 2936
2927 2937 // Read cell?
2928 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
2938 + if ($this->readFilter->readCell($columnString, $row + 1, $this->phpSheetTitle)) {
2929 2939 // offset 4; size: 2; index to XF record
2930 2940 $xfIndex = self::getUInt2d($recordData, 4);
2931 2941
2932 2942 $numValue = self::extractNumber((string) substr($recordData, 6, 8));
2933 2943
2934 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
2944 + $cell = $this->phpSheet->getCell($cellCoordinate);
2935 2945 if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
2936 2946 // add cell style
2937 - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
2947 + $cell->setXfIndexNoUpdate($this->mapCellXfIndex[$xfIndex]);
2938 2948 }
2939 2949
2940 2950 // add cell value
2941 2951 $cell->setValueExplicit($numValue, DataType::TYPE_NUMERIC);
@@ -2963,8 +2973,9 @@
2963 2973
2964 2974 // offset: 2; size: 2; col index
2965 2975 $column = self::getUInt2d($recordData, 2);
2966 2976 $columnString = Coordinate::stringFromColumnIndex($column + 1);
2977 + $cellCoordinate = $columnString . ($row + 1);
2967 2978
2968 2979 // offset: 20: size: variable; formula structure
2969 2980 $formulaStructure = (string) substr($recordData, 20);
2970 2981
@@ -2990,12 +3001,12 @@
2990 3001 $this->baseCell = Coordinate::stringFromColumnIndex($baseCol + 1) . ($baseRow + 1);
2991 3002 }
2992 3003
2993 3004 // Read cell?
2994 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
3005 + if ($this->readFilter->readCell($columnString, $row + 1, $this->phpSheetTitle)) {
2995 3006 if ($isPartOfSharedFormula) {
2996 3007 // formula is added to this cell after the sheet has been read
2997 - $this->sharedFormulaParts[$columnString . ($row + 1)] = $this->baseCell;
3008 + $this->sharedFormulaParts[$cellCoordinate] = $this->baseCell;
2998 3009 }
2999 3010
3000 3011 // offset: 16: size: 4; not used
3001 3012
@@ -3002,9 +3013,11 @@
3002 3013 // offset: 4; size: 2; XF index
3003 3014 $xfIndex = self::getUInt2d($recordData, 4);
3004 3015
3005 3016 // offset: 6; size: 8; result of the formula
3006 - if ((ord($recordData[6]) == 0) && (ord($recordData[12]) == 255) && (ord($recordData[13]) == 255)) {
3017 + $resultType = ord($recordData[6]);
3018 + $isSpecialResult = (ord($recordData[12]) == 255) && (ord($recordData[13]) == 255);
3019 + if (($resultType == 0) && $isSpecialResult) {
3007 3020 // String formula. Result follows in appended STRING record
3008 3021 $dataType = DataType::TYPE_STRING;
3009 3022
3010 3023 // read possible SHAREDFMLA record
@@ -3014,29 +3027,17 @@
3014 3027 }
3015 3028
3016 3029 // read STRING record
3017 3030 $value = $this->readString();
3018 - } elseif (
3019 - (ord($recordData[6]) == 1)
3020 - && (ord($recordData[12]) == 255)
3021 - && (ord($recordData[13]) == 255)
3022 - ) {
3031 + } elseif (($resultType == 1) && $isSpecialResult) {
3023 3032 // Boolean formula. Result is in +2; 0=false, 1=true
3024 3033 $dataType = DataType::TYPE_BOOL;
3025 3034 $value = (bool) ord($recordData[8]);
3026 - } elseif (
3027 - (ord($recordData[6]) == 2)
3028 - && (ord($recordData[12]) == 255)
3029 - && (ord($recordData[13]) == 255)
3030 - ) {
3035 + } elseif (($resultType == 2) && $isSpecialResult) {
3031 3036 // Error formula. Error code is in +2
3032 3037 $dataType = DataType::TYPE_ERROR;
3033 3038 $value = Xls\ErrorCode::lookup(ord($recordData[8]));
3034 - } elseif (
3035 - (ord($recordData[6]) == 3)
3036 - && (ord($recordData[12]) == 255)
3037 - && (ord($recordData[13]) == 255)
3038 - ) {
3039 + } elseif (($resultType == 3) && $isSpecialResult) {
3039 3040 // Formula result is a null string
3040 3041 $dataType = DataType::TYPE_NULL;
3041 3042 $value = '';
3042 3043 } else {
@@ -3044,12 +3045,14 @@
3044 3045 $dataType = DataType::TYPE_NUMERIC;
3045 3046 $value = self::extractNumber((string) substr($recordData, 6, 8));
3046 3047 }
3047 3048
3048 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
3049 + $cell = $this->phpSheet->getCell($cellCoordinate);
3049 3050 if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
3050 - // add cell style
3051 - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3051 + // add cell style; skipping the collection update is safe here
3052 + // because every path below ends in setCalculatedValue(), which
3053 + // performs the update
3054 + $cell->setXfIndexNoUpdate($this->mapCellXfIndex[$xfIndex]);
3052 3055 }
3053 3056
3054 3057 // store the formula
3055 3058 if (!$isPartOfSharedFormula) {
@@ -3154,11 +3157,12 @@
3154 3157
3155 3158 // offset: 2; size: 2; column index
3156 3159 $column = self::getUInt2d($recordData, 2);
3157 3160 $columnString = Coordinate::stringFromColumnIndex($column + 1);
3161 + $cellCoordinate = $columnString . ($row + 1);
3158 3162
3159 3163 // Read cell?
3160 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
3164 + if ($this->readFilter->readCell($columnString, $row + 1, $this->phpSheetTitle)) {
3161 3165 // offset: 4; size: 2; index to XF record
3162 3166 $xfIndex = self::getUInt2d($recordData, 4);
3163 3167
3164 3168 // offset: 6; size: 1; the boolean value or error value
@@ -3166,9 +3170,14 @@
3166 3170
3167 3171 // offset: 7; size: 1; 0=boolean; 1=error
3168 3172 $isError = ord($recordData[7]);
3169 3173
3170 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
3174 + $cell = $this->phpSheet->getCell($cellCoordinate);
3175 + if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
3176 + // add cell style; a value write does not follow on every path,
3177 + // so use the updating setter to guarantee persistence
3178 + $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3179 + }
3171 3180 switch ($isError) {
3172 3181 case 0: // boolean
3173 3182 $value = (bool) $boolErr;
3174 3183
@@ -3183,13 +3192,8 @@
3183 3192 $cell->setValueExplicit($value, DataType::TYPE_ERROR);
3184 3193
3185 3194 break;
3186 3195 }
3187 -
3188 - if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
3189 - // add cell style
3190 - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3191 - }
3192 3196 }
3193 3197 }
3194 3198
3195 3199 /**
@@ -3216,16 +3220,19 @@
3216 3220
3217 3221 // offset: 4; size: 2 x nc; list of indexes to XF records
3218 3222 // add style information
3219 3223 if (!$this->readDataOnly && $this->readEmptyCells) {
3224 + $rowIndex = $row + 1;
3220 3225 for ($i = 0; $i < $length / 2 - 3; ++$i) {
3221 3226 $columnString = Coordinate::stringFromColumnIndex($fc + $i + 1);
3222 3227
3223 3228 // Read cell?
3224 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
3229 + if ($this->readFilter->readCell($columnString, $rowIndex, $this->phpSheetTitle)) {
3225 3230 $xfIndex = self::getUInt2d($recordData, 4 + 2 * $i);
3226 3231 if (isset($this->mapCellXfIndex[$xfIndex])) {
3227 - $this->phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3232 + // blank cells never receive a value write, so use the
3233 + // updating setter to guarantee persistence
3234 + $this->phpSheet->getCell($columnString . $rowIndex)->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3228 3235 }
3229 3236 }
3230 3237 }
3231 3238 }
@@ -3256,11 +3263,12 @@
3256 3263
3257 3264 // offset: 2; size: 2; index to column
3258 3265 $column = self::getUInt2d($recordData, 2);
3259 3266 $columnString = Coordinate::stringFromColumnIndex($column + 1);
3267 + $cellCoordinate = $columnString . ($row + 1);
3260 3268
3261 3269 // Read cell?
3262 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
3270 + if ($this->readFilter->readCell($columnString, $row + 1, $this->phpSheetTitle)) {
3263 3271 // offset: 4; size: 2; XF index
3264 3272 $xfIndex = self::getUInt2d($recordData, 4);
3265 3273
3266 3274 // add cell value
@@ -3273,15 +3281,14 @@
3273 3281 $value = $string['value'];
3274 3282 }
3275 3283 /** @var string $value */
3276 3284 if ($this->readEmptyCells || trim($value) !== '') {
3277 - $cell = $this->phpSheet->getCell($columnString . ($row + 1));
3278 - $cell->setValueExplicit($value, DataType::TYPE_STRING);
3279 -
3285 + $cell = $this->phpSheet->getCell($cellCoordinate);
3280 3286 if (!$this->readDataOnly && isset($this->mapCellXfIndex[$xfIndex])) {
3281 3287 // add cell style
3282 - $cell->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3288 + $cell->setXfIndexNoUpdate($this->mapCellXfIndex[$xfIndex]);
3283 3289 }
3290 + $cell->setValueExplicit($value, DataType::TYPE_STRING);
3284 3291 }
3285 3292 }
3286 3293 }
3287 3294
@@ -3302,16 +3309,19 @@
3302 3309 // offset: 2; size: 2; col index
3303 3310 $col = self::getUInt2d($recordData, 2);
3304 3311 $columnString = Coordinate::stringFromColumnIndex($col + 1);
3305 3312
3313 + $rowIndex = $row + 1;
3314 +
3306 3315 // Read cell?
3307 - if ($this->getReadFilter()->readCell($columnString, $row + 1, $this->phpSheet->getTitle())) {
3316 + if ($this->readFilter->readCell($columnString, $rowIndex, $this->phpSheetTitle)) {
3308 3317 // offset: 4; size: 2; XF index
3309 3318 $xfIndex = self::getUInt2d($recordData, 4);
3310 3319
3311 - // add style information
3320 + // add style information; blank cells never receive a value write,
3321 + // so use the updating setter to guarantee persistence
3312 3322 if (!$this->readDataOnly && $this->readEmptyCells && isset($this->mapCellXfIndex[$xfIndex])) {
3313 - $this->phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3323 + $this->phpSheet->getCell($columnString . $rowIndex)->setXfIndex($this->mapCellXfIndex[$xfIndex]);
3314 3324 }
3315 3325 }
3316 3326 }
3317 3327
@@ -3611,9 +3621,9 @@
3611 3621 $rangeBoundaries = Coordinate::getRangeBoundaries($cellRangeAddress);
3612 3622 StringHelper::stringIncrement($rangeBoundaries[1][0]);
3613 3623 for ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; ++$row) {
3614 3624 for ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; StringHelper::stringIncrement($column)) {
3615 - if ($this->getReadFilter()->readCell($column, $row, $this->phpSheet->getTitle())) {
3625 + if ($this->readFilter->readCell($column, $row, $this->phpSheetTitle)) {
3616 3626 $includeCellRange = true;
3617 3627
3618 3628 break 2;
3619 3629 }
@@ -4659,9 +4669,9 @@
4659 4669 // offset: 1; size: 2; one-based index to definedname record
4660 4670 $definedNameIndex = self::getUInt2d($formulaData, 1) - 1;
4661 4671 // offset: 2; size: 2; not used
4662 4672 /** @var string[] */
4663 - $data = $this->definedname[$definedNameIndex]['name'] ?? ''; //* @phpstan-ignore-line
4673 + $data = $this->definedname[$definedNameIndex]['name'] ?? '';
4664 4674
4665 4675 break;
4666 4676 case 0x24: // single cell reference e.g. A5
4667 4677 case 0x44: