Coverage Report

Created: 2025-08-11 08:01

/src/graphicsmagick/magick/registry.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
% Copyright (C) 2003-2009 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
%
5
% This program is covered by multiple licenses, which are described in
6
% Copyright.txt. You should have received a copy of Copyright.txt with this
7
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
8
%
9
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
%                                                                             %
11
%                                                                             %
12
%                                                                             %
13
%           RRRR    EEEEE    GGG   IIIII  SSSSS  TTTTT  RRRR   Y   Y          %
14
%           R   R   E       G        I    SS       T    R   R   Y Y           %
15
%           RRRR    EEE     G GGG    I     SSS     T    RRRR     Y            %
16
%           R R     E       G   G    I       SS    T    R R      Y            %
17
%           R  R    EEEEE    GGG   IIIII  SSSSS    T    R  R     Y            %
18
%                                                                             %
19
%                                                                             %
20
%                          GraphicsMagick Registry.                           %
21
%                                                                             %
22
%                                                                             %
23
%                              Software Design                                %
24
%                                John Cristy                                  %
25
%                                October 2001                                 %
26
%                                                                             %
27
%                                                                             %
28
%                                                                             %
29
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
30
%
31
%
32
*/
33

34
/*
35
  Include declarations.
36
*/
37
#include "magick/studio.h"
38
#include "magick/registry.h"
39
#include "magick/semaphore.h"
40
#include "magick/utility.h"
41
/*
42
  Typedef declarations.
43
*/
44
typedef struct _RegistryInfo
45
{
46
  long
47
    id;
48
49
  RegistryType
50
    type;
51
52
  void
53
    *blob;
54
55
  size_t
56
    length;
57
58
  unsigned long
59
    signature;
60
61
  struct _RegistryInfo
62
    *previous,
63
    *next;
64
} RegistryInfo;
65

66
/*
67
  Global declarations.
68
*/
69
static SemaphoreInfo
70
  *registry_semaphore = (SemaphoreInfo *) NULL;
71
72
static long
73
  current_id = 0;
74
75
static RegistryInfo
76
  *registry_list = (RegistryInfo *) NULL;
77

78
/*
79
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80
%                                                                             %
81
%                                                                             %
82
%                                                                             %
83
%   D e l e t e M a g i c k R e g i s t r y                                   %
84
%                                                                             %
85
%                                                                             %
86
%                                                                             %
87
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88
%
89
%  DeleteMagickRegistry() deletes an entry in the registry as defined by the
90
%  id.  It returns MagickPass if the entry is deleted otherwise MagickFail if
91
%  no entry is found in the registry that matches the id.
92
%
93
%  The format of the DeleteMagickRegistry method is:
94
%
95
%      MagickPassFail DeleteMagickRegistry(const long id)
96
%
97
%  A description of each parameter follows:
98
%
99
%    o id: The registry id.
100
%
101
%
102
*/
103
MagickExport MagickPassFail DeleteMagickRegistry(const long id)
104
0
{
105
0
  register RegistryInfo
106
0
    *p;
107
108
0
  RegistryInfo
109
0
    *registry_info;
110
111
0
  LockSemaphoreInfo(registry_semaphore);
112
0
  for (p=registry_list; p != (RegistryInfo *) NULL; p=p->next)
113
0
  {
114
0
    if (id != p->id)
115
0
      continue;
116
0
    registry_info=p;
117
0
    switch (registry_info->type)
118
0
    {
119
0
      case ImageRegistryType:
120
0
      {
121
0
        DestroyImage((Image *) registry_info->blob);
122
0
        break;
123
0
      }
124
0
      case ImageInfoRegistryType:
125
0
      {
126
0
        DestroyImageInfo((ImageInfo *) registry_info->blob);
127
0
        break;
128
0
      }
129
0
      default:
130
0
      {
131
0
        MagickFreeMemory(registry_info->blob);
132
0
        break;
133
0
      }
134
0
    }
135
0
    if (registry_info == registry_list)
136
0
      registry_list=registry_info->next;
137
0
    if (registry_info->previous != (RegistryInfo *) NULL)
138
0
      registry_info->previous->next=registry_info->next;
139
0
    if (registry_info->next != (RegistryInfo *) NULL)
140
0
      registry_info->next->previous=registry_info->previous;
141
0
    MagickFreeMemory(registry_info);
142
0
    registry_info=(RegistryInfo *) NULL;
143
0
    break;
144
0
  }
145
0
  UnlockSemaphoreInfo(registry_semaphore);
146
0
  return ((p != (RegistryInfo *) NULL) ? MagickPass : MagickFail);
147
0
}
148

