Skip to content

Commit b90d0ba

Browse files
committed
Validate site short name when entered in ACP
Signed-off-by: Matt Friedman <maf675@gmail.com>
1 parent 93cf693 commit b90d0ba

3 files changed

Lines changed: 100 additions & 35 deletions

File tree

event/listener.php

Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ public function acp_pwa_options($event)
160160

161161
$my_config_vars = [
162162
'legend_pwa_settings'=> 'PWA_SETTINGS',
163-
'pwa_short_name' => ['lang' => 'PWA_SHORT_NAME', 'validate' => 'string', 'type' => 'custom', 'function' => [$this, 'pwa_short_sitename'], 'explain' => true],
164-
'pwa_icon_small' => ['lang' => 'PWA_ICON_SMALL', 'validate' => 'pwa_options', 'type' => 'custom', 'function' => [$this, 'pwa_icon_name'], 'explain' => true],
165-
'pwa_icon_large' => ['lang' => 'PWA_ICON_LARGE', 'validate' => 'pwa_options', 'type' => 'custom', 'function' => [$this, 'pwa_icon_name'], 'explain' => true],
163+
'pwa_short_name' => ['lang' => 'PWA_SHORT_NAME', 'validate' => 'pwa_options:string', 'type' => 'custom', 'function' => [$this, 'pwa_short_sitename'], 'explain' => true],
164+
'pwa_icon_small' => ['lang' => 'PWA_ICON_SMALL', 'validate' => 'pwa_options:icons', 'type' => 'custom', 'function' => [$this, 'pwa_icon_name'], 'explain' => true],
165+
'pwa_icon_large' => ['lang' => 'PWA_ICON_LARGE', 'validate' => 'pwa_options:icons', 'type' => 'custom', 'function' => [$this, 'pwa_icon_name'], 'explain' => true],
166166
];
167167

168168
$event->update_subarray('display_vars', 'vars', phpbb_insert_config_array($event['display_vars']['vars'], $my_config_vars, ['before' => 'legend4']));
@@ -203,40 +203,79 @@ public function pwa_short_sitename($value, $key)
203203
*/
204204
public function validate_pwa_options($event)
205205
{
206-
// Ignore validation if icon fields are empty
207-
if ($event['config_definition']['validate'] !== 'pwa_options' || (empty($event['cfg_array']['pwa_icon_small']) && empty($event['cfg_array']['pwa_icon_large'])))
208-
{
209-
return;
210-
}
206+
$type = 0;
207+
$mode = 1;
211208

212-
$value = $event['cfg_array'][$event['config_name']];
209+
$validator = explode(':', $event['config_definition']['validate']);
213210

214-
// Don't allow empty values, if one icon is set, both must be set.
215-
if (empty($value))
211+
if ($validator[$type] !== 'pwa_options')
216212
{
217-
$this->add_error($event, 'PWA_IMAGE_NOT_PROVIDED', $this->language->lang(strtoupper($event['config_name'])));
218213
return;
219214
}
220215

221-
// Check if image is valid
222-
$image = $this->root_path . $this->config['icons_path'] . '/' . $value;
223-
$image_info = $this->imagesize->getImageSize($image);
224-
if ($image_info !== false)
225-
{
226-
if (($event['config_name'] === 'pwa_icon_small' && $image_info['width'] !== 192 && $image_info['height'] !== 192) ||
227-
($event['config_name'] === 'pwa_icon_large' && $image_info['width'] !== 512 && $image_info['height'] !== 512))
228-
{
229-
$this->add_error($event, 'PWA_ICON_SIZE_INVALID', $value);
230-
}
231-
232-
if ($image_info['type'] !== IMAGETYPE_PNG)
233-
{
234-
$this->add_error($event, 'PWA_ICON_MIME_INVALID', $value);
235-
}
236-
}
237-
else
216+
switch ($validator[$mode])
238217
{
239-
$this->add_error($event, 'PWA_IMAGE_INVALID', $value);
218+
case 'string':
219+
// Ignore validation if icon fields are empty
220+
if (empty($event['cfg_array']['pwa_short_name']))
221+
{
222+
return;
223+
}
224+
225+
$short_name = $event['cfg_array']['pwa_short_name'];
226+
227+
// Do not allow multibyte characters or emoji
228+
if (strlen($short_name) !== mb_strlen($short_name, 'UTF-8'))
229+
{
230+
$this->add_error($event, 'PWA_SHORT_NAME_INVALID');
231+
return;
232+
}
233+
234+
// Do not allow strings longer than 12 characters
235+
if (strlen($short_name) > 12)
236+
{
237+
$this->add_error($event, 'PWA_SHORT_NAME_INVALID');
238+
return;
239+
}
240+
break;
241+
242+
case 'icons':
243+
// Ignore validation if icon fields are empty
244+
if (empty($event['cfg_array']['pwa_icon_small']) && empty($event['cfg_array']['pwa_icon_large']))
245+
{
246+
return;
247+
}
248+
249+
$value = $event['cfg_array'][$event['config_name']];
250+
251+
// Don't allow empty values, if one icon is set, both must be set.
252+
if (empty($value))
253+
{
254+
$this->add_error($event, 'PWA_IMAGE_NOT_PROVIDED', $this->language->lang(strtoupper($event['config_name'])));
255+
return;
256+
}
257+
258+
// Check if image is valid
259+
$image = $this->root_path . $this->config['icons_path'] . '/' . $value;
260+
$image_info = $this->imagesize->getImageSize($image);
261+
if ($image_info !== false)
262+
{
263+
if (($event['config_name'] === 'pwa_icon_small' && $image_info['width'] !== 192 && $image_info['height'] !== 192) ||
264+
($event['config_name'] === 'pwa_icon_large' && $image_info['width'] !== 512 && $image_info['height'] !== 512))
265+
{
266+
$this->add_error($event, 'PWA_ICON_SIZE_INVALID', $value);
267+
}
268+
269+
if ($image_info['type'] !== IMAGETYPE_PNG)
270+
{
271+
$this->add_error($event, 'PWA_ICON_MIME_INVALID', $value);
272+
}
273+
}
274+
else
275+
{
276+
$this->add_error($event, 'PWA_IMAGE_INVALID', $value);
277+
}
278+
break;
240279
}
241280
}
242281

