Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions controller/main.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,10 @@ public function handle()
$this->packager->create_extension($this->data);
$filename = $this->packager->create_zip($this->data);

$response = new Response($filename);
$response = new Response(file_get_contents($filename));
$response->headers->set('Content-type', 'application/octet-stream');
$response->headers->set('Content-Disposition', 'attachment; filename="' . basename($filename) . '";');
$response->headers->set('Content-length', filesize($filename));
$response->sendHeaders();
$response->setContent(readfile($filename));

return $response;
}
Expand Down
69 changes: 67 additions & 2 deletions helper/validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,26 @@ public function validate_extension_name($value)
*/
public function validate_extension_display_name($value)
{
if ((string) $value !== '' && strpos($value, '"') === false)
if ((string) $value !== '')
{
return htmlspecialchars_decode($value, ENT_NOQUOTES);
return $this->validate_generated_string($value, 'SKELETON_INVALID_DISPLAY_NAME');
}

throw new runtime_exception($this->language->lang('SKELETON_INVALID_DISPLAY_NAME'));
}

/**
* Validate the extension description for insertion into composer.json
*
* @param string $value The value to validate
* @return string The valid value
* @throws runtime_exception
*/
public function validate_extension_description($value)
{
return $this->validate_generated_string($value, 'SKELETON_INVALID_EXTENSION_DESCRIPTION');
}