149
/*
150
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151
%                                                                             %
152
%                                                                             %
153
%                                                                             %
154
+   D e s t r o y M a g i c k R e g i s t r y                                 %
155
%                                                                             %
156
%                                                                             %
157
%                                                                             %
158
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159
%
160
%  DestroyMagickRegistry() deallocates memory associated the magick registry.
161
%
162
%  The format of the DestroyMagickRegistry method is:
163
%
164
%       void DestroyMagickRegistry(void)
165
%
166
%
167
*/
168
void DestroyMagickRegistry(void)
169
0
{
170
0
  register RegistryInfo
171
0
    *p;
172
173
0
  RegistryInfo
174
0
    *registry_info;
175
176
0
  for (p=registry_list; p != (RegistryInfo *) NULL; )
177
0
  {
178
0
    registry_info=p;
179
0
    p=p->next;
180
0
    switch (registry_info->type)
181
0
    {
182
0
      case ImageRegistryType:
183
0
      {
184
0
        DestroyImage((Image *) registry_info->blob);
185
0
        break;
186
0
      }
187
0
      case ImageInfoRegistryType:
188
0
      {
189
0
        DestroyImageInfo((ImageInfo *) registry_info->blob);
190
0
        break;
191
0
      }
192
0
      default:
193
0
      {
194
0
        MagickFreeMemory(registry_info->blob);
195
0
        break;
196
0
      }
197
0
    }
198
0
    MagickFreeMemory(registry_info);
199
0
  }
200
0
  registry_list=(RegistryInfo *) NULL;
201
0
  current_id = 0;
202
0
  DestroySemaphoreInfo(&registry_semaphore);
203
0
}
204

205
/*
206
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207
%                                                                             %
208
%                                                                             %
209
%                                                                             %
210
%   G e t I m a g e F r o m M a g i c k R e g i s t r y                       %
211
%                                                                             %
212
%                                                                             %
213
%                                                                             %
214
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
215
%
216
%  GetImageFromMagickRegistry() gets an image from the registry as defined by
217
%  its name.  If the blob that matches the name is not found, NULL is returned.
218
%
219
%  The format of the GetImageFromMagickRegistry method is:
220
%
221
%      Image *GetImageFromMagickRegistry(const char *name,long *id,
222
%        ExceptionInfo *exception)
223
%
224
%  A description of each parameter follows:
225
%
226
%    o name: The name of the image to retrieve from the registry.
227
%
228
%    o id: The registry id.
229
%
230
%    o exception: Return any errors or warnings in this structure.
231
%
232
%
233
*/
234
MagickExport Image *GetImageFromMagickRegistry(const char *name,long *id,
235
  ExceptionInfo *exception)
236
0
{
237
0
  Image
238
0
    *image;
239
240
0
  register RegistryInfo
241
0
    *p;
242
243
0
  *id=(-1);
244
0
  image=(Image *) NULL;
245
0
  LockSemaphoreInfo(registry_semaphore);
246
0
  for (p=registry_list; p != (RegistryInfo *) NULL; p=p->next)
247
0
  {
248
0
    if (p->type != ImageRegistryType)
249
0
      continue;
250
0
    if (LocaleCompare(((Image *) p->blob)->filename,name) == 0)
251
0
      {
252
0
        *id=p->id;
253
0
        image=CloneImageList((Image *) p->blob,exception);
254
0
        break;
255
0
      }
256
0
  }
257
0
  UnlockSemaphoreInfo(registry_semaphore);
258
0
  if (image == (Image *) NULL)
259
0
    ThrowException(exception,RegistryError,UnableToLocateImage,name);
260
0
  return (image);
261
0
}
262