language/en/webpushnotifications_common_acp.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
'PWA_SETTINGS' => 'Progressive web application options',
4242
'PWA_SHORT_NAME' => 'Short site name',
4343
'PWA_SHORT_NAME_EXPLAIN' => 'Your site name in 12 characters or fewer, which may be used as a label for an icon on a mobile device’s home screen. (If this field is left empty, the first 12 characters of the <samp>Site name</samp> will be used.)',
44+
'PWA_SHORT_NAME_INVALID' => '“Short site name” contains illegal characters or exceeds the 12 character limit.',
4445
'PWA_ICON_SMALL' => 'Small mobile device icon',
4546
'PWA_ICON_SMALL_EXPLAIN' => 'File name of a 192px x 192px PNG image. This file must be uploaded to your board’s <samp>icons</samp> directory.',
4647
'PWA_ICON_LARGE' => 'Large mobile device icon',

tests/event/listener_test.php

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,43 +334,68 @@ public function validate_pwa_options_data()
334334
{
335335
return [
336336
[
337+
'pwa_options:icons',
337338
['pwa_icon_small' => '192.png', 'pwa_icon_large' => '512.png'],
338339
[],
339340
],
340341
[
342+
'pwa_options:icons',
341343
['pwa_icon_small' => '1.png', 'pwa_icon_large' => '512.png'],
342344
['PWA_ICON_SIZE_INVALID'],
343345
],
344346
[
347+
'pwa_options:icons',
345348
['pwa_icon_small' => '1.png', 'pwa_icon_large' => '12.png'],
346349
['PWA_ICON_SIZE_INVALID'],
347350
],
348351
[
352+
'pwa_options:icons',
349353
['pwa_icon_small' => '192.jpg', 'pwa_icon_large' => '512.gif'],
350354
['PWA_ICON_MIME_INVALID'],
351355
],
352356
[
357+
'pwa_options:icons',
353358
['pwa_icon_small' => '', 'pwa_icon_large' => ''],
354359
[],
355360
],
361+
[
362+
'pwa_options:string',
363+
['pwa_short_name' => 'foo'],
364+
[],
365+
],
366+
[
367+
'pwa_options:string',
368+
['pwa_short_name' => ''],
369+
[],
370+
],
371+
[
372+
'pwa_options:string',
373+
['pwa_short_name' => 'foo❤️'],
374+
['PWA_SHORT_NAME_INVALID'],
375+
],
376+
[
377+
'pwa_options:string',
378+
['pwa_short_name' => str_repeat('a', 50)],
379+
['PWA_SHORT_NAME_INVALID'],
380+
],
356381
];
357382
}
358383

359384
/**
360385
* @dataProvider validate_pwa_options_data
361386
*/
362-
public function test_validate_pwa_options($cfg_array, $expected_error)
387+
public function test_validate_pwa_options($validate, $cfg_array, $expected_error)
363388
{
364389
$this->config['icons_path'] = 'images/icons';
365390
$config_name = key($cfg_array);
366-
$config_definition = ['validate' => 'pwa_options'];
367-
$small_image = $cfg_array['pwa_icon_small'] ? explode('.', $cfg_array['pwa_icon_small']) : ['', ''];
368-
$large_image = $cfg_array['pwa_icon_large'] ? explode('.', $cfg_array['pwa_icon_large']) : ['', ''];
391+
$config_definition = ['validate' => $validate];
392+
$small_image = isset($cfg_array['pwa_icon_small']) ? explode('.', $cfg_array['pwa_icon_small']) : ['', ''];
393+
$large_image = isset($cfg_array['pwa_icon_large']) ? explode('.', $cfg_array['pwa_icon_large']) : ['', ''];
369394
$error = [];
370395

371396
$this->set_listener();
372397

373-
$this->imagesize->expects(self::any())
398+
$this->imagesize->expects(!empty($cfg_array['pwa_icon_small']) || !empty($cfg_array['pwa_icon_large']) ? self::once() : self::never())
374399
->method('getImageSize')
375400
->willReturnMap([
376401
[$this->root_path . $this->config['icons_path'] . '/', '', false],

0 commit comments

Comments
 (0)