Coverage Report

Created: 2025-08-12 07:37

/src/imagemagick/coders/url.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%                                                                             %
4
%                                                                             %
5
%                                                                             %
6
%                            U   U  RRRR   L                                  %
7
%                            U   U  R   R  L                                  %
8
%                            U   U  RRRR   L                                  %
9
%                            U   U  R R    L                                  %
10
%                             UUU   R  R   LLLLL                              %
11
%                                                                             %
12
%                                                                             %
13
%                        Retrieve An Image Via URL.                           %
14
%                                                                             %
15
%                              Software Design                                %
16
%                                   Cristy                                    %
17
%                              Bill Radcliffe                                 %
18
%                                March 2000                                   %
19
%                                                                             %
20
%                                                                             %
21
%  Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization         %
22
%  dedicated to making software imaging solutions freely available.           %
23
%                                                                             %
24
%  You may not use this file except in compliance with the License.  You may  %
25
%  obtain a copy of the License at                                            %
26
%                                                                             %
27
%    https://imagemagick.org/script/license.php                               %
28
%                                                                             %
29
%  Unless required by applicable law or agreed to in writing, software        %
30
%  distributed under the License is distributed on an "AS IS" BASIS,          %
31
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
32
%  See the License for the specific language governing permissions and        %
33
%  limitations under the License.                                             %
34
%                                                                             %
35
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36
%
37
%
38
*/
39

40
/*
41
  Include declarations.
42
*/
43
#include "MagickCore/studio.h"
44
#include "MagickCore/blob.h"
45
#include "MagickCore/blob-private.h"
46
#include "MagickCore/constitute.h"
47
#include "MagickCore/delegate.h"
48
#include "MagickCore/exception.h"
49
#include "MagickCore/exception-private.h"
50
#include "MagickCore/image.h"
51
#include "MagickCore/image-private.h"
52
#include "MagickCore/list.h"
53
#include "MagickCore/magick.h"
54
#include "MagickCore/memory_.h"
55
#include "MagickCore/module.h"
56
#include "MagickCore/nt-base-private.h"
57
#include "MagickCore/quantum-private.h"
58
#include "MagickCore/static.h"
59
#include "MagickCore/resource_.h"
60
#include "MagickCore/string_.h"
61
#include "MagickCore/utility.h"
62
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
63
#  include <urlmon.h>
64
#  if !defined(__MINGW32__)
65
#    pragma comment(lib, "urlmon.lib")
66
#  endif
67
#endif
68

69
/*
70
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71
%                                                                             %
72
%                                                                             %
73
%                                                                             %
74
%   R e a d U R L I m a g e                                                   %
75
%                                                                             %
76
%                                                                             %
77
%                                                                             %
78
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79
%
80
%  ReadURLImage retrieves an image via URL, decodes the image, and returns
81
%  it.  It allocates the memory necessary for the new Image structure and
82
%  returns a pointer to the new image.
83
%
84
%  The format of the ReadURLImage method is:
85
%
86
%      Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
87
%
88
%  A description of each parameter follows:
89
%
90
%    o image_info: the image info.
91
%
92
%    o exception: return any errors or warnings in this structure.
93
%
94
*/
95
96
#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
97
static Image* InvokeURLDelegate(ImageInfo* read_info,Image* image,
98
  const char *delegate,ExceptionInfo* exception)
99
0
{
100
0
  Image
101
0
    *images,
102
0
    *next;
103
104
0
  MagickBooleanType
105
0
    status;
106
107
0
  images=(Image *) NULL;
108
0
  status=InvokeDelegate(read_info,image,delegate,(char *) NULL,
109
0
    exception);
110
0
  if (status != MagickFalse)
111
0
    {
112
0
      (void) FormatLocaleString(read_info->filename,MagickPathExtent,
113
0
        "%s.dat",read_info->unique);
114
0
      *read_info->magick='\0';
115
0
      images=ReadImage(read_info,exception);
116
0
      (void) RelinquishUniqueFileResource(read_info->filename);
117
0
      if (images != (Image *) NULL)
118
0
        for (next=images; next != (Image *) NULL; next=next->next)
119
0
          (void) CopyMagickString(next->filename,image->filename,
120
0
            MagickPathExtent);
121
0
    }
122
0
  return(images);
123
0
}
124
#endif
125
126
static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
127
237
{
128
237
  char
129
237
    filename[MagickPathExtent];
130
131
237
  FILE
132
237
    *file;
133
134
237
  Image
135
237
    *image,
136
237
    *images,
137
237
    *next;
138
139
237
  ImageInfo
140
237
    *read_info;
141
142
237
  int
143
237
    unique_file;
144
145
237
  images=(Image *) NULL;
146
237
  image=AcquireImage(image_info,exception);
147
237
  read_info=CloneImageInfo(image_info);
148
237
  SetImageInfoBlob(read_info,(void *) NULL,0);
149
237
#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
150
237
  if (LocaleCompare(read_info->magick,"http") == 0)
151
0
    {
152
0
      images=InvokeURLDelegate(read_info,image,"http:decode",exception);
153
0
      read_info=DestroyImageInfo(read_info);
154
0
      image=DestroyImage(image);
155
0
      return(images);
156
0
    }
157
237
  if (LocaleCompare(read_info->magick,"https") == 0)
158
0
    {
159
0
      images=InvokeURLDelegate(read_info,image,"https:decode",exception);
160
0
      read_info=DestroyImageInfo(read_info);
161
0
      image=DestroyImage(image);
162
0
      return(images);
163
0
    }
164
237
#endif
165
237
  if (LocaleCompare(read_info->magick,"file") == 0)
166
0
    {
167
0
      (void) CopyMagickString(read_info->filename,image_info->filename+2,
168
0
        MagickPathExtent);
169
0
      *read_info->magick='\0';
170
0
      images=ReadImage(read_info,exception);
171
0
      read_info=DestroyImageInfo(read_info);
172
0
      image=DestroyImage(image);
173
0
      return(GetFirstImageInList(images));
174
0
    }
175
237
  file=(FILE *) NULL;
176
237
  unique_file=AcquireUniqueFileResource(read_info->filename);
177
237
  if (unique_file != -1)
178
237
    file=fdopen(unique_file,"wb");
179
237
  if ((unique_file == -1) || (file == (FILE *) NULL))
180
0
    {
181
0
      ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
182
0
        read_info->filename);
183
0
      read_info=DestroyImageInfo(read_info);
184
0
      image=DestroyImage(image);
185
0
      return((Image *) NULL);
186
0
    }
