From 9771a55837bb2c151c7e6bfd178d931a09d621fa Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Thu, 20 Oct 2022 22:26:24 +0200 Subject: [PATCH 1/3] Create filter for folder name Signed-off-by: Christian Wolf --- lib/Helper/FileSystem/RecipeNameHelper.php | 44 +++++++++++++++++++ .../FileSystem/RecipeNameHelperTest.php | 44 +++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 lib/Helper/FileSystem/RecipeNameHelper.php create mode 100644 tests/Unit/Helper/FileSystem/RecipeNameHelperTest.php diff --git a/lib/Helper/FileSystem/RecipeNameHelper.php b/lib/Helper/FileSystem/RecipeNameHelper.php new file mode 100644 index 000000000..71de5b492 --- /dev/null +++ b/lib/Helper/FileSystem/RecipeNameHelper.php @@ -0,0 +1,44 @@ +l = $l; + $this->logger = $logger; + } + + /** + * Replace the name of a recipe such that no special chars are present anymore. + * + * Additionally, the file name is truncated to 100 chars. + * + * @param string $recipeName The original recipe name + * @return string The cleaned recipe name + */ + public function getFolderName(string $recipeName): string { + $pattern = '/[\\/:?!"\\\\\'|&^#]/'; + $recipeName = preg_replace($pattern, '_', $recipeName); + + if (strlen($recipeName) > 100) { + $recipeName = substr($recipeName, 0, 97) . '...'; + } + + return $recipeName; + } +} diff --git a/tests/Unit/Helper/FileSystem/RecipeNameHelperTest.php b/tests/Unit/Helper/FileSystem/RecipeNameHelperTest.php new file mode 100644 index 000000000..f3e45cec5 --- /dev/null +++ b/tests/Unit/Helper/FileSystem/RecipeNameHelperTest.php @@ -0,0 +1,44 @@ +createStub(IL10N::class); + $l->method('t')->willReturnArgument(0); + $logger = $this->createStub(LoggerInterface::class); + + $this->dut = new RecipeNameHelper($l, $logger); + } + + public function dpGetFolderName() { + $tenChars = 'abcdefghij'; + $ninetyChars = str_repeat($tenChars, 9); + + return [ + 'short name' => ['recipe name', 'recipe name'], + '95 chars' => ["${ninetyChars}12345", "${ninetyChars}12345"], + '99 chars' => ["${ninetyChars}123456789", "${ninetyChars}123456789"], + '100 chars' => ["${ninetyChars}1234567890", "${ninetyChars}1234567890"], + '101 chars' => ["${ninetyChars}12345678901", "${ninetyChars}1234567..."], + '102 chars' => ["${ninetyChars}123456789012", "${ninetyChars}1234567..."], + '105 chars' => ["${ninetyChars}123456789012345", "${ninetyChars}1234567..."], + 'special chars' => ['a/b:c?d!e"f|g\\h\'i^j&k#l', 'a_b_c_d_e_f_g_h_i_j_k_l'], + ]; + } + + /** @dataProvider dpGetFolderName */ + public function testGetFolderName($recipeName, $expected) { + $this->assertEquals($expected, $this->dut->getFolderName($recipeName)); + } +} From d0ee7a91d7970ee47d4bc6794e552253b430d2a9 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Thu, 20 Oct 2022 22:26:52 +0200 Subject: [PATCH 2/3] Activate filter for folder renaming Signed-off-by: Christian Wolf --- lib/Service/RecipeService.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/Service/RecipeService.php b/lib/Service/RecipeService.php index d343e69e1..d4020bb56 100755 --- a/lib/Service/RecipeService.php +++ b/lib/Service/RecipeService.php @@ -20,6 +20,7 @@ use OCA\Cookbook\Helper\UserFolderHelper; use OCA\Cookbook\Exception\HtmlParsingException; use OCA\Cookbook\Exception\ImportException; +use OCA\Cookbook\Helper\FileSystem\RecipeNameHelper; use OCA\Cookbook\Helper\Filter\JSONFilter; /** @@ -57,6 +58,8 @@ class RecipeService { * @var ImageService */ private $imageService; + /** @var RecipeNameHelper */ + private $recipeNameHelper; /** @var JSONFilter */ private $jsonFilter; @@ -68,6 +71,7 @@ public function __construct( UserConfigHelper $userConfigHelper, UserFolderHelper $userFolder, ImageService $imageService, + RecipeNameHelper $recipeNameHelper, IL10N $il10n, LoggerInterface $logger, HtmlDownloadService $downloadService, @@ -82,6 +86,7 @@ public function __construct( $this->logger = $logger; $this->userConfigHelper = $userConfigHelper; $this->imageService = $imageService; + $this->recipeNameHelper = $recipeNameHelper; $this->htmlDownloadService = $downloadService; $this->recipeExtractionService = $extractionService; $this->jsonFilter = $jsonFilter; @@ -209,16 +214,18 @@ public function addRecipe($json, $importedHtml = null) { $user_folder = $this->userFolder->getFolder(); $recipe_folder = null; + $recipeFolderName = $this->recipeNameHelper->getFolderName($json['name']); + // Recipe already has an id, update it if (isset($json['id']) && $json['id']) { $recipe_folder = $user_folder->getById($json['id'])[0]; $old_path = $recipe_folder->getPath(); - $new_path = dirname($old_path) . '/' . $json['name']; + $new_path = dirname($old_path) . '/' . $recipeFolderName; // The recipe is being renamed, move the folder if ($old_path !== $new_path) { - if ($user_folder->nodeExists($json['name'])) { + if ($user_folder->nodeExists($recipeFolderName)) { throw new RecipeExistsException($this->il10n->t('Another recipe with that name already exists')); } @@ -229,11 +236,11 @@ public function addRecipe($json, $importedHtml = null) { } else { $json['dateCreated'] = $now; - if ($user_folder->nodeExists($json['name'])) { + if ($user_folder->nodeExists($recipeFolderName)) { throw new RecipeExistsException($this->il10n->t('Another recipe with that name already exists')); } - $recipe_folder = $user_folder->newFolder($json['name']); + $recipe_folder = $user_folder->newFolder($recipeFolderName); } // Write JSON file to disk From 6c489841e08aacae4cb1edc4f35d101571a35252 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Thu, 20 Oct 2022 22:30:33 +0200 Subject: [PATCH 3/3] Update changelog Signed-off-by: Christian Wolf --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c18fc39d..5338d4ab6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ [#1222](https://github.com/nextcloud/cookbook/pull/1222) @christianlupus - Add overlay when app navigation is open [1122](https://github.com/nextcloud/cookbook/pull/1122) @MarcelRobitaille +- Add filter to prevent special chars in folder names + [#1268](https://github.com/nextcloud/cookbook/pull/1268) @christianlupus ### Maintenance - Use the pre-built database images for MySQL and PostgreSQL tests