Skip to content

Commit bc4397f

Browse files
committed
Refactor Transformation\WrapperController
Removes superglobals. Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
1 parent 48fe211 commit bc4397f

2 files changed

Lines changed: 136 additions & 230 deletions

File tree

‎libraries/classes/Controllers/Transformation/WrapperController.php‎

Lines changed: 136 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,28 @@
88
use PhpMyAdmin\Controllers\AbstractController;
99
use PhpMyAdmin\Core;
1010
use PhpMyAdmin\DatabaseInterface;
11+
use PhpMyAdmin\Dbal\DatabaseName;
12+
use PhpMyAdmin\Dbal\TableName;
1113
use PhpMyAdmin\DbTableExists;
14+
use PhpMyAdmin\Http\ServerRequest;
1215
use PhpMyAdmin\Image\ImageWrapper;
1316
use PhpMyAdmin\ResponseRenderer;
1417
use PhpMyAdmin\Template;
1518
use PhpMyAdmin\Transformations;
1619
use PhpMyAdmin\Util;
20+
use Webmozart\Assert\InvalidArgumentException;
1721

1822
use function __;
1923
use function htmlspecialchars;
20-
use function in_array;
2124
use function intval;
25+
use function is_numeric;
26+
use function is_string;
2227
use function round;
28+
use function sprintf;
29+
use function str_contains;
2330
use function str_replace;
24-
use function stripos;
25-
use function substr;
31+
use function str_starts_with;
32+
use function strtolower;
2633

