don't crash when loading images > 65kB (fixes #13529)
[swfdec.git] / libswfdec / swfdec_load_object.c
blob5b659f2f02acae5cc2fb34c2149942c3112a377c
1 /* Swfdec
2 * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
3 * 2007 Pekka Lampila <pekka.lampila@iki.fi>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
25 #include <string.h>
26 #include "swfdec_load_object.h"
27 #include "swfdec_as_frame_internal.h"
28 #include "swfdec_as_strings.h"
29 #include "swfdec_debug.h"
30 #include "swfdec_loader_internal.h"
31 #include "swfdec_loadertarget.h"
32 #include "swfdec_player_internal.h"
33 #include "swfdec_resource_request.h"
35 /*** SWFDEC_LOADER_TARGET ***/
37 static SwfdecPlayer *
38 swfdec_load_object_loader_target_get_player (SwfdecLoaderTarget *target)
40 return SWFDEC_PLAYER (SWFDEC_AS_OBJECT (target)->context);
43 static void
44 swfdec_load_object_loader_target_parse (SwfdecLoaderTarget *target,
45 SwfdecLoader *loader)
47 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
49 if (load_object->progress != NULL) {
50 load_object->progress (load_object->target,
51 swfdec_loader_get_loaded (loader), swfdec_loader_get_size (loader));
55 static void
56 swfdec_load_object_loader_target_error (SwfdecLoaderTarget *target,
57 SwfdecLoader *loader)
59 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
61 /* break reference to the loader */
62 swfdec_loader_set_target (loader, NULL);
63 load_object->loader = NULL;
64 g_object_unref (loader);
66 /* call finish */
67 load_object->finish (load_object->target, NULL);
69 /* unroot */
70 swfdec_player_unroot_object (SWFDEC_PLAYER (
71 SWFDEC_AS_OBJECT (load_object)->context), G_OBJECT (load_object));
74 static void
75 swfdec_load_object_loader_target_eof (SwfdecLoaderTarget *target,
76 SwfdecLoader *loader)
78 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
79 char *text;
81 // get text
82 text =
83 swfdec_loader_get_text (loader, load_object->target->context->version);
85 /* break reference to the loader */
86 swfdec_loader_set_target (loader, NULL);
87 load_object->loader = NULL;
88 g_object_unref (loader);
90 /* call finish */
91 if (text != NULL) {
92 load_object->finish (load_object->target,
93 swfdec_as_context_give_string (load_object->target->context, text));
94 } else {
95 load_object->finish (load_object->target, SWFDEC_AS_STR_EMPTY);
98 /* unroot */
99 swfdec_player_unroot_object (SWFDEC_PLAYER (
100 SWFDEC_AS_OBJECT (load_object)->context), G_OBJECT (load_object));
103 static void
104 swfdec_load_object_loader_target_init (SwfdecLoaderTargetInterface *iface)
106 iface->get_player = swfdec_load_object_loader_target_get_player;
107 iface->parse = swfdec_load_object_loader_target_parse;
108 iface->eof = swfdec_load_object_loader_target_eof;
109 iface->error = swfdec_load_object_loader_target_error;
112 /*** SWFDEC_LOAD_OBJECT ***/
114 G_DEFINE_TYPE_WITH_CODE (SwfdecLoadObject, swfdec_load_object, SWFDEC_TYPE_AS_OBJECT,
115 G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_LOADER_TARGET, swfdec_load_object_loader_target_init))
117 static void
118 swfdec_load_object_reset (SwfdecLoadObject *load_object)
120 if (load_object->loader) {
121 swfdec_loader_set_target (load_object->loader, NULL);
122 g_object_unref (load_object->loader);
123 load_object->loader = NULL;
127 static void
128 swfdec_load_object_mark (SwfdecAsObject *object)
130 swfdec_as_object_mark (SWFDEC_LOAD_OBJECT (object)->target);
132 SWFDEC_AS_OBJECT_CLASS (swfdec_load_object_parent_class)->mark (object);
135 static void
136 swfdec_load_object_dispose (GObject *object)
138 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (object);
140 swfdec_load_object_reset (load_object);
142 G_OBJECT_CLASS (swfdec_load_object_parent_class)->dispose (object);
145 static void
146 swfdec_load_object_class_init (SwfdecLoadObjectClass *klass)
148 GObjectClass *object_class = G_OBJECT_CLASS (klass);
149 SwfdecAsObjectClass *as_object_class = SWFDEC_AS_OBJECT_CLASS (klass);
151 object_class->dispose = swfdec_load_object_dispose;
153 as_object_class->mark = swfdec_load_object_mark;
156 static void
157 swfdec_load_object_init (SwfdecLoadObject *load_object)
161 static void
162 swfdec_load_object_got_loader (SwfdecPlayer *player, SwfdecLoader *loader, gpointer obj)
164 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (obj);
166 if (loader == NULL) {
167 return;
169 load_object->loader = loader;
171 swfdec_loader_set_target (load_object->loader,
172 SWFDEC_LOADER_TARGET (load_object));
173 swfdec_loader_set_data_type (load_object->loader, SWFDEC_LOADER_DATA_TEXT);
176 static gboolean
177 swfdec_load_object_load (SwfdecLoadObject *load_object, const char *url,
178 SwfdecLoaderRequest request, SwfdecBuffer *data)
180 SwfdecPlayer *player;
181 SwfdecSecurity *sec;
183 g_return_val_if_fail (SWFDEC_IS_LOAD_OBJECT (load_object), FALSE);
184 g_return_val_if_fail (url != NULL, FALSE);
186 player = SWFDEC_PLAYER (SWFDEC_AS_OBJECT (load_object)->context);
187 swfdec_load_object_reset (load_object);
189 /* get the current security */
190 g_assert (SWFDEC_AS_CONTEXT (player)->frame);
191 sec = SWFDEC_AS_CONTEXT (player)->frame->security;
193 g_object_ref (load_object);
194 swfdec_player_request_resource (player, sec, url, request, data,
195 swfdec_load_object_got_loader, load_object, g_object_unref);
197 return TRUE;
200 SwfdecAsObject *
201 swfdec_load_object_new (SwfdecAsObject *target, const char *url,
202 SwfdecLoaderRequest request, SwfdecBuffer *data,
203 SwfdecLoadObjectProgress progress, SwfdecLoadObjectFinish finish)
205 SwfdecLoadObject *load_object;
207 g_return_val_if_fail (SWFDEC_IS_AS_OBJECT (target), NULL);
208 g_return_val_if_fail (url != NULL, NULL);
209 g_return_val_if_fail (finish != NULL, NULL);
211 if (!swfdec_as_context_use_mem (target->context, sizeof (SwfdecLoadObject)))
212 return NULL;
213 load_object = SWFDEC_LOAD_OBJECT (g_object_new (
214 SWFDEC_TYPE_LOAD_OBJECT, NULL));
215 swfdec_as_object_add (SWFDEC_AS_OBJECT (load_object), target->context,
216 sizeof (SwfdecLoadObject));
218 load_object->target = target;
219 load_object->progress = progress;
220 load_object->finish = finish;
222 if (!swfdec_load_object_load (load_object, url, request, data))
223 return NULL;
225 swfdec_player_root_object (SWFDEC_PLAYER (target->context),
226 G_OBJECT (load_object));
228 return SWFDEC_AS_OBJECT (load_object);