1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                  SSSSS  TTTTT   AAA   TTTTT  IIIII   CCCC                   %
7 %                  SS       T    A   A    T      I    C                       %
8 %                   SSS     T    AAAAA    T      I    C                       %
9 %                     SS    T    A   A    T      I    C                       %
10 %                  SSSSS    T    A   A    T    IIIII   CCCC                   %
11 %                                                                             %
12 %                                                                             %
13 %                          MagickCore Static Methods                          %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                   Cristy                                    %
17 %                                 March 2000                                  %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    https://imagemagick.org/script/license.php                               %
27 %                                                                             %
28 %  Unless required by applicable law or agreed to in writing, software        %
29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31 %  See the License for the specific language governing permissions and        %
32 %  limitations under the License.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 
40 /*
41   Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/coder.h"
45 #include "MagickCore/exception-private.h"
46 #include "MagickCore/image.h"
47 #include "MagickCore/module.h"
48 #include "MagickCore/policy.h"
49 #include "MagickCore/static.h"
50 #include "MagickCore/string_.h"
51 #include "coders/coders.h"
52 
53 /*
54   Define declarations.
55 */
56 #define AddMagickCoder(coder)  { #coder, MagickFalse, \
57   Register ## coder ## Image, Unregister ## coder ## Image },
58 
59 /*
60   ImageMagick module stub.
61 */
RegisterUndefinedImage(void)62 ModuleExport size_t RegisterUndefinedImage(void)
63 {
64   return(MagickImageCoderSignature);
65 }
66 
UnregisterUndefinedImage(void)67 ModuleExport void UnregisterUndefinedImage(void)
68 {
69 }
70 
71 /*
72   ImageMagick modules.
73 */
74 static struct
75 {
76   const char
77     *module;
78 
79   MagickBooleanType
80     registered;
81 
82   size_t
83     (*register_module)(void);
84 
85   void
86     (*unregister_module)(void);
87 } MagickModules[] = {
88 #if !defined(MAGICKCORE_BUILD_MODULES)
89   #include "coders/coders-list.h"
90 #endif
91   { (const char *) NULL, MagickFalse, RegisterUndefinedImage, UnregisterUndefinedImage }
92 };
93 
94 /*
95 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96 %                                                                             %
97 %                                                                             %
98 %                                                                             %
99 %   I n v o k e S t a t i c I m a g e F i l t e r                             %
100 %                                                                             %
101 %                                                                             %
102 %                                                                             %
103 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 %
105 %  InvokeStaticImageFilter() invokes a static image filter.
106 %
107 %  The format of the InvokeStaticImageFilter method is:
108 %
109 %      MagickBooleanType InvokeStaticImageFilter(const char *tag,Image **image,
110 %        const int argc,const char **argv)
111 %
112 %  A description of each parameter follows:
113 %
114 %    o tag: the module tag.
115 %
116 %    o image: the image.
117 %
118 %    o argc: the number of elements in the argument vector.
119 %
120 %    o argv: A text array containing the command line arguments.
121 %
122 %    o argv: A text array containing the command line arguments.
123 %
124 %    o exception: return any errors or warnings in this structure.
125 %
126 */
127 #if defined(MAGICKCORE_MODULES_SUPPORT)
InvokeStaticImageFilter(const char * tag,Image ** image,const int argc,const char ** argv,ExceptionInfo * exception)128 MagickExport MagickBooleanType InvokeStaticImageFilter(const char *tag,
129   Image **image,const int argc,const char **argv,ExceptionInfo *exception)
130 {
131   PolicyRights
132     rights;
133 
134   assert(image != (Image **) NULL);
135   assert((*image)->signature == MagickCoreSignature);
136   if ((*image)->debug != MagickFalse)
137     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",(*image)->filename);
138   rights=ReadPolicyRights;
139   if (IsRightsAuthorized(FilterPolicyDomain,rights,tag) == MagickFalse)
140     {
141       errno=EPERM;
142       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
143         "NotAuthorized","`%s'",tag);
144       return(MagickFalse);
145     }
146 #if defined(MAGICKCORE_MODULES_SUPPORT)
147   (void) tag;
148   (void) argc;
149   (void) argv;
150   (void) exception;
151 #else
152   {
153     extern size_t
154       analyzeImage(Image **,const int,char **,ExceptionInfo *);
155 
156     ImageFilterHandler
157       *image_filter;
158 
159     image_filter=(ImageFilterHandler *) NULL;
160     if (LocaleCompare("analyze",tag) == 0)
161       image_filter=(ImageFilterHandler *) analyzeImage;
162     if (image_filter == (ImageFilterHandler *) NULL)
163       (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
164         "UnableToLoadModule","`%s'",tag);
165     else
166       {
167         size_t
168           signature;
169 
170         if ((*image)->debug != MagickFalse)
171           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
172             "Invoking \"%s\" static image filter",tag);
173         signature=image_filter(image,argc,argv,exception);
174         if ((*image)->debug != MagickFalse)
175           (void) LogMagickEvent(CoderEvent,GetMagickModule(),"\"%s\" completes",
176             tag);
177         if (signature != MagickImageFilterSignature)
178           {
179             (void) ThrowMagickException(exception,GetMagickModule(),ModuleError,
180               "ImageFilterSignatureMismatch","'%s': %8lx != %8lx",tag,
181               (unsigned long) signature,(unsigned long)
182               MagickImageFilterSignature);
183             return(MagickFalse);
184           }
185       }
186   }
187 #endif
188   return(MagickTrue);
189 }
190 #endif
191 
192 /*
193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194 %                                                                             %
195 %                                                                             %
196 %                                                                             %
197 %   R e g i s t e r S t a t i c M o d u l e                                   %
198 %                                                                             %
199 %                                                                             %
200 %                                                                             %
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202 %
203 %  RegisterStaticModule() statically registers a module.
204 %
205 %  The format of the RegisterStaticModule method is:
206 %
207 %      MagickBooleanType RegisterStaticModule(const char module,
208 %        ExceptionInfo *exception)
209 %
210 %  A description of each parameter follows:
211 %
212 %    o module: the want to register.
213 %
214 %    o exception: return any errors or warnings in this structure.
215 %
216 */
RegisterStaticModule(const char * module,ExceptionInfo * exception)217 MagickExport MagickBooleanType RegisterStaticModule(const char *module,
218   ExceptionInfo *exception)
219 {
220   char
221     module_name[MagickPathExtent];
222 
223   PolicyRights
224     rights;
225 
226   register const CoderInfo
227     *p;
228 
229   size_t
230     extent;
231 
232   ssize_t
233     i;
234 
235   /*
236     Assign module name from alias.
237   */
238   assert(module != (const char *) NULL);
239   rights=ReadPolicyRights;
240   if (IsRightsAuthorized(ModulePolicyDomain,rights,module) == MagickFalse)
241     {
242       errno=EPERM;
243       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
244         "NotAuthorized","`%s'",module);
245       return(MagickFalse);
246     }
247   (void) CopyMagickString(module_name,module,MagickPathExtent);
248   p=GetCoderInfo(module,exception);
249   if (p != (CoderInfo *) NULL)
250     (void) CopyMagickString(module_name,p->name,MagickPathExtent);
251   extent=sizeof(MagickModules)/sizeof(MagickModules[0]);
252   for (i=0; i < (ssize_t) extent; i++)
253     if (LocaleCompare(MagickModules[i].module,module_name) == 0)
254       {
255         if (MagickModules[i].registered == MagickFalse)
256           {
257             (void) (MagickModules[i].register_module)();
258             MagickModules[i].registered=MagickTrue;
259           }
260         return(MagickTrue);
261       }
262   return(MagickFalse);
263 }
264 
265 /*
266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
267 %                                                                             %
268 %                                                                             %
269 %                                                                             %
270 %   R e g i s t e r S t a t i c M o d u l e s                                 %
271 %                                                                             %
272 %                                                                             %
273 %                                                                             %
274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275 %
276 %  RegisterStaticModules() statically registers all the available module
277 %  handlers.
278 %
279 %  The format of the RegisterStaticModules method is:
280 %
281 %      (void) RegisterStaticModules(void)
282 %
283 */
RegisterStaticModules(void)284 MagickExport void RegisterStaticModules(void)
285 {
286   size_t
287     extent;
288 
289   ssize_t
290     i;
291 
292   extent=sizeof(MagickModules)/sizeof(MagickModules[0]);
293   for (i=0; i < (ssize_t) extent; i++)
294   {
295     if (MagickModules[i].registered == MagickFalse)
296       {
297         (void) (MagickModules[i].register_module)();
298         MagickModules[i].registered=MagickTrue;
299       }
300   }
301 }
302 
303 /*
304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 %                                                                             %
306 %                                                                             %
307 %                                                                             %
308 %   U n r e g i s t e r S t a t i c M o d u l e                               %
309 %                                                                             %
310 %                                                                             %
311 %                                                                             %
312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
313 %
314 %  UnregisterStaticModule() statically unregisters the named module.
315 %
316 %  The format of the UnregisterStaticModule method is:
317 %
318 %      MagickBooleanType UnregisterStaticModule(const char *module)
319 %
320 %  A description of each parameter follows:
321 %
322 %    o module: the module we want to unregister.
323 %
324 */
UnregisterStaticModule(const char * module)325 MagickExport MagickBooleanType UnregisterStaticModule(const char *module)
326 {
327   size_t
328     extent;
329 
330   ssize_t
331     i;
332 
333   extent=sizeof(MagickModules)/sizeof(MagickModules[0]);
334   for (i=0; i < (ssize_t) extent; i++)
335     if (LocaleCompare(MagickModules[i].module,module) == 0)
336       {
337         if (MagickModules[i].registered != MagickFalse)
338           {
339             (MagickModules[i].unregister_module)();
340             MagickModules[i].registered=MagickFalse;
341           }
342         return(MagickTrue);
343       }
344   return(MagickFalse);
345 }
346 
347 /*
348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 %                                                                             %
350 %                                                                             %
351 %                                                                             %
352 %   U n r e g i s t e r S t a t i c M o d u l e s                             %
353 %                                                                             %
354 %                                                                             %
355 %                                                                             %
356 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357 %
358 %  UnregisterStaticModules() statically unregisters all the available module
359 %  handlers.
360 %
361 %  The format of the UnregisterStaticModules method is:
362 %
363 %      UnregisterStaticModules(void)
364 %
365 */
UnregisterStaticModules(void)366 MagickExport void UnregisterStaticModules(void)
367 {
368   size_t
369     extent;
370 
371   ssize_t
372     i;
373 
374   extent=sizeof(MagickModules)/sizeof(MagickModules[0]);
375   for (i=0; i < (ssize_t) extent; i++)
376   {
377     if (MagickModules[i].registered != MagickFalse)
378       {
379         (MagickModules[i].unregister_module)();
380         MagickModules[i].registered=MagickFalse;
381       }
382   }
383 }
384