1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2024-10-30 07:32:39 +01:00

Ensured base64 images are read from image upload folder

Also removed unused storage systems and updated testing.
This commit is contained in:
Dan Brown 2020-12-06 15:34:18 +00:00
parent 8911e3f441
commit 884664bfe9
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
3 changed files with 37 additions and 26 deletions

View File

@ -42,13 +42,6 @@ return [
'root' => storage_path(), 'root' => storage_path(),
], ],
'ftp' => [
'driver' => 'ftp',
'host' => 'ftp.example.com',
'username' => 'your-username',
'password' => 'your-password',
],
's3' => [ 's3' => [
'driver' => 's3', 'driver' => 's3',
'key' => env('STORAGE_S3_KEY', 'your-key'), 'key' => env('STORAGE_S3_KEY', 'your-key'),
@ -59,16 +52,6 @@ return [
'use_path_style_endpoint' => env('STORAGE_S3_ENDPOINT', null) !== null, 'use_path_style_endpoint' => env('STORAGE_S3_ENDPOINT', null) !== null,
], ],
'rackspace' => [
'driver' => 'rackspace',
'username' => 'your-username',
'key' => 'your-key',
'container' => 'your-container',
'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
'region' => 'IAD',
'url_type' => 'publicURL',
],
], ],
]; ];

View File

@ -450,28 +450,32 @@ class ImageService
/** /**
* Get a storage path for the given image URL. * Get a storage path for the given image URL.
* Ensures the path will start with "uploads/images".
* Returns null if the url cannot be resolved to a local URL. * Returns null if the url cannot be resolved to a local URL.
*/ */
private function imageUrlToStoragePath(string $url): ?string private function imageUrlToStoragePath(string $url): ?string
{ {
$url = trim($url); $url = ltrim(trim($url), '/');
// Handle potential relative paths // Handle potential relative paths
$isRelative = strpos($url, 'http') !== 0; $isRelative = strpos($url, 'http') !== 0;
if ($isRelative) { if ($isRelative) {
return trim($url, '/'); if (strpos(strtolower($url), 'uploads/images') === 0) {
return trim($url, '/');
}
return null;
} }
// Handle local images based on paths on the same domain // Handle local images based on paths on the same domain
$potentialHostPaths = [ $potentialHostPaths = [
url('/'), url('uploads/images/'),
$this->getPublicUrl('/'), $this->getPublicUrl('/uploads/images/'),
]; ];
foreach ($potentialHostPaths as $potentialBasePath) { foreach ($potentialHostPaths as $potentialBasePath) {
$potentialBasePath = strtolower($potentialBasePath); $potentialBasePath = strtolower($potentialBasePath);
if (strpos(strtolower($url), $potentialBasePath) === 0) { if (strpos(strtolower($url), $potentialBasePath) === 0) {
return trim(substr($url, strlen($potentialBasePath)), '/'); return 'uploads/images/' . trim(substr($url, strlen($potentialBasePath)), '/');
} }
} }

View File

@ -1,9 +1,8 @@
<?php namespace Tests\Entity; <?php namespace Tests\Entity;
use BookStack\Entities\Chapter; use BookStack\Entities\Chapter;
use BookStack\Entities\Page; use BookStack\Entities\Page;
use BookStack\Uploads\HttpFetcher; use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Tests\TestCase; use Tests\TestCase;
@ -154,14 +153,39 @@ class ExportTest extends TestCase
public function test_page_export_sets_right_data_type_for_svg_embeds() public function test_page_export_sets_right_data_type_for_svg_embeds()
{ {
$page = Page::first(); $page = Page::first();
$page->html = '<img src="http://example.com/image.svg">'; Storage::disk('local')->makeDirectory('uploads/images/gallery');
Storage::disk('local')->put('uploads/images/gallery/svg_test.svg', '<svg></svg>');
$page->html = '<img src="http://localhost/uploads/images/gallery/svg_test.svg">';
$page->save(); $page->save();
$this->asEditor(); $this->asEditor();
$this->mockHttpFetch('<svg></svg>');
$resp = $this->get($page->getUrl('/export/html')); $resp = $this->get($page->getUrl('/export/html'));
Storage::disk('local')->delete('uploads/images/gallery/svg_test.svg');
$resp->assertStatus(200); $resp->assertStatus(200);
$resp->assertSee('<img src="data:image/svg+xml;base64'); $resp->assertSee('<img src="data:image/svg+xml;base64');
} }
public function test_page_export_contained_html_image_fetches_only_run_when_url_points_to_image_upload_folder()
{
$page = Page::first();
$page->html = '<img src="http://localhost/uploads/images/gallery/svg_test.svg"/>'
."\n".'<img src="http://localhost/uploads/svg_test.svg"/>'
."\n".'<img src="/uploads/svg_test.svg"/>';
$storageDisk = Storage::disk('local');
$storageDisk->makeDirectory('uploads/images/gallery');
$storageDisk->put('uploads/images/gallery/svg_test.svg', '<svg>good</svg>');
$storageDisk->put('uploads/svg_test.svg', '<svg>bad</svg>');
$page->save();
$resp = $this->asEditor()->get($page->getUrl('/export/html'));
$storageDisk->delete('uploads/images/gallery/svg_test.svg');
$storageDisk->delete('uploads/svg_test.svg');
$resp->assertDontSee('http://localhost/uploads/images/gallery/svg_test.svg');
$resp->assertSee('http://localhost/uploads/svg_test.svg');
$resp->assertSee('src="/uploads/svg_test.svg"');
}
} }