2734
/**
2835
* Wrapper script for rendering transformations
@@ -51,194 +58,176 @@ public function __construct(
5158
$this->dbi = $dbi;
5259
}
5360

54-
public function __invoke(): void
61+
public function __invoke(ServerRequest $request): void
5562
{
5663
$this->response->getHeader()->setIsTransformationWrapper(true);
57-
$GLOBALS['cn'] = $GLOBALS['cn'] ?? null;
58-
$GLOBALS['transform_key'] = $GLOBALS['transform_key'] ?? null;
59-
$GLOBALS['request_params'] = $GLOBALS['request_params'] ?? null;
60-
$GLOBALS['size_params'] = $GLOBALS['size_params'] ?? null;
61-
$GLOBALS['where_clause'] = $GLOBALS['where_clause'] ?? null;
62-
$GLOBALS['row'] = $GLOBALS['row'] ?? null;
63-
64-
$GLOBALS['default_ct'] = $GLOBALS['default_ct'] ?? null;
65-
$GLOBALS['mime_map'] = $GLOBALS['mime_map'] ?? null;
66-
$GLOBALS['mime_options'] = $GLOBALS['mime_options'] ?? null;
67-
$GLOBALS['ct'] = $GLOBALS['ct'] ?? null;
68-
$GLOBALS['mime_type'] = $GLOBALS['mime_type'] ?? null;
69-
$GLOBALS['srcImage'] = $GLOBALS['srcImage'] ?? null;
70-
$GLOBALS['srcWidth'] = $GLOBALS['srcWidth'] ?? null;
71-
$GLOBALS['srcHeight'] = $GLOBALS['srcHeight'] ?? null;
72-
$GLOBALS['ratioWidth'] = $GLOBALS['ratioWidth'] ?? null;
73-
$GLOBALS['ratioHeight'] = $GLOBALS['ratioHeight'] ?? null;
74-
$GLOBALS['destWidth'] = $GLOBALS['destWidth'] ?? null;
75-
$GLOBALS['destHeight'] = $GLOBALS['destHeight'] ?? null;
76-
$GLOBALS['destImage'] = $GLOBALS['destImage'] ?? null;
7764

78-
$relationParameters = $this->relation->getRelationParameters();
79-
80-
DbTableExists::check($GLOBALS['db'], $GLOBALS['table'], true);
81-
82-
/**
83-
* Sets globals from $_REQUEST
84-
*/
85-
$GLOBALS['request_params'] = [
86-
'cn',
87-
'ct',
88-
'sql_query',
89-
'transform_key',
90-
'where_clause',
91-
];
92-
$GLOBALS['size_params'] = [
93-
'newHeight',
94-
'newWidth',
95-
];
96-
foreach ($GLOBALS['request_params'] as $one_request_param) {
97-
if (! isset($_REQUEST[$one_request_param])) {
98-
continue;
99-
}
100-
101-
if (in_array($one_request_param, $GLOBALS['size_params'])) {
102-
$GLOBALS[$one_request_param] = intval($_REQUEST[$one_request_param]);
103-
if ($GLOBALS[$one_request_param] > 2000) {
104-
$GLOBALS[$one_request_param] = 2000;
105-
}
106-
} else {
107-
$GLOBALS[$one_request_param] = $_REQUEST[$one_request_param];
108-
}
65+
try {
66+
$db = DatabaseName::fromValue($request->getParam('db'));
67+
$table = TableName::fromValue($request->getParam('table'));
68+
} catch (InvalidArgumentException $exception) {
69+
return;
10970
}
11071

111-
/**
112-
* Get the list of the fields of the current table
113-
*/
114-
$this->dbi->selectDb($GLOBALS['db']);
115-
if (isset($GLOBALS['where_clause'])) {
116-
if (! Core::checkSqlQuerySignature($GLOBALS['where_clause'], $_GET['where_clause_sign'] ?? '')) {
117-
/* l10n: In case a SQL query did not pass a security check */
118-
Core::fatalError(__('There is an issue with your request.'));
72+
DbTableExists::check($db->getName(), $table->getName(), true);
73+
$this->dbi->selectDb($db);
11974

120-
return;
121-
}
75+
$query = $this->getQuery($table, $request->getParam('where_clause'), $request->getParam('where_clause_sign'));
76+
if ($query === null) {
77+
/* l10n: In case a SQL query did not pass a security check */
78+
Core::fatalError(__('There is an issue with your request.'));
12279

123-
$result = $this->dbi->query(
124-
'SELECT * FROM ' . Util::backquote($GLOBALS['table'])
125-
. ' WHERE ' . $GLOBALS['where_clause'] . ';'
126-
);
127-
$GLOBALS['row'] = $result->fetchAssoc();
128-
} else {
129-
$result = $this->dbi->query(
130-
'SELECT * FROM ' . Util::backquote($GLOBALS['table']) . ' LIMIT 1;'
131-
);
132-
$GLOBALS['row'] = $result->fetchAssoc();
80+
return;
13381
}
13482

135-
// No row returned
136-
if ($GLOBALS['row'] === []) {
83+
$row = $this->dbi->query($query)->fetchAssoc();
84+
if ($row === []) {
13785
return;
13886
}
13987

140-
$GLOBALS['default_ct'] = 'application/octet-stream';
88+
$transformKey = $request->getParam('transform_key');
89+
if (
90+
! is_string($transformKey) || $transformKey === ''
91+
|| ! isset($row[$transformKey]) || $row[$transformKey] === ''
92+
) {
93+
return;
94+
}
14195

96+
$mediaTypeMap = [];
97+
$mediaTypeOptions = [];
98+
$relationParameters = $this->relation->getRelationParameters();
14299
if (
143100
$relationParameters->columnCommentsFeature !== null
144101
&& $relationParameters->browserTransformationFeature !== null
145102
) {
146-
$GLOBALS['mime_map'] = $this->transformations->getMime($GLOBALS['db'], $GLOBALS['table']) ?? [];
147-
148-
$GLOBALS['mime_options'] = $this->transformations->getOptions(
149-
$GLOBALS['mime_map'][$GLOBALS['transform_key']]['transformation_options'] ?? ''
103+
$mediaTypeMap = $this->transformations->getMime($db->getName(), $table->getName()) ?? [];
104+
$mediaTypeOptions = $this->transformations->getOptions(
105+
$mediaTypeMap[$transformKey]['transformation_options'] ?? ''
150106
);
151107

152-
foreach ($GLOBALS['mime_options'] as $option) {
153-
if (substr($option, 0, 10) !== '; charset=') {
108+
foreach ($mediaTypeOptions as $option) {
109+
if (! str_starts_with($option, '; charset=')) {
154110
continue;
155111
}
156112

157-
$GLOBALS['mime_options']['charset'] = $option;
113+
$mediaTypeOptions['charset'] = $option;
158114
}
159115
}
160116

161117
$this->response->getHeader()->sendHttpHeaders();
162118

163-
// [MIME]
164-
if (isset($GLOBALS['ct']) && ! empty($GLOBALS['ct'])) {
165-
$GLOBALS['mime_type'] = $GLOBALS['ct'];
119+
/** @psalm-suppress MixedAssignment */
120+
$contentType = $request->getParam('ct');
121+
if (is_string($contentType) && $contentType !== '') {
122+
$contentMediaType = $contentType;
166123
} else {
167-
$GLOBALS['mime_type'] = (! empty($GLOBALS['mime_map'][$GLOBALS['transform_key']]['mimetype'])
168-
? str_replace('_', '/', $GLOBALS['mime_map'][$GLOBALS['transform_key']]['mimetype'])
169-
: $GLOBALS['default_ct'])
170-
. ($GLOBALS['mime_options']['charset'] ?? '');
124+
$contentMediaType = 'application/octet-stream';
125+
if (! empty($mediaTypeMap[$transformKey]['mimetype'])) {
126+
$contentMediaType = str_replace('_', '/', $mediaTypeMap[$transformKey]['mimetype']);
127+
}
128+
129+
$contentMediaType .= $mediaTypeOptions['charset'] ?? '';
171130
}
172131

173-
Core::downloadHeader($GLOBALS['cn'] ?? '', $GLOBALS['mime_type']);
132+
/** @psalm-suppress MixedAssignment */
133+
$contentName = $request->getParam('cn');
134+
$contentName = is_string($contentName) ? $contentName : '';
174135

175-
if (! isset($_REQUEST['resize'])) {
176-
if (stripos($GLOBALS['mime_type'], 'html') === false) {
177-
echo $GLOBALS['row'][$GLOBALS['transform_key']];
178-
} else {
179-
echo htmlspecialchars($GLOBALS['row'][$GLOBALS['transform_key']]);
180-
}
181-
} else {
182-
// if image_*__inline.inc.php finds that we can resize,
183-
// it sets the resize parameter to jpeg or png
136+
Core::downloadHeader($contentName, $contentMediaType);
137+
138+
$resize = $request->getParam('resize');
139+
if ($resize !== 'jpeg' && $resize !== 'png') {
140+
if (str_contains(strtolower($contentMediaType), 'html')) {
141+
echo htmlspecialchars($row[$transformKey]);
184142

185-
$GLOBALS['srcImage'] = ImageWrapper::fromString($GLOBALS['row'][$GLOBALS['transform_key']]);
186-
if ($GLOBALS['srcImage'] === null) {
187143
return;
188144
}
189145

190-
$GLOBALS['srcWidth'] = $GLOBALS['srcImage']->width();
191-
$GLOBALS['srcHeight'] = $GLOBALS['srcImage']->height();
146+
echo $row[$transformKey];
192147

193-
// Check to see if the width > height or if width < height
194-
// if so adjust accordingly to make sure the image
195-
// stays smaller than the new width and new height
148+
return;
149+
}
196150

197-
$GLOBALS['ratioWidth'] = $GLOBALS['srcWidth'] / $_REQUEST['newWidth'];
198-
$GLOBALS['ratioHeight'] = $GLOBALS['srcHeight'] / $_REQUEST['newHeight'];
151+
$srcImage = ImageWrapper::fromString($row[$transformKey]);
152+
if ($srcImage === null) {
153+
return;
154+
}
199155

200-
if ($GLOBALS['ratioWidth'] < $GLOBALS['ratioHeight']) {
201-
$GLOBALS['destWidth'] = intval(round($GLOBALS['srcWidth'] / $GLOBALS['ratioHeight']));
202-
$GLOBALS['destHeight'] = intval($_REQUEST['newHeight']);
203-
} else {
204-
$GLOBALS['destWidth'] = intval($_REQUEST['newWidth']);
205-
$GLOBALS['destHeight'] = intval(round($GLOBALS['srcHeight'] / $GLOBALS['ratioWidth']));
206-
}
156+
$newHeight = $this->formatSize($request->getParam('newHeight'));
157+
$newWidth = $this->formatSize($request->getParam('newWidth'));
207158

208-
if ($_REQUEST['resize']) {
209-
$GLOBALS['destImage'] = ImageWrapper::create($GLOBALS['destWidth'], $GLOBALS['destHeight']);
210-
if ($GLOBALS['destImage'] === null) {
211-
$GLOBALS['srcImage']->destroy();
159+
$srcWidth = $srcImage->width();
160+
$srcHeight = $srcImage->height();
212161

213-
return;
214-
}
162+
$ratioWidth = $srcWidth / $newWidth;
163+
$ratioHeight = $srcHeight / $newHeight;
215164

216-
// ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0,
217-
// $destWidth, $destHeight, $srcWidth, $srcHeight);
218-
// better quality but slower:
219-
$GLOBALS['destImage']->copyResampled(
220-
$GLOBALS['srcImage'],
221-
0,
222-
0,
223-
0,
224-
0,
225-
$GLOBALS['destWidth'],
226-
$GLOBALS['destHeight'],
227-
$GLOBALS['srcWidth'],
228-
$GLOBALS['srcHeight']
229-
);
230-
if ($_REQUEST['resize'] === 'jpeg') {
231-
$GLOBALS['destImage']->jpeg(null, 75);
232-
}
165+
/**
166+
* Check to see if the width > height or if width < height
167+
* if so adjust accordingly to make sure the image
168+
* stays smaller than the new width and new height
169+
*/
170+
if ($ratioWidth < $ratioHeight) {
171+
$destWidth = intval(round($srcWidth / $ratioHeight));
172+
$destHeight = $newHeight;
173+
} else {
174+
$destWidth = $newWidth;
175+
$destHeight = intval(round($srcHeight / $ratioWidth));
176+
}
233177

234-
if ($_REQUEST['resize'] === 'png') {
235-
$GLOBALS['destImage']->png();
236-
}
178+
$destImage = ImageWrapper::create($destWidth, $destHeight);
179+
if ($destImage === null) {
180+
$srcImage->destroy();
237181

238-
$GLOBALS['destImage']->destroy();
239-
}
182+
return;
183+
}
240184

241-
$GLOBALS['srcImage']->destroy();
185+
$destImage->copyResampled($srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
186+
187+
if ($resize === 'jpeg') {
188+
$destImage->jpeg(null, 75);
189+
} else {
190+
$destImage->png();
242191
}
192+
193+
$destImage->destroy();
194+
$srcImage->destroy();
195+
}
196+
197+
/**
198+
* @param mixed $size
199+
*/
200+
private function formatSize($size): int
201+
{
202+
if (! is_numeric($size) || $size < 2) {
203+
return 1;
204+
}
205+
206+
if ($size >= 2000) {
207+
return 2000;
208+
}
209+
210+
return (int) $size;
211+
}
212+
213+
/**
214+
* @param mixed $whereClause
215+
* @param mixed $whereClauseSign
216+
*/
217+
private function getQuery(TableName $table, $whereClause, $whereClauseSign): ?string
218+
{
219+
if ($whereClause === null) {
220+
return sprintf('SELECT * FROM %s LIMIT 1;', Util::backquote($table));
221+
}
222+
223+
if (
224+
! is_string($whereClause) || $whereClause === ''
225+
|| ! is_string($whereClauseSign) || $whereClauseSign === ''
226+
|| ! Core::checkSqlQuerySignature($whereClause, $whereClauseSign)
227+
) {
228+
return null;
229+
}
230+
231+
return sprintf('SELECT * FROM %s WHERE %s;', Util::backquote($table), $whereClause);
243232
}
244233
}

0 commit comments

Comments
 (0)