Skip to content

Commit fcbae16

Browse files
committed
Merge branch 'development' into release
2 parents 7c3a4c7 + 07ec880 commit fcbae16

File tree

132 files changed

+376
-97
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+376
-97
lines changed

.github/translators.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,5 @@ Tahsin Ahmed (tahsinahmed2012) :: Bengali
519519
bojan_che :: Serbian (Cyrillic)
520520
setiawan setiawan (culture.setiawan) :: Indonesian
521521
Donald Mac Kenzie (kiuman) :: Norwegian Bokmal
522+
Gabriel Silver (GabrielBSilver) :: Hebrew
523+
Tomas Darius Davainis (Tomasdd) :: Lithuanian

app/Exports/ZipExports/ZipExportReader.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ public function readData(): array
5858
{
5959
$this->open();
6060

61+
$info = $this->zip->statName('data.json');
62+
if ($info === false) {
63+
throw new ZipExportException(trans('errors.import_zip_cant_decode_data'));
64+
}
65+
66+
$maxSize = max(intval(config()->get('app.upload_limit')), 1) * 1000000;
67+
if ($info['size'] > $maxSize) {
68+
throw new ZipExportException(trans('errors.import_zip_data_too_large'));
69+
}
70+
6171
// Validate json data exists, including metadata
6272
$jsonData = $this->zip->getFromName('data.json') ?: '';
6373
$importData = json_decode($jsonData, true);
@@ -73,6 +83,17 @@ public function fileExists(string $fileName): bool
7383
return $this->zip->statName("files/{$fileName}") !== false;
7484
}
7585

86+
public function fileWithinSizeLimit(string $fileName): bool
87+
{
88+
$fileInfo = $this->zip->statName("files/{$fileName}");
89+
if ($fileInfo === false) {
90+
return false;
91+
}
92+
93+
$maxSize = max(intval(config()->get('app.upload_limit')), 1) * 1000000;
94+
return $fileInfo['size'] <= $maxSize;
95+
}
96+
7697
/**
7798
* @return false|resource
7899
*/

app/Exports/ZipExports/ZipFileReferenceRule.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ public function __construct(
1313
) {
1414
}
1515

16-
1716
/**
1817
* @inheritDoc
1918
*/
@@ -23,6 +22,13 @@ public function validate(string $attribute, mixed $value, Closure $fail): void
2322
$fail('validation.zip_file')->translate();
2423
}
2524

25+
if (!$this->context->zipReader->fileWithinSizeLimit($value)) {
26+
$fail('validation.zip_file_size')->translate([
27+
'attribute' => $value,
28+
'size' => config('app.upload_limit'),
29+
]);
30+
}
31+
2632
if (!empty($this->acceptedMimes)) {
2733
$fileMime = $this->context->zipReader->sniffFileMime($value);
2834
if (!in_array($fileMime, $this->acceptedMimes)) {

app/Exports/ZipExports/ZipImportRunner.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ protected function exportTagsToInputArray(array $exportTags): array
265265

266266
protected function zipFileToUploadedFile(string $fileName, ZipExportReader $reader): UploadedFile
267267
{
268+
if (!$reader->fileWithinSizeLimit($fileName)) {
269+
throw new ZipImportException([
270+
"File $fileName exceeds app upload limit."
271+
]);
272+
}
273+
268274
$tempPath = tempnam(sys_get_temp_dir(), 'bszipextract');
269275
$fileStream = $reader->streamFile($fileName);
270276
$tempStream = fopen($tempPath, 'wb');

app/Search/SearchController.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ public function searchForSelector(Request $request, QueryPopular $queryPopular)
7878

7979
// Search for entities otherwise show most popular
8080
if ($searchTerm !== false) {
81-
$searchTerm .= ' {type:' . implode('|', $entityTypes) . '}';
82-
$entities = $this->searchRunner->searchEntities(SearchOptions::fromString($searchTerm), 'all', 1, 20)['results'];
81+
$options = SearchOptions::fromString($searchTerm);
82+
$options->setFilter('type', implode('|', $entityTypes));
83+
$entities = $this->searchRunner->searchEntities($options, 'all', 1, 20)['results'];
8384
} else {
8485
$entities = $queryPopular->run(20, 0, $entityTypes);
8586
}

app/Search/SearchOptionSet.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,12 @@ public function nonNegated(): self
8282
$values = array_values(array_filter($this->options, fn (SearchOption $option) => !$option->negated));
8383
return new self($values);
8484
}
85+
86+
/**
87+
* @return self<T>
88+
*/
89+
public function limit(int $limit): self
90+
{
91+
return new self(array_slice(array_values($this->options), 0, $limit));
92+
}
8593
}

app/Search/SearchOptions.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public static function fromString(string $search): self
3535
{
3636
$instance = new self();
3737
$instance->addOptionsFromString($search);
38+
$instance->limitOptions();
3839
return $instance;
3940
}
4041

@@ -87,6 +88,8 @@ public static function fromRequest(Request $request): self
8788
$instance->filters = $instance->filters->merge($extras->filters);
8889
}
8990

