media/libpng/pngmem.c

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

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.

     2 /* pngmem.c - stub functions for memory allocation
     3  *
     4  * Last changed in libpng 1.6.8 [December 19, 2013]
     5  * Copyright (c) 1998-2013 Glenn Randers-Pehrson
     6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
     7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
     8  *
     9  * This code is released under the libpng license.
    10  * For conditions of distribution and use, see the disclaimer
    11  * and license in png.h
    12  *
    13  * This file provides a location for all memory allocation.  Users who
    14  * need special memory handling are expected to supply replacement
    15  * functions for png_malloc() and png_free(), and to use
    16  * png_create_read_struct_2() and png_create_write_struct_2() to
    17  * identify the replacement functions.
    18  */
    20 #include "pngpriv.h"
    22 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
    23 /* Free a png_struct */
    24 void /* PRIVATE */
    25 png_destroy_png_struct(png_structrp png_ptr)
    26 {
    27    if (png_ptr != NULL)
    28    {
    29       /* png_free might call png_error and may certainly call
    30        * png_get_mem_ptr, so fake a temporary png_struct to support this.
    31        */
    32       png_struct dummy_struct = *png_ptr;
    33       memset(png_ptr, 0, (sizeof *png_ptr));
    34       png_free(&dummy_struct, png_ptr);
    36 #     ifdef PNG_SETJMP_SUPPORTED
    37          /* We may have a jmp_buf left to deallocate. */
    38          png_free_jmpbuf(&dummy_struct);
    39 #     endif
    40    }
    41 }
    43 /* Allocate memory.  For reasonable files, size should never exceed
    44  * 64K.  However, zlib may allocate more then 64K if you don't tell
    45  * it not to.  See zconf.h and png.h for more information.  zlib does
    46  * need to allocate exactly 64K, so whatever you call here must
    47  * have the ability to do that.
    48  */
    49 PNG_FUNCTION(png_voidp,PNGAPI
    50 png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
    51 {
    52    png_voidp ret;
    54    ret = png_malloc(png_ptr, size);
    56    if (ret != NULL)
    57       memset(ret, 0, size);
    59    return ret;
    60 }
    62 /* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
    63  * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
    64  * Checking and error handling must happen outside this routine; it returns NULL
    65  * if the allocation cannot be done (for any reason.)
    66  */
    67 PNG_FUNCTION(png_voidp /* PRIVATE */,
    68 png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
    69    PNG_ALLOCATED)
    70 {
    71    /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
    72     * allocators have also been removed in 1.6.0, so any 16-bit system now has
    73     * to implement a user memory handler.  This checks to be sure it isn't
    74     * called with big numbers.
    75     */
    76 #ifndef PNG_USER_MEM_SUPPORTED
    77    PNG_UNUSED(png_ptr)
    78 #endif
    80    if (size > 0 && size <= PNG_SIZE_MAX
    81 #     ifdef PNG_MAX_MALLOC_64K
    82          && size <= 65536U
    83 #     endif
    84       )
    85    {
    86 #ifdef PNG_USER_MEM_SUPPORTED
    87       if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
    88          return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
    90       else
    91 #endif
    92          return malloc((size_t)size); /* checked for truncation above */
    93    }
    95    else
    96       return NULL;
    97 }
    99 #if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
   100    defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
   101 /* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
   102  * that arises because of the checks in png_realloc_array that are repeated in
   103  * png_malloc_array.
   104  */
   105 static png_voidp
   106 png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
   107    size_t element_size)
   108 {
   109    png_alloc_size_t req = nelements; /* known to be > 0 */
   111    if (req <= PNG_SIZE_MAX/element_size)
   112       return png_malloc_base(png_ptr, req * element_size);
   114    /* The failure case when the request is too large */
   115    return NULL;
   116 }
   118 PNG_FUNCTION(png_voidp /* PRIVATE */,
   119 png_malloc_array,(png_const_structrp png_ptr, int nelements,
   120    size_t element_size),PNG_ALLOCATED)
   121 {
   122    if (nelements <= 0 || element_size == 0)
   123       png_error(png_ptr, "internal error: array alloc");
   125    return png_malloc_array_checked(png_ptr, nelements, element_size);
   126 }
   128 PNG_FUNCTION(png_voidp /* PRIVATE */,
   129 png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
   130    int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
   131 {
   132    /* These are internal errors: */
   133    if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
   134       (old_array == NULL && old_elements > 0))
   135       png_error(png_ptr, "internal error: array realloc");
   137    /* Check for overflow on the elements count (so the caller does not have to
   138     * check.)
   139     */
   140    if (add_elements <= INT_MAX - old_elements)
   141    {
   142       png_voidp new_array = png_malloc_array_checked(png_ptr,
   143          old_elements+add_elements, element_size);
   145       if (new_array != NULL)
   146       {
   147          /* Because png_malloc_array worked the size calculations below cannot
   148           * overflow.
   149           */
   150          if (old_elements > 0)
   151             memcpy(new_array, old_array, element_size*(unsigned)old_elements);
   153          memset((char*)new_array + element_size*(unsigned)old_elements, 0,
   154             element_size*(unsigned)add_elements);
   156          return new_array;
   157       }
   158    }
   160    return NULL; /* error */
   161 }
   162 #endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
   164 /* Various functions that have different error handling are derived from this.
   165  * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
   166  * function png_malloc_default is also provided.
   167  */
   168 PNG_FUNCTION(png_voidp,PNGAPI
   169 png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
   170 {
   171    png_voidp ret;
   173    if (png_ptr == NULL)
   174       return NULL;
   176    ret = png_malloc_base(png_ptr, size);
   178    if (ret == NULL)
   179        png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
   181    return ret;
   182 }
   184 #ifdef PNG_USER_MEM_SUPPORTED
   185 PNG_FUNCTION(png_voidp,PNGAPI
   186 png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
   187    PNG_ALLOCATED PNG_DEPRECATED)
   188 {
   189    png_voidp ret;
   191    if (png_ptr == NULL)
   192       return NULL;
   194    /* Passing 'NULL' here bypasses the application provided memory handler. */
   195    ret = png_malloc_base(NULL/*use malloc*/, size);
   197    if (ret == NULL)
   198       png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
   200    return ret;
   201 }
   202 #endif /* PNG_USER_MEM_SUPPORTED */
   204 /* This function was added at libpng version 1.2.3.  The png_malloc_warn()
   205  * function will issue a png_warning and return NULL instead of issuing a
   206  * png_error, if it fails to allocate the requested memory.
   207  */
   208 PNG_FUNCTION(png_voidp,PNGAPI
   209 png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
   210    PNG_ALLOCATED)
   211 {
   212    if (png_ptr != NULL)
   213    {
   214       png_voidp ret = png_malloc_base(png_ptr, size);
   216       if (ret != NULL)
   217          return ret;
   219       png_warning(png_ptr, "Out of memory");
   220    }
   222    return NULL;
   223 }
   225 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return
   226  * without taking any action.
   227  */
   228 void PNGAPI
   229 png_free(png_const_structrp png_ptr, png_voidp ptr)
   230 {
   231    if (png_ptr == NULL || ptr == NULL)
   232       return;
   234 #ifdef PNG_USER_MEM_SUPPORTED
   235    if (png_ptr->free_fn != NULL)
   236       png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
   238    else
   239       png_free_default(png_ptr, ptr);
   240 }
   242 PNG_FUNCTION(void,PNGAPI
   243 png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
   244 {
   245    if (png_ptr == NULL || ptr == NULL)
   246       return;
   247 #endif /* PNG_USER_MEM_SUPPORTED */
   249    free(ptr);
   250 }
   252 #ifdef PNG_USER_MEM_SUPPORTED
   253 /* This function is called when the application wants to use another method
   254  * of allocating and freeing memory.
   255  */
   256 void PNGAPI
   257 png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
   258   malloc_fn, png_free_ptr free_fn)
   259 {
   260    if (png_ptr != NULL)
   261    {
   262       png_ptr->mem_ptr = mem_ptr;
   263       png_ptr->malloc_fn = malloc_fn;
   264       png_ptr->free_fn = free_fn;
   265    }
   266 }
   268 /* This function returns a pointer to the mem_ptr associated with the user
   269  * functions.  The application should free any memory associated with this
   270  * pointer before png_write_destroy and png_read_destroy are called.
   271  */
   272 png_voidp PNGAPI
   273 png_get_mem_ptr(png_const_structrp png_ptr)
   274 {
   275    if (png_ptr == NULL)
   276       return NULL;
   278    return png_ptr->mem_ptr;
   279 }
   280 #endif /* PNG_USER_MEM_SUPPORTED */
   281 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

mercurial