Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* vim:set ts=2 sw=2 sts=2 et cindent: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include <dlfcn.h>
7 #include <stdio.h>
9 #include "nsDebug.h"
10 #include "mozilla/NullPtr.h"
12 #include "GStreamerLoader.h"
14 #define LIBGSTREAMER 0
15 #define LIBGSTAPP 1
16 #define LIBGSTVIDEO 2
18 #ifdef __OpenBSD__
19 #define LIB_GST_SUFFIX ".so"
20 #else
21 #define LIB_GST_SUFFIX ".so.0"
22 #endif
24 namespace mozilla {
26 /*
27 * Declare our function pointers using the types from the global gstreamer
28 * definitions.
29 */
30 #define GST_FUNC(_, func) typeof(::func)* func;
31 #define REPLACE_FUNC(func) GST_FUNC(-1, func)
32 #include "GStreamerFunctionList.h"
33 #undef GST_FUNC
34 #undef REPLACE_FUNC
36 /*
37 * Redefinitions of functions that have been defined in the gstreamer headers to
38 * stop them calling the gstreamer functions in global scope.
39 */
40 GstBuffer * gst_buffer_ref_impl(GstBuffer *buf);
41 void gst_buffer_unref_impl(GstBuffer *buf);
42 void gst_message_unref_impl(GstMessage *msg);
43 void gst_caps_unref_impl(GstCaps *caps);
45 #if GST_VERSION_MAJOR == 1
46 void gst_sample_unref_impl(GstSample *sample);
47 #endif
49 bool
50 load_gstreamer()
51 {
52 #ifdef __APPLE__
53 return true;
54 #endif
55 static bool loaded = false;
57 if (loaded) {
58 return true;
59 }
61 void *gstreamerLib = nullptr;
62 guint major = 0;
63 guint minor = 0;
64 guint micro, nano;
66 typedef typeof(::gst_version) VersionFuncType;
67 if (VersionFuncType *versionFunc = (VersionFuncType*)dlsym(RTLD_DEFAULT, "gst_version")) {
68 versionFunc(&major, &minor, µ, &nano);
69 }
71 if (major == GST_VERSION_MAJOR && minor == GST_VERSION_MINOR) {
72 gstreamerLib = RTLD_DEFAULT;
73 } else {
74 gstreamerLib = dlopen("libgstreamer-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL);
75 }
77 void *handles[3] = {
78 gstreamerLib,
79 dlopen("libgstapp-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL),
80 dlopen("libgstvideo-" GST_API_VERSION LIB_GST_SUFFIX, RTLD_NOW | RTLD_LOCAL)
81 };
83 for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
84 if (!handles[i]) {
85 NS_WARNING("Couldn't link gstreamer libraries");
86 goto fail;
87 }
88 }
90 #define GST_FUNC(lib, symbol) \
91 if (!(symbol = (typeof(symbol))dlsym(handles[lib], #symbol))) { \
92 NS_WARNING("Couldn't link symbol " #symbol); \
93 goto fail; \
94 }
95 #define REPLACE_FUNC(symbol) symbol = symbol##_impl;
96 #include "GStreamerFunctionList.h"
97 #undef GST_FUNC
98 #undef REPLACE_FUNC
100 loaded = true;
101 return true;
103 fail:
105 for (size_t i = 0; i < sizeof(handles) / sizeof(handles[0]); i++) {
106 if (handles[i] && handles[i] != RTLD_DEFAULT) {
107 dlclose(handles[i]);
108 }
109 }
111 return false;
112 }
114 GstBuffer *
115 gst_buffer_ref_impl(GstBuffer *buf)
116 {
117 return (GstBuffer *)gst_mini_object_ref(GST_MINI_OBJECT_CAST(buf));
118 }
120 void
121 gst_buffer_unref_impl(GstBuffer *buf)
122 {
123 gst_mini_object_unref(GST_MINI_OBJECT_CAST(buf));
124 }
126 void
127 gst_message_unref_impl(GstMessage *msg)
128 {
129 gst_mini_object_unref(GST_MINI_OBJECT_CAST(msg));
130 }
132 #if GST_VERSION_MAJOR == 1
133 void
134 gst_sample_unref_impl(GstSample *sample)
135 {
136 gst_mini_object_unref(GST_MINI_OBJECT_CAST(sample));
137 }
138 #endif
140 void
141 gst_caps_unref_impl(GstCaps *caps)
142 {
143 gst_mini_object_unref(GST_MINI_OBJECT_CAST(caps));
144 }
146 }