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/Shared/OLE/ChainedBlockStream.php +55 -16 3.3.2 → 3.4 View file →
@@ -57,9 +57,9 @@
57 57 }
58 58
59 59 // 25 is length of "ole-chainedblockstream://"
60 60 parse_str((string) substr($path, 25), $this->params);
61 - if (!isset($this->params['oleInstanceId'], $this->params['blockId'], $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { //* @phpstan-ignore-line
61 + if (!isset($this->params['oleInstanceId'], $this->params['blockId'], $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) { //* @phpstan-ignore offsetAccess.nonOffsetAccessible (I don't know how to fix this)
62 62 if ($options & STREAM_REPORT_ERRORS) {
63 63 trigger_error('OLE stream not found', E_USER_WARNING);
64 64 }
65 65
@@ -64,37 +64,61 @@
64 64 }
65 65
66 66 return false;
67 67 }
68 - $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; //* @phpstan-ignore-line
69 - if (!($this->ole instanceof OLE)) { //* @phpstan-ignore-line
68 + $this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']]; //* @phpstan-ignore assign.propertyType (I don't know how to fix this)
69 + if (!($this->ole instanceof OLE)) { //* @phpstan-ignore instanceof.alwaysTrue (I don't know how to fix this)
70 70 throw new Exception('class is not OLE');
71 71 }
72 72
73 - $blockId = $this->params['blockId'];
73 + $blockId = (int) $this->params['blockId'];
74 + $size = isset($this->params['size']) ? (int) $this->params['size'] : null;
75 + $isRoot = isset($this->params['isRoot']) && $this->params['isRoot'] === '1';
74 76 $this->data = '';
75 - if (isset($this->params['size']) && $this->params['size'] < $this->ole->bigBlockThreshold && $blockId != $this->ole->root->startBlock) {
77 + if ($size !== null && $size < $this->ole->bigBlockThreshold && !$isRoot) {
76 78 // Block id refers to small blocks
77 - $rootPos = $this->ole->getBlockOffset((int) $this->ole->root->startBlock);
79 + $rootData = '';
80 + if ($this->ole->root->startBlock === null) {
81 + throw new Exception('Invalid OLE root mini-stream chain.');
82 + }
83 + $rootBlockId = (int) $this->ole->root->startBlock;
84 + $rootBlocks = [];
85 + while ($rootBlockId !== -2) {
86 + if (isset($rootBlocks[$rootBlockId], $this->ole->bbat[$rootBlockId])) {
87 + throw new Exception('Invalid OLE root mini-stream chain.');
88 + }
89 + $rootBlocks[$rootBlockId] = true;
90 + fseek($this->ole->_file_handle, $this->ole->getBlockOffset($rootBlockId));
91 + $rootData .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
92 + $rootBlockId = self::nextBlock($this->ole->bbat, $rootBlockId, 'Invalid OLE root mini-stream chain.');
93 + }
94 +
95 + $smallBlocks = [];
78 96 while ($blockId != -2) {
79 - /** @var int $blockId */
80 - $pos = $rootPos + $blockId * $this->ole->bigBlockSize;
81 - $blockId = $this->ole->sbat[$blockId];
82 - fseek($this->ole->_file_handle, $pos);
83 - $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
97 + if (isset($smallBlocks[$blockId], $this->ole->sbat[$blockId])) {
98 + throw new Exception('Invalid OLE mini-stream chain.');
99 + }
100 + $smallBlocks[$blockId] = true;
101 + $pos = $blockId * $this->ole->smallBlockSize;
102 + $this->data .= substr($rootData, $pos, $this->ole->smallBlockSize);
103 + $blockId = self::nextBlock($this->ole->sbat, $blockId, 'Invalid OLE mini-stream chain.');
84 104 }
85 105 } else {
86 106 // Block id refers to big blocks
107 + $bigBlocks = [];
87 108 while ($blockId != -2) {
88 - /** @var int $blockId */
109 + if (isset($bigBlocks[$blockId], $this->ole->bbat[$blockId])) {
110 + throw new Exception('Invalid OLE stream chain.');
111 + }
112 + $bigBlocks[$blockId] = true;
89 113 $pos = $this->ole->getBlockOffset($blockId);
90 114 fseek($this->ole->_file_handle, $pos);
91 115 $this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);
92 - $blockId = $this->ole->bbat[$blockId];
116 + $blockId = self::nextBlock($this->ole->bbat, $blockId, 'Invalid OLE stream chain.');
93 117 }
94 118 }
95 - if (isset($this->params['size'])) {
96 - $this->data = (string) substr($this->data, 0, $this->params['size']); //* @phpstan-ignore-line
119 + if ($size !== null) {
120 + $this->data = (string) substr($this->data, 0, $size);
97 121 }
98 122
99 123 if ($options & STREAM_USE_PATH) {
100 124 $openedPath = $path;
@@ -102,8 +126,19 @@
102 126
103 127 return true;
104 128 }
105 129
130 + /** @param mixed[] $allocationTable */
131 + private static function nextBlock(array $allocationTable, int $blockId, string $message): int
132 + {
133 + $nextBlockId = $allocationTable[$blockId] ?? null;
134 + if (!is_int($nextBlockId)) {
135 + throw new Exception($message);
136 + }
137 +
138 + return $nextBlockId;
139 + }
140 +
106 141 /**
107 142 * Implements support for fclose().
108 143 */
109 144 public function stream_close(): void // @codingStandardsIgnoreLine
@@ -150,8 +185,12 @@
150 185 }
151 186
152 187 /**
153 188 * Implements support for fseek().
189 + * Note that the first condition is always true, at least in
190 + * the unit test suite. One consequence is that Phpstan's
191 + * correct flagging of count($this->data) below is never
192 + * executed, and would fail should it be executed.
154 193 *
155 194 * @param int $offset byte offset
156 195 * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END
157 196 */
@@ -160,9 +199,9 @@
160 199 if ($whence == SEEK_SET && $offset >= 0) {
161 200 $this->pos = $offset;
162 201 } elseif ($whence == SEEK_CUR && -$offset <= $this->pos) {
163 202 $this->pos += $offset;
164 - } elseif ($whence == SEEK_END && -$offset <= count($this->data)) { // @phpstan-ignore-line
203 + } elseif ($whence == SEEK_END && -$offset <= count($this->data)) { // @phpstan-ignore argument.type (phpstan is correct - see docBlock above)
165 204 $this->pos = strlen($this->data) + $offset;
166 205 } else {
167 206 return false;
168 207 }