91+
$instance->limitOptions();
92+
9093
return $instance;
9194
}
9295

@@ -147,6 +150,25 @@ protected function addOptionsFromString(string $searchString): void
147150
$this->filters = $this->filters->merge(new SearchOptionSet($terms['filters']));
148151
}
149152

153+
/**
154+
* Limit the amount of search options to reasonable levels.
155+
* Provides higher limits to logged-in users since that signals a slightly
156+
* higher level of trust.
157+
*/
158+
protected function limitOptions(): void
159+
{
160+
$userLoggedIn = !user()->isGuest();
161+
$searchLimit = $userLoggedIn ? 10 : 5;
162+
$exactLimit = $userLoggedIn ? 4 : 2;
163+
$tagLimit = $userLoggedIn ? 8 : 4;
164+
$filterLimit = $userLoggedIn ? 10 : 5;
165+
166+
$this->searches = $this->searches->limit($searchLimit);
167+
$this->exacts = $this->exacts->limit($exactLimit);
168+
$this->tags = $this->tags->limit($tagLimit);
169+
$this->filters = $this->filters->limit($filterLimit);
170+
}
171+
150172
/**
151173
* Decode backslash escaping within the input string.
152174
*/

composer.lock

Lines changed: 32 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lang/ar/errors.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
'import_zip_cant_read' => 'لم أتمكن من قراءة المِلَفّ المضغوط -ZIP-.',
110110
'import_zip_cant_decode_data' => 'لم نتمكن من العثور على محتوى المِلَفّ المضغوط data.json وفك تشفيره.',
111111
'import_zip_no_data' => 'لا تتضمن بيانات المِلَفّ المضغوط أي محتوى متوقع للكتاب أو الفصل أو الصفحة.',
112+
'import_zip_data_too_large' => 'ZIP data.json content exceeds the configured application maximum upload size.',
112113
'import_validation_failed' => 'فشل التحقق من صحة استيراد المِلَفّ المضغوط بسبب الأخطاء التالية:',
113114
'import_zip_failed_notification' => 'فشل استيراد المِلَفّ المضغوط.',
114115
'import_perms_books' => 'أنت تفتقر إلى الصلاحيات المطلوبة لإنشاء الكتب.',

lang/ar/validation.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
'uploaded' => 'تعذر تحميل الملف. قد لا يقبل الخادم ملفات بهذا الحجم.',
107107

108108
'zip_file' => ':attribute بحاجة إلى الرجوع إلى مِلَفّ داخل المِلَفّ المضغوط.',
109+
'zip_file_size' => 'The file :attribute must not exceed :size MB.',
109110
'zip_file_mime' => ':attribute بحاجة إلى الإشارة إلى مِلَفّ من نوع :validTypes، وجدت :foundType.',
110111
'zip_model_expected' => 'عنصر البيانات المتوقع ولكن ":type" تم العثور عليه.',
111112
'zip_unique' => 'يجب أن يكون :attribute فريداً لنوع الكائن داخل المِلَفّ المضغوط.',

0 commit comments

Comments
 (0)