make swfdec_as_object_mark() only mark if not marked yet
[swfdec.git] / swfdec / swfdec_load_object.c
blob339b145bdd3097e831355e698c708cb793f14107
1 /* Swfdec
2 * Copyright (C) 2007-2008 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_access.h"
28 #include "swfdec_as_frame_internal.h"
29 #include "swfdec_as_strings.h"
30 #include "swfdec_debug.h"
31 #include "swfdec_internal.h"
32 #include "swfdec_loader_internal.h"
33 #include "swfdec_stream_target.h"
34 #include "swfdec_player_internal.h"
36 /*** SWFDEC_STREAM_TARGET ***/
38 static SwfdecPlayer *
39 swfdec_load_object_stream_target_get_player (SwfdecStreamTarget *target)
41 return SWFDEC_PLAYER (swfdec_gc_object_get_context (target));
44 static gboolean
45 swfdec_load_object_stream_target_parse (SwfdecStreamTarget *target,
46 SwfdecStream *stream)
48 SwfdecLoader *loader = SWFDEC_LOADER (stream);
49 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
50 SwfdecPlayer *player = SWFDEC_PLAYER (swfdec_gc_object_get_context (target));
52 if (load_object->progress != NULL) {
53 swfdec_sandbox_use (load_object->sandbox);
54 load_object->progress (player, &load_object->target,
55 swfdec_loader_get_loaded (loader), swfdec_loader_get_size (loader));
56 swfdec_sandbox_unuse (load_object->sandbox);
58 return FALSE;
61 static void
62 swfdec_load_object_stream_target_error (SwfdecStreamTarget *target,
63 SwfdecStream *stream)
65 SwfdecLoader *loader = SWFDEC_LOADER (stream);
66 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
67 SwfdecPlayer *player = SWFDEC_PLAYER (swfdec_gc_object_get_context (load_object->sandbox));
69 /* break reference to the loader */
70 swfdec_stream_set_target (SWFDEC_STREAM (loader), NULL);
71 load_object->loader = NULL;
72 g_object_unref (loader);
74 /* call finish */
75 swfdec_sandbox_use (load_object->sandbox);
76 load_object->finish (player, &load_object->target, NULL);
77 swfdec_sandbox_unuse (load_object->sandbox);
79 /* unroot */
80 swfdec_player_unroot (player, load_object);
83 static void
84 swfdec_load_object_stream_target_close (SwfdecStreamTarget *target,
85 SwfdecStream *stream)
87 SwfdecPlayer *player = SWFDEC_PLAYER (swfdec_gc_object_get_context (target));
88 SwfdecLoadObject *load_object = SWFDEC_LOAD_OBJECT (target);
89 char *text;
91 // get text
92 text = swfdec_buffer_queue_pull_text (swfdec_stream_get_queue (stream), load_object->version);
94 /* break reference to the loader */
95 swfdec_stream_set_target (stream, NULL);
96 load_object->loader = NULL;
98 /* call finish */
99 swfdec_sandbox_use (load_object->sandbox);
100 if (text != NULL) {
101 load_object->finish (player, &load_object->target,
102 swfdec_as_context_give_string (SWFDEC_AS_CONTEXT (player), text));
103 } else {
104 load_object->finish (player, &load_object->target, SWFDEC_AS_STR_EMPTY);
106 swfdec_sandbox_unuse (load_object->sandbox);
108 /* unroot */
109 swfdec_player_unroot (player, load_object);
112 static void
113 swfdec_load_object_stream_target_init (SwfdecStreamTargetInterface *iface)
115 iface->get_player = swfdec_load_object_stream_target_get_player;
116 iface->parse = swfdec_load_object_stream_target_parse;
117 iface->close = swfdec_load_object_stream_target_close;
118 iface->error = swfdec_load_object_stream_target_error;
121 /*** SWFDEC_LOAD_OBJECT ***/
123 G_DEFINE_TYPE_WITH_CODE (SwfdecLoadObject, swfdec_load_object, SWFDEC_TYPE_GC_OBJECT,
124 G_IMPLEMENT_INTERFACE (SWFDEC_TYPE_STREAM_TARGET, swfdec_load_object_stream_target_init))
126 static void
127 swfdec_load_object_dispose (GObject *object)
129 SwfdecLoadObject *load = SWFDEC_LOAD_OBJECT (object);
131 if (load->loader) {
132 swfdec_stream_set_target (SWFDEC_STREAM (load->loader), NULL);
133 g_object_unref (load->loader);
134 load->loader = NULL;
136 if (load->buffer) {
137 swfdec_buffer_unref (load->buffer);
138 load->buffer = NULL;
140 g_strfreev (load->header_names);
141 g_strfreev (load->header_values);
143 G_OBJECT_CLASS (swfdec_load_object_parent_class)->dispose (object);
146 static void
147 swfdec_load_object_class_init (SwfdecLoadObjectClass *klass)
149 GObjectClass *object_class = G_OBJECT_CLASS (klass);
151 object_class->dispose = swfdec_load_object_dispose;
154 static void
155 swfdec_load_object_init (SwfdecLoadObject *load_object)
159 static void
160 swfdec_load_object_load (SwfdecPlayer *player, gboolean allow, gpointer obj)
162 SwfdecLoadObject *load = SWFDEC_LOAD_OBJECT (obj);
164 if (!allow) {
165 SWFDEC_WARNING ("SECURITY: no access to %s from %s",
166 load->url, swfdec_url_get_url (load->sandbox->url));
168 /* call finish */
169 swfdec_sandbox_use (load->sandbox);
170 load->finish (player, &load->target, NULL);
171 swfdec_sandbox_unuse (load->sandbox);
173 /* unroot */
174 swfdec_player_unroot (player, load);
175 return;
178 load->loader = swfdec_player_load_with_headers (player, load->url,
179 load->buffer, load->header_count, (const char **)load->header_names,
180 (const char **)load->header_values);
182 swfdec_stream_set_target (SWFDEC_STREAM (load->loader), SWFDEC_STREAM_TARGET (load));
183 swfdec_loader_set_data_type (load->loader, SWFDEC_LOADER_DATA_TEXT);
186 static const SwfdecAccessMatrix swfdec_load_object_matrix = {
187 { SWFDEC_ACCESS_NO, SWFDEC_ACCESS_NO, SWFDEC_ACCESS_NO },
188 { SWFDEC_ACCESS_NO, SWFDEC_ACCESS_YES, SWFDEC_ACCESS_POLICY },
189 { SWFDEC_ACCESS_YES, SWFDEC_ACCESS_NO, SWFDEC_ACCESS_NO },
190 { SWFDEC_ACCESS_NO, SWFDEC_ACCESS_NO, SWFDEC_ACCESS_POLICY },
191 { SWFDEC_ACCESS_YES, SWFDEC_ACCESS_NO, SWFDEC_ACCESS_POLICY }
194 /* perform security checks */
195 static void
196 swfdec_load_object_request (gpointer objectp, gpointer playerp)
198 SwfdecLoadObject *load = objectp;
200 swfdec_player_allow_by_matrix (playerp, load->sandbox, load->url,
201 swfdec_load_object_matrix, swfdec_load_object_load, load);
204 static void
205 swfdec_load_object_mark (gpointer object, gpointer player)
207 SwfdecLoadObject *load = object;
209 /* need to mark ourself, becuase we're not a real GcObject */
210 swfdec_gc_object_mark (load);
212 swfdec_gc_object_mark (load->sandbox);
213 if (load->url)
214 swfdec_as_string_mark (load->url);
215 swfdec_as_value_mark (&load->target);
218 void
219 swfdec_load_object_create (SwfdecPlayer *player, const SwfdecAsValue *target,
220 const char *url, SwfdecBuffer *data, guint header_count, char **header_names,
221 char **header_values, SwfdecLoadObjectProgress progress,
222 SwfdecLoadObjectFinish finish)
224 SwfdecLoadObject *load;
226 g_return_if_fail (SWFDEC_IS_PLAYER (player));
227 g_return_if_fail (target != NULL);
228 g_return_if_fail (url != NULL);
229 g_return_if_fail (header_count == 0 || header_names != NULL);
230 g_return_if_fail (header_count == 0 || header_values != NULL);
231 g_return_if_fail (finish != NULL);
233 load = g_object_new (SWFDEC_TYPE_LOAD_OBJECT, "context", player, NULL);
234 swfdec_player_root_full (player, load, swfdec_load_object_mark, NULL);
236 load->target = *target;
237 load->url = url;
238 load->buffer = data;
239 load->header_count = header_count;
240 load->header_names = header_names;
241 load->header_values = header_values;
242 load->progress = progress;
243 load->finish = finish;
244 /* get the current security */
245 g_assert (SWFDEC_AS_CONTEXT (player)->frame);
246 load->sandbox = swfdec_sandbox_get (player);
247 load->version = SWFDEC_AS_CONTEXT (player)->version;
248 swfdec_player_request_resource (player, swfdec_load_object_request, load, NULL);