/**
* Validate and require the extension date/time
*
Expand Down Expand Up @@ -143,6 +155,8 @@ public function validate_vendor_name($value)
*/
public function validate_extension_homepage($value)
{
$value = $this->validate_generated_string($value, 'SKELETON_INVALID_EXTENSION_URL');

if ((string) $value !== '' && filter_var($value, FILTER_VALIDATE_URL) === false)
{
throw new runtime_exception($this->language->lang('SKELETON_INVALID_EXTENSION_URL'));
Expand All @@ -151,6 +165,18 @@ public function validate_extension_homepage($value)
return $value;
}

/**
* Validate the author name
*
* @param string $value The value to validate
* @return string The valid value
* @throws runtime_exception
*/
public function validate_author_name($value)
{
return $this->validate_generated_string($value, 'SKELETON_INVALID_AUTHOR_NAME');
}

/**
* Validate the author homepage URL
*
Expand All @@ -160,6 +186,8 @@ public function validate_extension_homepage($value)
*/
public function validate_author_homepage($value)
{
$value = $this->validate_generated_string($value, 'SKELETON_INVALID_AUTHOR_URL');

if ((string) $value !== '' && filter_var($value, FILTER_VALIDATE_URL) === false)
{
throw new runtime_exception($this->language->lang('SKELETON_INVALID_AUTHOR_URL'));
Expand All @@ -177,6 +205,8 @@ public function validate_author_homepage($value)
*/
public function validate_author_email($value)
{
$value = $this->validate_generated_string($value, 'SKELETON_INVALID_AUTHOR_EMAIL');

if ((string) $value !== '' && filter_var($value, FILTER_VALIDATE_EMAIL) === false)
{
throw new runtime_exception($this->language->lang('SKELETON_INVALID_AUTHOR_EMAIL'));
Expand All @@ -185,6 +215,18 @@ public function validate_author_email($value)
return $value;
}

/**
* Validate the author role
*
* @param string $value The value to validate
* @return string The valid value
* @throws runtime_exception
*/
public function validate_author_role($value)
{
return $this->validate_generated_string($value, 'SKELETON_INVALID_AUTHOR_ROLE');
}

/**
* Validate and require the phpBB minimum version
*
Expand Down Expand Up @@ -239,6 +281,29 @@ public function validate_php_version($value)

}

/**
* Validate a string inserted without escaping into generated files.
* Values must be safe inside a JSON string and must not contain a PHP comment
* terminator. Request values are HTML escaped, so inspect their decoded form
* and return safe characters without HTML entities.
*
* @param string $value The value to validate
* @param string $error Language key used for invalid input
* @return string The valid value
* @throws runtime_exception
*/
protected function validate_generated_string($value, $error)
{
$decoded_value = htmlspecialchars_decode((string) $value, ENT_QUOTES);

if (preg_match('/["\\\\\x00-\x1F]/', $decoded_value) || strpos($decoded_value, '*/') !== false)
{
throw new runtime_exception($this->language->lang($error));
}

return htmlspecialchars_decode((string) $value, ENT_NOQUOTES);
}

/**
* Version value check. Checks for values like:
* 1.0.0-RC1
Expand Down
4 changes: 3 additions & 1 deletion language/en/common.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
'SKELETON_QUESTION_EXTENSION_TIME_EXPLAIN' => 'YYYY-MM-DD, default: today',

'SKELETON_QUESTION_NUM_AUTHORS' => 'How many authors does the extension have',
'SKELETON_QUESTION_NUM_AUTHORS_EXPLAIN' => 'default: 1',

'SKELETON_QUESTION_AUTHOR_NAME' => 'Please enter the author name',
'SKELETON_QUESTION_AUTHOR_NAME_UI' => 'Author name',
Expand Down Expand Up @@ -148,8 +147,11 @@
'SKELETON_TITLE_COMPONENT_INFO' => 'Components',

'SKELETON_INVALID_AUTHOR_EMAIL' => 'An author email is invalid',
'SKELETON_INVALID_AUTHOR_NAME' => 'An author name is invalid',
'SKELETON_INVALID_AUTHOR_ROLE' => 'An author role is invalid',
'SKELETON_INVALID_AUTHOR_URL' => 'An author homepage URL is invalid',
'SKELETON_INVALID_DISPLAY_NAME' => 'The display name you provided is invalid',
'SKELETON_INVALID_EXTENSION_DESCRIPTION'=> 'The extension description you provided is invalid',
'SKELETON_INVALID_EXTENSION_TIME' => 'The extension date you provided is invalid',
'SKELETON_INVALID_EXTENSION_URL' => 'The extension homepage URL is invalid',
'SKELETON_INVALID_EXTENSION_VERSION'=> 'The extension version you provided is invalid',
Expand Down
4 changes: 4 additions & 0 deletions skeleton/console/command/sample.php.twig
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ class sample extends \phpbb\console\command\command
*
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
*
* @return int 0 if everything went fine, or an exit code
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln($this->user->lang('CLI_{{ EXTENSION.extension_name|upper }}_HELLO'));

return 0;
}
}
4 changes: 3 additions & 1 deletion skeleton/notification/type/sample.php.twig
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ class sample extends \phpbb\notification\type\base
*/
public function get_url()
{
return $this->helper->route('{{ EXTENSION.vendor_name }}_{{ EXTENSION.extension_name }}_controller', $this->get_data('{{ EXTENSION.extension_name|lower }}_sample_name'));
return $this->helper->route('{{ EXTENSION.vendor_name }}_{{ EXTENSION.extension_name }}_controller', [
'name' => $this->get_data('{{ EXTENSION.extension_name|lower }}_sample_name'),
]);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions tests/controller/main_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ public function test_submit_success()
$response = $this->get_controller($this->packager_mock)->handle();

$this->assertInstanceOf('\Symfony\Component\HttpFoundation\Response', $response);
$this->assertSame('', $response->getContent());
$this->assertSame('0', $response->headers->get('Content-length'));
}

public function test_submit_exception()
Expand Down
17 changes: 17 additions & 0 deletions tests/helper/validator_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public function valid_data(): array

['extension_display_name', 'Foo bar'],
['extension_display_name', 'Foo >bar\'s< & world'],
['extension_description', 'Foo >bar\'s< & world'],
['author_name', 'Foo Bar'],
['author_role', 'Developer'],

['extension_time', '0000-00-00'],

Expand Down Expand Up @@ -145,6 +148,13 @@ public function invalid_data(): array
['extension_display_name', '', 'SKELETON_INVALID_DISPLAY_NAME'],
['extension_display_name', null, 'SKELETON_INVALID_DISPLAY_NAME'],
['extension_display_name', 'Foo bar&quot;s world', 'SKELETON_INVALID_DISPLAY_NAME'],
['extension_display_name', 'Foo */ bar', 'SKELETON_INVALID_DISPLAY_NAME'],
['extension_display_name', 'Foo \\ bar', 'SKELETON_INVALID_DISPLAY_NAME'],

['extension_description', 'Foo &quot;bar&quot;', 'SKELETON_INVALID_EXTENSION_DESCRIPTION'],
['extension_description', 'Foo \\ bar', 'SKELETON_INVALID_EXTENSION_DESCRIPTION'],
['extension_description', "Foo\nbar", 'SKELETON_INVALID_EXTENSION_DESCRIPTION'],
['extension_description', 'Foo */ bar', 'SKELETON_INVALID_EXTENSION_DESCRIPTION'],

['extension_time', '00-00-0000', 'SKELETON_INVALID_EXTENSION_TIME'],
['extension_time', 'FOO', 'SKELETON_INVALID_EXTENSION_TIME'],
Expand Down Expand Up @@ -175,13 +185,20 @@ public function invalid_data(): array

['extension_homepage', 'www.web.com', 'SKELETON_INVALID_EXTENSION_URL'],
['extension_homepage', 'foo', 'SKELETON_INVALID_EXTENSION_URL'],
['extension_homepage', 'https://example.com/\\bad', 'SKELETON_INVALID_EXTENSION_URL'],

['author_name', 'Foo */ Bar', 'SKELETON_INVALID_AUTHOR_NAME'],
['author_name', 'Foo &quot;Bar&quot;', 'SKELETON_INVALID_AUTHOR_NAME'],
['author_role', 'Developer \\ Maintainer', 'SKELETON_INVALID_AUTHOR_ROLE'],

['author_homepage', 'www.web.com', 'SKELETON_INVALID_AUTHOR_URL'],
['author_homepage', 'foo', 'SKELETON_INVALID_AUTHOR_URL'],
['author_homepage', 'https://example.com/*/', 'SKELETON_INVALID_AUTHOR_URL'],

['author_email', 'mail.com', 'SKELETON_INVALID_AUTHOR_EMAIL'],
['author_email', 'user@mail', 'SKELETON_INVALID_AUTHOR_EMAIL'],
['author_email', 'foo', 'SKELETON_INVALID_AUTHOR_EMAIL'],
['author_email', 'foo&quot;@example.com', 'SKELETON_INVALID_AUTHOR_EMAIL'],

['phpbb_version_min', '', 'SKELETON_INVALID_PHPBB_MIN_VERSION'],
['phpbb_version_min', null, 'SKELETON_INVALID_PHPBB_MIN_VERSION'],
Expand Down