187
237
  (void) CopyMagickString(filename,image_info->magick,MagickPathExtent);
188
237
  (void) ConcatenateMagickString(filename,":",MagickPathExtent);
189
237
  LocaleLower(filename);
190
237
  (void) ConcatenateMagickString(filename,image_info->filename,
191
237
    MagickPathExtent);
192
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
193
  (void) fclose(file);
194
  if (URLDownloadToFile(NULL,filename,read_info->filename,0,NULL) != S_OK)
195
    {
196
      ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
197
        filename);
198
      (void) RelinquishUniqueFileResource(read_info->filename);
199
      read_info=DestroyImageInfo(read_info);
200
      image=DestroyImage(image);
201
      return((Image *) NULL);
202
    }
203
#else
204
237
  (void) fclose(file);
205
237
#endif
206
237
  *read_info->magick='\0';
207
237
  images=ReadImage(read_info,exception);
208
237
  (void) RelinquishUniqueFileResource(read_info->filename);
209
237
  if (images != (Image *) NULL)
210
0
    for (next=images; next != (Image *) NULL; next=next->next)
211
0
      (void) CopyMagickString(next->filename,image->filename,MagickPathExtent);
212
237
  read_info=DestroyImageInfo(read_info);
213
237
  image=DestroyImage(image);
214
237
  if (images != (Image *) NULL)
215
0
    GetPathComponent(image_info->filename,TailPath,images->filename);
216
237
  else
217
237
    {
218
237
      (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
219
237
        "NoDataReturned","`%s'",filename);
220
237
      return((Image *) NULL);
221
237
    }
222
0
  return(GetFirstImageInList(images));
223
237
}
224

225
/*
226
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227
%                                                                             %
228
%                                                                             %
229
%                                                                             %
230
%   R e g i s t e r U R L I m a g e                                           %
231
%                                                                             %
232
%                                                                             %
233
%                                                                             %
234
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235
%
236
%  RegisterURLImage() adds attributes for the URL image format to
237
%  the list of supported formats.  The attributes include the image format
238
%  tag, a method to read and/or write the format, whether the format
239
%  supports the saving of more than one frame to the same file or blob,
240
%  whether the format supports native in-memory I/O, and a brief
241
%  description of the format.
242
%
243
%  The format of the RegisterURLImage method is:
244
%
245
%      size_t RegisterURLImage(void)
246
%
247
*/
248
ModuleExport size_t RegisterURLImage(void)
249
7
{
250
7
  MagickInfo
251
7
    *entry;
252
253
7
  entry=AcquireMagickInfo("URL","HTTP","Uniform Resource Locator (http://)");
254
7
  entry->decoder=(DecodeImageHandler *) ReadURLImage;
255
7
  entry->format_type=ImplicitFormatType;
256
7
  (void) RegisterMagickInfo(entry);
257
7
  entry=AcquireMagickInfo("URL","HTTPS","Uniform Resource Locator (https://)");
258
7
  entry->decoder=(DecodeImageHandler *) ReadURLImage;
259
7
  entry->format_type=ImplicitFormatType;
260
7
  (void) RegisterMagickInfo(entry);
261
7
  entry=AcquireMagickInfo("URL","FTP","Uniform Resource Locator (ftp://)");
262
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
263
  entry->decoder=(DecodeImageHandler *) ReadURLImage;
264
#endif
265
7
  entry->format_type=ImplicitFormatType;
266
7
  (void) RegisterMagickInfo(entry);
267
7
  entry=AcquireMagickInfo("URL","FILE","Uniform Resource Locator (file://)");
268
7
  entry->decoder=(DecodeImageHandler *) ReadURLImage;
269
7
  entry->format_type=ImplicitFormatType;
270
7
  (void) RegisterMagickInfo(entry);
271
7
  return(MagickImageCoderSignature);
272
7
}
273

274
/*
275
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276
%                                                                             %
277
%                                                                             %
278
%                                                                             %
279
%   U n r e g i s t e r U R L I m a g e                                       %
280
%                                                                             %
281
%                                                                             %
282
%                                                                             %
283
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284
%
285
%  UnregisterURLImage() removes format registrations made by the
286
%  URL module from the list of supported formats.
287
%
288
%  The format of the UnregisterURLImage method is:
289
%
290
%      UnregisterURLImage(void)
291
%
292
*/
293
ModuleExport void UnregisterURLImage(void)
294
0
{
295
0
  (void) UnregisterMagickInfo("HTTP");
296
0
  (void) UnregisterMagickInfo("FTP");
297
0
  (void) UnregisterMagickInfo("FILE");
298
0
}