PathVerificationTest.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace Test\Files;
  8. use OC\Files\Storage\Local;
  9. use OC\Files\View;
  10. use OCP\Files\InvalidPathException;
  11. /**
  12. * Class PathVerificationTest
  13. *
  14. * @group DB
  15. *
  16. * @package Test\Files
  17. */
  18. class PathVerificationTest extends \Test\TestCase {
  19. /**
  20. * @var \OC\Files\View
  21. */
  22. private $view;
  23. protected function setUp(): void {
  24. parent::setUp();
  25. $this->view = new View();
  26. }
  27. public function testPathVerificationFileNameTooLong() {
  28. $this->expectException(\OCP\Files\InvalidPathException::class);
  29. $this->expectExceptionMessage('File name is too long');
  30. $fileName = str_repeat('a', 500);
  31. $this->view->verifyPath('', $fileName);
  32. }
  33. /**
  34. * @dataProvider providesEmptyFiles
  35. */
  36. public function testPathVerificationEmptyFileName($fileName) {
  37. $this->expectException(\OCP\Files\InvalidPathException::class);
  38. $this->expectExceptionMessage('Empty filename is not allowed');
  39. $this->view->verifyPath('', $fileName);
  40. }
  41. public function providesEmptyFiles() {
  42. return [
  43. [''],
  44. [' '],
  45. ];
  46. }
  47. /**
  48. * @dataProvider providesDotFiles
  49. */
  50. public function testPathVerificationDotFiles($fileName) {
  51. $this->expectException(\OCP\Files\InvalidPathException::class);
  52. $this->expectExceptionMessage('Dot files are not allowed');
  53. $this->view->verifyPath('', $fileName);
  54. }
  55. public function providesDotFiles() {
  56. return [
  57. ['.'],
  58. ['..'],
  59. [' .'],
  60. [' ..'],
  61. ['. '],
  62. ['.. '],
  63. [' . '],
  64. [' .. '],
  65. ];
  66. }
  67. /**
  68. * @dataProvider providesAstralPlane
  69. */
  70. public function testPathVerificationAstralPlane($fileName) {
  71. $connection = \OC::$server->getDatabaseConnection();
  72. if (!$connection->supports4ByteText()) {
  73. $this->expectException(InvalidPathException::class);
  74. $this->expectExceptionMessage('File name contains at least one invalid character');
  75. } else {
  76. $this->addToAssertionCount(1);
  77. }
  78. $this->view->verifyPath('', $fileName);
  79. }
  80. public function providesAstralPlane() {
  81. return [
  82. // this is the monkey emoji - http://en.wikipedia.org/w/index.php?title=%F0%9F%90%B5&redirect=no
  83. ['🐵'],
  84. ['🐵.txt'],
  85. ['txt.💩'],
  86. ['💩🐵.txt'],
  87. ['💩🐵'],
  88. ];
  89. }
  90. /**
  91. * @dataProvider providesInvalidCharsPosix
  92. */
  93. public function testPathVerificationInvalidCharsPosix($fileName) {
  94. $this->expectException(\OCP\Files\InvalidCharacterInPathException::class);
  95. $storage = new Local(['datadir' => '']);
  96. $fileName = " 123{$fileName}456 ";
  97. self::invokePrivate($storage, 'verifyPosixPath', [$fileName]);
  98. }
  99. public function providesInvalidCharsPosix() {
  100. return [
  101. [\chr(0)],
  102. [\chr(1)],
  103. [\chr(2)],
  104. [\chr(3)],
  105. [\chr(4)],
  106. [\chr(5)],
  107. [\chr(6)],
  108. [\chr(7)],
  109. [\chr(8)],
  110. [\chr(9)],
  111. [\chr(10)],
  112. [\chr(11)],
  113. [\chr(12)],
  114. [\chr(13)],
  115. [\chr(14)],
  116. [\chr(15)],
  117. [\chr(16)],
  118. [\chr(17)],
  119. [\chr(18)],
  120. [\chr(19)],
  121. [\chr(20)],
  122. [\chr(21)],
  123. [\chr(22)],
  124. [\chr(23)],
  125. [\chr(24)],
  126. [\chr(25)],
  127. [\chr(26)],
  128. [\chr(27)],
  129. [\chr(28)],
  130. [\chr(29)],
  131. [\chr(30)],
  132. [\chr(31)],
  133. ['/'],
  134. ['\\'],
  135. ];
  136. }
  137. /**
  138. * @dataProvider providesValidPosixPaths
  139. */
  140. public function testPathVerificationValidPaths($fileName) {
  141. $storage = new Local(['datadir' => '']);
  142. self::invokePrivate($storage, 'verifyPosixPath', [$fileName]);
  143. // nothing thrown
  144. $this->addToAssertionCount(1);
  145. }
  146. public function providesValidPosixPaths() {
  147. return [
  148. ['simple'],
  149. ['simple.txt'],
  150. ['\''],
  151. ['`'],
  152. ['%'],
  153. ['()'],
  154. ['[]'],
  155. ['!'],
  156. ['$'],
  157. ['_'],
  158. ];
  159. }
  160. }