1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 21:57:35 +00:00

LibWeb: Fix mismatching Resource subclass types

This was a confusing bug: ImageStyleValue loaded its image resource as
a Generic resource, while HTMLImageElement loaded as Image.

This patch fixes the issue and adds an assertion to verify that we only
share resources that have the same C++ client class type.
This commit is contained in:
Andreas Kling 2020-06-05 23:32:23 +02:00
parent 3337365000
commit 5dc8c4a24c
5 changed files with 13 additions and 3 deletions

View file

@ -293,13 +293,14 @@ ImageStyleValue::ImageStyleValue(const URL& url, Document& document)
{ {
LoadRequest request; LoadRequest request;
request.set_url(url); request.set_url(url);
set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request)); set_resource(ResourceLoader::the().load_resource(Resource::Type::Image, request));
} }
void ImageStyleValue::resource_did_load() void ImageStyleValue::resource_did_load()
{ {
if (!m_document) if (!m_document)
return; return;
// FIXME: Use the shared decoder from ImageResource!
m_bitmap = Gfx::load_png_from_memory(resource()->encoded_data().data(), resource()->encoded_data().size()); m_bitmap = Gfx::load_png_from_memory(resource()->encoded_data().data(), resource()->encoded_data().size());
if (!m_bitmap) if (!m_bitmap)
return; return;

View file

@ -36,7 +36,7 @@
#include <LibGfx/Color.h> #include <LibGfx/Color.h>
#include <LibWeb/CSS/Length.h> #include <LibWeb/CSS/Length.h>
#include <LibWeb/CSS/PropertyID.h> #include <LibWeb/CSS/PropertyID.h>
#include <LibWeb/Loader/Resource.h> #include <LibWeb/Loader/ImageResource.h>
namespace Web { namespace Web {
@ -302,7 +302,7 @@ private:
class ImageStyleValue final class ImageStyleValue final
: public StyleValue : public StyleValue
, public ResourceClient { , public ImageResourceClient {
public: public:
static NonnullRefPtr<ImageStyleValue> create(const URL& url, Document& document) { return adopt(*new ImageStyleValue(url, document)); } static NonnullRefPtr<ImageStyleValue> create(const URL& url, Document& document) { return adopt(*new ImageStyleValue(url, document)); }
virtual ~ImageStyleValue() override { } virtual ~ImageStyleValue() override { }

View file

@ -54,6 +54,9 @@ public:
protected: protected:
ImageResource* resource() { return static_cast<ImageResource*>(ResourceClient::resource()); } ImageResource* resource() { return static_cast<ImageResource*>(ResourceClient::resource()); }
const ImageResource* resource() const { return static_cast<const ImageResource*>(ResourceClient::resource()); } const ImageResource* resource() const { return static_cast<const ImageResource*>(ResourceClient::resource()); }
private:
virtual Resource::Type client_type() const override { return Resource::Type::Image; }
}; };
} }

View file

@ -99,6 +99,8 @@ void ResourceClient::set_resource(Resource* resource)
m_resource->unregister_client({}, *this); m_resource->unregister_client({}, *this);
m_resource = resource; m_resource = resource;
if (m_resource) { if (m_resource) {
ASSERT(resource->type() == client_type());
m_resource->register_client({}, *this); m_resource->register_client({}, *this);
// Make sure that reused resources also have their load callback fired. // Make sure that reused resources also have their load callback fired.

View file

@ -55,6 +55,8 @@ public:
static NonnullRefPtr<Resource> create(Badge<ResourceLoader>, Type, const LoadRequest&); static NonnullRefPtr<Resource> create(Badge<ResourceLoader>, Type, const LoadRequest&);
virtual ~Resource(); virtual ~Resource();
Type type() const { return m_type; }
bool is_loaded() const { return m_loaded; } bool is_loaded() const { return m_loaded; }
bool is_failed() const { return m_failed; } bool is_failed() const { return m_failed; }
@ -95,6 +97,8 @@ public:
virtual void resource_did_fail() { } virtual void resource_did_fail() { }
protected: protected:
virtual Resource::Type client_type() const { return Resource::Type::Generic; }
Resource* resource() { return m_resource; } Resource* resource() { return m_resource; }
const Resource* resource() const { return m_resource; } const Resource* resource() const { return m_resource; }
void set_resource(Resource*); void set_resource(Resource*);