263
/*
264
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265
%                                                                             %
266
%                                                                             %
267
%                                                                             %
268
%   G e t M a g i c k R e g i s t r y                                         %
269
%                                                                             %
270
%                                                                             %
271
%                                                                             %
272
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273
%
274
%  GetMagickRegistry() gets a blob from the registry as defined by the id.  If
275
%  the blob that matches the id is not found, NULL is returned.
276
%
277
%  The format of the GetMagickRegistry method is:
278
%
279
%      const void *GetMagickRegistry(const long id,RegistryType *type,
280
%        size_t *length,ExceptionInfo *exception)
281
%
282
%  A description of each parameter follows:
283
%
284
%    o id: The registry id.
285
%
286
%    o type: The registry type.
287
%
288
%    o length: The blob length in number of bytes.
289
%
290
%    o exception: Return any errors or warnings in this structure.
291
%
292
%
293
*/
294
MagickExport void *GetMagickRegistry(const long id,RegistryType *type,
295
  size_t *length,ExceptionInfo *exception)
296
0
{
297
0
  register RegistryInfo
298
0
    *p;
299
300
0
  void
301
0
    *blob;
302
303
0
  RegistryInfo
304
0
    *registry_info;
305
306
0
  blob=(void *) NULL;
307
0
  *type=UndefinedRegistryType;
308
0
  *length=0;
309
0
  LockSemaphoreInfo(registry_semaphore);
310
0
  for (p=registry_list; p != (RegistryInfo *) NULL; p=p->next)
311
0
  {
312
0
    if (id != p->id)
313
0
      continue;
314
0
    registry_info=p;
315
0
    switch (registry_info->type)
316
0
    {
317
0
      case ImageRegistryType:
318
0
      {
319
0
        Image
320
0
          *image;
321
322
0
        image=(Image *) registry_info->blob;
323
0
        blob=(void *) CloneImageList(image,exception);
324
0
        break;
325
0
      }
326
0
      case ImageInfoRegistryType:
327
0
      {
328
0
        ImageInfo
329
0
          *image_info;
330
331
0
        image_info=(ImageInfo *) registry_info->blob;
332
0
        blob=(void *) CloneImageInfo(image_info);
333
0
        break;
334
0
      }
335
0
      default:
336
0
      {
337
0
        blob=MagickAllocateMemory(void *,registry_info->length);
338
0
        if (blob == (void *) NULL)
339
0
          {
340
0
            ThrowException3(exception,ResourceLimitError,
341
0
              MemoryAllocationFailed,UnableToGetFromRegistry);
342
0
            break;
343
0
          }
344
0
        (void) memcpy(blob,registry_info->blob,registry_info->length);
345
0
        break;
346
0
      }
347
0
    }
348
0
    *type=registry_info->type;
349
0
    *length=registry_info->length;
350
0
    break;
351
0
  }
352
0
  UnlockSemaphoreInfo(registry_semaphore);
353
0
  if (blob == (void *) NULL)
354
0
    {
355
0
      char
356
0
        description[MaxTextExtent];
357
358
0
      FormatString(description,"id=%ld",id);
359
0
      ThrowException(exception,RegistryError,UnableToLocateImage,
360
0
        description);
361
0
    }
362
0
  return(blob);
363
0
}
364

365
/*
366
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367
%                                                                             %
368
%                                                                             %
369
%                                                                             %
370
+   I n i t i a l i z e M a g i c k R e g i s t r y                           %
371
%                                                                             %
372
%                                                                             %
373
%                                                                             %
374
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375
%
376
%  InitializeMagickRegistry() ensures that the magick registry is ready for
377
%  use.
378
%
379
%  The format of the InitializeMagickRegistry method is:
380
%
381
%       void InitializeMagickRegistry(void)
382
%
383
%
384
*/
385
void InitializeMagickRegistry(void)
386
250
{
387
250
  assert(registry_semaphore == (SemaphoreInfo *) NULL);
388
250
  registry_semaphore=AllocateSemaphoreInfo();
389
250
  current_id = 0;
390
250
  registry_list = (RegistryInfo *) NULL;
391
250
}
392

