@@ -758,86 +758,97 @@ void EditorAssetLibrary::_select_asset(int p_id) {
758758 _api_request (" asset/" + itos (p_id), REQUESTING_ASSET );
759759}
760760
761- void EditorAssetLibrary::_image_update (bool use_cache , bool final , const PackedByteArray &p_data, int p_queue_id) {
761+ void EditorAssetLibrary::_image_update (bool p_use_cache , bool p_final , const PackedByteArray &p_data, int p_queue_id) {
762762 Object *obj = ObjectDB::get_instance (image_queue[p_queue_id].target );
763+ if (!obj) {
764+ return ;
765+ }
763766
764- if (obj) {
765- bool image_set = false ;
766- PackedByteArray image_data = p_data;
767+ bool image_set = false ;
768+ PackedByteArray image_data = p_data;
767769
768- if (use_cache ) {
769- String cache_filename_base = EditorPaths::get_singleton ()->get_cache_dir ().path_join (" assetimage_" + image_queue[p_queue_id].image_url .md5_text ());
770+ if (p_use_cache ) {
771+ String cache_filename_base = EditorPaths::get_singleton ()->get_cache_dir ().path_join (" assetimage_" + image_queue[p_queue_id].image_url .md5_text ());
770772
771- Ref<FileAccess> file = FileAccess::open (cache_filename_base + " .data" , FileAccess::READ );
772- if (file.is_valid ()) {
773- PackedByteArray cached_data;
774- int len = file->get_32 ();
775- cached_data.resize (len);
773+ Ref<FileAccess> file = FileAccess::open (cache_filename_base + " .data" , FileAccess::READ );
774+ if (file.is_valid ()) {
775+ PackedByteArray cached_data;
776+ int len = file->get_32 ();
777+ cached_data.resize (len);
776778
777- uint8_t *w = cached_data.ptrw ();
778- file->get_buffer (w, len);
779+ uint8_t *w = cached_data.ptrw ();
780+ file->get_buffer (w, len);
779781
780- image_data = cached_data;
781- }
782+ image_data = cached_data;
783+ }
784+ }
785+
786+ int len = image_data.size ();
787+ const uint8_t *r = image_data.ptr ();
788+ Ref<Image> image = memnew (Image);
789+
790+ uint8_t png_signature[8 ] = { 137 , 80 , 78 , 71 , 13 , 10 , 26 , 10 };
791+ uint8_t jpg_signature[3 ] = { 255 , 216 , 255 };
792+ uint8_t webp_signature[4 ] = { 82 , 73 , 70 , 70 };
793+ uint8_t bmp_signature[2 ] = { 66 , 77 };
794+
795+ if (r) {
796+ Ref<Image> parsed_image;
797+
798+ if ((memcmp (&r[0 ], &png_signature[0 ], 8 ) == 0 ) && Image::_png_mem_loader_func) {
799+ parsed_image = Image::_png_mem_loader_func (r, len);
800+ } else if ((memcmp (&r[0 ], &jpg_signature[0 ], 3 ) == 0 ) && Image::_jpg_mem_loader_func) {
801+ parsed_image = Image::_jpg_mem_loader_func (r, len);
802+ } else if ((memcmp (&r[0 ], &webp_signature[0 ], 4 ) == 0 ) && Image::_webp_mem_loader_func) {
803+ parsed_image = Image::_webp_mem_loader_func (r, len);
804+ } else if ((memcmp (&r[0 ], &bmp_signature[0 ], 2 ) == 0 ) && Image::_bmp_mem_loader_func) {
805+ parsed_image = Image::_bmp_mem_loader_func (r, len);
806+ } else if (Image::_svg_scalable_mem_loader_func) {
807+ parsed_image = Image::_svg_scalable_mem_loader_func (r, len, 1.0 );
782808 }
783809
784- int len = image_data.size ();
785- const uint8_t *r = image_data.ptr ();
786- Ref<Image> image = Ref<Image>(memnew (Image));
787-
788- uint8_t png_signature[8 ] = { 137 , 80 , 78 , 71 , 13 , 10 , 26 , 10 };
789- uint8_t jpg_signature[3 ] = { 255 , 216 , 255 };
790- uint8_t webp_signature[4 ] = { 82 , 73 , 70 , 70 };
791- uint8_t bmp_signature[2 ] = { 66 , 77 };
792-
793- if (r) {
794- if ((memcmp (&r[0 ], &png_signature[0 ], 8 ) == 0 ) && Image::_png_mem_loader_func) {
795- image->copy_internals_from (Image::_png_mem_loader_func (r, len));
796- } else if ((memcmp (&r[0 ], &jpg_signature[0 ], 3 ) == 0 ) && Image::_jpg_mem_loader_func) {
797- image->copy_internals_from (Image::_jpg_mem_loader_func (r, len));
798- } else if ((memcmp (&r[0 ], &webp_signature[0 ], 4 ) == 0 ) && Image::_webp_mem_loader_func) {
799- image->copy_internals_from (Image::_webp_mem_loader_func (r, len));
800- } else if ((memcmp (&r[0 ], &bmp_signature[0 ], 2 ) == 0 ) && Image::_bmp_mem_loader_func) {
801- image->copy_internals_from (Image::_bmp_mem_loader_func (r, len));
802- } else if (Image::_svg_scalable_mem_loader_func) {
803- image->copy_internals_from (Image::_svg_scalable_mem_loader_func (r, len, 1.0 ));
810+ if (parsed_image.is_null ()) {
811+ if (is_print_verbose_enabled ()) {
812+ ERR_PRINT (vformat (" Asset Library: Invalid image downloaded from '%s' for asset # %d" , image_queue[p_queue_id].image_url , image_queue[p_queue_id].asset_id ));
804813 }
814+ } else {
815+ image->copy_internals_from (parsed_image);
805816 }
817+ }
806818
807- if (!image->is_empty ()) {
808- switch (image_queue[p_queue_id].image_type ) {
809- case IMAGE_QUEUE_ICON :
819+ if (!image->is_empty ()) {
820+ switch (image_queue[p_queue_id].image_type ) {
821+ case IMAGE_QUEUE_ICON :
822+ image->resize (64 * EDSCALE , 64 * EDSCALE , Image::INTERPOLATE_LANCZOS );
823+ break ;
810824
811- image->resize (64 * EDSCALE , 64 * EDSCALE , Image::INTERPOLATE_LANCZOS );
825+ case IMAGE_QUEUE_THUMBNAIL : {
826+ float max_height = 85 * EDSCALE ;
812827
813- break ;
814- case IMAGE_QUEUE_THUMBNAIL : {
815- float max_height = 85 * EDSCALE ;
828+ float scale_ratio = max_height / (image->get_height () * EDSCALE );
829+ if (scale_ratio < 1 ) {
830+ image->resize (image->get_width () * EDSCALE * scale_ratio, image->get_height () * EDSCALE * scale_ratio, Image::INTERPOLATE_LANCZOS );
831+ }
832+ } break ;
816833
817- float scale_ratio = max_height / (image->get_height () * EDSCALE );
818- if (scale_ratio < 1 ) {
819- image->resize (image->get_width () * EDSCALE * scale_ratio, image->get_height () * EDSCALE * scale_ratio, Image::INTERPOLATE_LANCZOS );
820- }
821- } break ;
822- case IMAGE_QUEUE_SCREENSHOT : {
823- float max_height = 397 * EDSCALE ;
834+ case IMAGE_QUEUE_SCREENSHOT : {
835+ float max_height = 397 * EDSCALE ;
824836
825- float scale_ratio = max_height / (image->get_height () * EDSCALE );
826- if (scale_ratio < 1 ) {
827- image->resize (image->get_width () * EDSCALE * scale_ratio, image->get_height () * EDSCALE * scale_ratio, Image::INTERPOLATE_LANCZOS );
828- }
829- } break ;
830- }
837+ float scale_ratio = max_height / (image->get_height () * EDSCALE );
838+ if (scale_ratio < 1 ) {
839+ image->resize (image->get_width () * EDSCALE * scale_ratio, image->get_height () * EDSCALE * scale_ratio, Image::INTERPOLATE_LANCZOS );
840+ }
841+ } break ;
842+ }
831843
832- Ref<ImageTexture> tex = ImageTexture::create_from_image (image);
844+ Ref<ImageTexture> tex = ImageTexture::create_from_image (image);
833845
834- obj->call (" set_image" , image_queue[p_queue_id].image_type , image_queue[p_queue_id].image_index , tex);
835- image_set = true ;
836- }
846+ obj->call (" set_image" , image_queue[p_queue_id].image_type , image_queue[p_queue_id].image_index , tex);
847+ image_set = true ;
848+ }
837849
838- if (!image_set && final ) {
839- obj->call (" set_image" , image_queue[p_queue_id].image_type , image_queue[p_queue_id].image_index , get_editor_theme_icon (SNAME (" FileBrokenBigThumb" )));
840- }
850+ if (!image_set && p_final) {
851+ obj->call (" set_image" , image_queue[p_queue_id].image_type , image_queue[p_queue_id].image_index , get_editor_theme_icon (SNAME (" FileBrokenBigThumb" )));
841852 }
842853}
843854
@@ -870,7 +881,10 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
870881 _image_update (p_code == HTTPClient::RESPONSE_NOT_MODIFIED , true , p_data, p_queue_id);
871882
872883 } else {
873- WARN_PRINT (" Error getting image file from URL: " + image_queue[p_queue_id].image_url );
884+ if (is_print_verbose_enabled ()) {
885+ WARN_PRINT (vformat (" Asset Library: Error getting image from '%s' for asset # %d." , image_queue[p_queue_id].image_url , image_queue[p_queue_id].asset_id ));
886+ }
887+
874888 Object *obj = ObjectDB::get_instance (image_queue[p_queue_id].target );
875889 if (obj) {
876890 obj->call (" set_image" , image_queue[p_queue_id].image_type , image_queue[p_queue_id].image_index , get_editor_theme_icon (SNAME (" FileBrokenBigThumb" )));
@@ -919,22 +933,48 @@ void EditorAssetLibrary::_update_image_queue() {
919933 }
920934}
921935
922- void EditorAssetLibrary::_request_image (ObjectID p_for, String p_image_url, ImageType p_type, int p_image_index) {
936+ void EditorAssetLibrary::_request_image (ObjectID p_for, int p_asset_id, String p_image_url, ImageType p_type, int p_image_index) {
937+ // Remove extra spaces around the URL. This isn't strictly valid, but recoverable.
938+ String trimmed_url = p_image_url.strip_edges ();
939+ if (trimmed_url != p_image_url && is_print_verbose_enabled ()) {
940+ WARN_PRINT (vformat (" Asset Library: Badly formatted image URL '%s' for asset # %d." , p_image_url, p_asset_id));
941+ }
942+
943+ // Validate the image URL first.
944+ {
945+ String url_scheme;
946+ String url_host;
947+ int url_port;
948+ String url_path;
949+ Error err = trimmed_url.parse_url (url_scheme, url_host, url_port, url_path);
950+ if (err != OK ) {
951+ if (is_print_verbose_enabled ()) {
952+ ERR_PRINT (vformat (" Asset Library: Invalid image URL '%s' for asset # %d." , trimmed_url, p_asset_id));
953+ }
954+
955+ Object *obj = ObjectDB::get_instance (p_for);
956+ if (obj) {
957+ obj->call (" set_image" , p_type, p_image_index, get_editor_theme_icon (SNAME (" FileBrokenBigThumb" )));
958+ }
959+ return ;
960+ }
961+ }
962+
923963 ImageQueue iq;
924- iq.image_url = p_image_url ;
964+ iq.image_url = trimmed_url ;
925965 iq.image_index = p_image_index;
926966 iq.image_type = p_type;
927967 iq.request = memnew (HTTPRequest);
928968 setup_http_request (iq.request );
929969
930970 iq.target = p_for;
971+ iq.asset_id = p_asset_id;
931972 iq.queue_id = ++last_queue_id;
932973 iq.active = false ;
933974
934975 iq.request ->connect (" request_completed" , callable_mp (this , &EditorAssetLibrary::_image_request_completed).bind (iq.queue_id ));
935976
936977 image_queue[iq.queue_id ] = iq;
937-
938978 add_child (iq.request );
939979
940980 _image_update (true , false , PackedByteArray (), iq.queue_id );
@@ -1311,7 +1351,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
13111351 item->connect (" category_selected" , callable_mp (this , &EditorAssetLibrary::_select_category));
13121352
13131353 if (r.has (" icon_url" ) && !r[" icon_url" ].operator String ().is_empty ()) {
1314- _request_image (item->get_instance_id (), r[" icon_url" ], IMAGE_QUEUE_ICON , 0 );
1354+ _request_image (item->get_instance_id (), r[" asset_id " ], r[ " icon_url" ], IMAGE_QUEUE_ICON , 0 );
13151355 }
13161356 }
13171357
@@ -1362,7 +1402,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
13621402 }
13631403
13641404 if (r.has (" icon_url" ) && !r[" icon_url" ].operator String ().is_empty ()) {
1365- _request_image (description->get_instance_id (), r[" icon_url" ], IMAGE_QUEUE_ICON , 0 );
1405+ _request_image (description->get_instance_id (), r[" asset_id " ], r[ " icon_url" ], IMAGE_QUEUE_ICON , 0 );
13661406 }
13671407
13681408 if (d.has (" previews" )) {
@@ -1383,11 +1423,11 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
13831423 description->add_preview (i, is_video, video_url);
13841424
13851425 if (p.has (" thumbnail" )) {
1386- _request_image (description->get_instance_id (), p[" thumbnail" ], IMAGE_QUEUE_THUMBNAIL , i);
1426+ _request_image (description->get_instance_id (), r[ " asset_id " ], p[" thumbnail" ], IMAGE_QUEUE_THUMBNAIL , i);
13871427 }
13881428
13891429 if (!is_video) {
1390- _request_image (description->get_instance_id (), p[" link" ], IMAGE_QUEUE_SCREENSHOT , i);
1430+ _request_image (description->get_instance_id (), r[ " asset_id " ], p[" link" ], IMAGE_QUEUE_SCREENSHOT , i);
13911431 }
13921432 }
13931433 }
0 commit comments