393
/*
394
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395
%                                                                             %
396
%                                                                             %
397
%                                                                             %
398
%   S e t M a g i c k R e g i s t r y                                         %
399
%                                                                             %
400
%                                                                             %
401
%                                                                             %
402
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403
%
404
%  SetMagickRegistry() sets a blob into the registry and returns a unique ID.
405
%  If an error occurs, -1 is returned.
406
%
407
%  The format of the SetMagickRegistry method is:
408
%
409
%      long SetMagickRegistry(const RegistryType type,const void *blob,
410
%        const size_t length,ExceptionInfo *exception)
411
%
412
%  A description of each parameter follows:
413
%
414
%    o type: The registry type.
415
%
416
%    o blob: The address of a Binary Large OBject.
417
%
418
%    o length: For a registry type of ImageRegistryType use sizeof(Image)
419
%      otherwise the blob length in number of bytes.
420
%
421
%    o exception: Return any errors or warnings in this structure.
422
%
423
%
424
*/
425
MagickExport long SetMagickRegistry(const RegistryType type,const void *blob,
426
  const size_t length,ExceptionInfo *exception)
427
0
{
428
0
  RegistryInfo
429
0
    *registry_info;
430
431
0
  void
432
0
    *clone_blob;
433
434
0
  switch (type)
435
0
  {
436
0
    case ImageRegistryType:
437
0
    {
438
0
      Image
439
0
        *image;
440
441
0
      image=(Image *) blob;
442
0
      if (length != sizeof(Image))
443
0
        {
444
0
          ThrowException3(exception,RegistryError,UnableToSetRegistry,
445
0
            StructureSizeMismatch);
446
0
          return(-1);
447
0
        }
448
0
      if (image->signature != MagickSignature)
449
0
        {
450
0
          ThrowException3(exception,RegistryError,UnableToSetRegistry,
451
0
            ImageExpected);
452
0
          return(-1);
453
0
        }
454
0
      clone_blob=(void *) CloneImageList(image,exception);
455
0
      if (clone_blob == (void *) NULL)
456
0
        return(-1);
457
0
      break;
458
0
    }
459
0
    case ImageInfoRegistryType:
460
0
    {
461
0
      ImageInfo
462
0
        *image_info;
463
464
0
      image_info=(ImageInfo *) blob;
465
0
      if (length != sizeof(ImageInfo))
466
0
        {
467
0
          ThrowException3(exception,RegistryError,UnableToSetRegistry,
468
0
            StructureSizeMismatch);
469
0
          return(-1);
470
0
        }
471
0
      if (image_info->signature != MagickSignature)
472
0
        {
473
0
          ThrowException3(exception,RegistryError,UnableToSetRegistry,
474
0
            ImageInfoExpected);
475
0
          return(-1);
476
0
        }
477
0
      clone_blob=(void *) CloneImageInfo(image_info);
478
0
      if (clone_blob == (void *) NULL)
479
0
        return(-1);
480
0
      break;
481
0
    }
482
0
    default:
483
0
    {
484
0
      clone_blob=MagickAllocateMemory(void *,length);
485
0
      if (clone_blob == (void *) NULL)
486
0
        return(-1);
487
0
      (void) memcpy(clone_blob,blob,length);
488
0
    }
489
0
  }
490
0
  registry_info=MagickAllocateMemory(RegistryInfo *,sizeof(RegistryInfo));
491
0
  if (registry_info == (RegistryInfo *) NULL)
492
0
    MagickFatalError3(ResourceLimitFatalError,MemoryAllocationFailed,
493
0
      UnableToAllocateRegistryInfo);
494
0
  (void) memset(registry_info,0,sizeof(RegistryInfo));
495
0
  registry_info->type=type;
496
0
  registry_info->blob=clone_blob;
497
0
  registry_info->length=length;
498
0
  registry_info->signature=MagickSignature;
499
0
  LockSemaphoreInfo(registry_semaphore);
500
0
  registry_info->id=current_id++;
501
0
  if (registry_list == (RegistryInfo *) NULL)
502
0
    registry_list=registry_info;
503
0
  else
504
0
    {
505
0
      register RegistryInfo
506
0
        *p;
507
508
0
      for (p=registry_list; p->next != (RegistryInfo *) NULL; p=p->next);
509
0
      registry_info->previous=p;
510
0
      p->next=registry_info;
511
0
    }
512
0
  UnlockSemaphoreInfo(registry_semaphore);
513
0
  return (registry_info->id);
514
0
}