Branch: Tag:

2005-11-03

2005-11-03 16:08:51 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Cleaned up and fixed several minor leaks in load_font().

Rev: src/modules/Image/font.c:1.88

2:   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: font.c,v 1.87 2005/08/15 17:00:39 grubba Exp $ + || $Id: font.c,v 1.88 2005/11/03 16:08:51 grubba Exp $   */      #include "global.h"
183:    if (font->mem && font->mem!=image_default_font)    {   #ifdef HAVE_MMAP +  if (font->mmaped_size) {    munmap(font->mem,font->mmaped_size); -  +  } else   #else    free(font->mem);   #endif -  +  font->mem = NULL;    }    free(font);    }
220:    return this->charinfo[c].width;   }    - #ifndef HAVE_MMAP - static INLINE ptrdiff_t my_read(int from, void *t, size_t towrite) + static INLINE ptrdiff_t my_read(int fd, void *t, size_t towrite)   {    ptrdiff_t res; -  while((res = fd_read(from, t, towrite)) < 0) +  while((res = fd_read(fd, t, towrite)) < 0)    {    switch(errno)    {
238: Inside #if undefined(HAVE_MMAP)
   }    return res;   } - #endif +       static INLINE off_t file_size(int fd)   {
290:    *! @[write]    */    - /*! @decl void create(string filename) -  *! Loads a font file to this font object. -  *! Similar to @[load()]. -  */ + #ifndef MAP_FAILED + #define MAP_FAILED ((void *)-1) + #endif    - void font_load(INT32 args); -  - void font_create(INT32 args) - { -  font_load(args); -  pop_stack(); - } -  +    void font_load(INT32 args)   { -  int fd = -1; -  size_t size; -  -  if (THIS) +  struct file_head    { -  free_font_struct(THIS); -  THIS=NULL; -  } +  unsigned INT32 cookie; +  unsigned INT32 version; +  unsigned INT32 chars; +  unsigned INT32 height; +  unsigned INT32 baseline; +  unsigned INT32 o[1]; +  } *fh = NULL; + #ifdef HAVE_MMAP +  size_t mmaped_size = 0; + #endif +  size_t size = 0;    -  +  if (args && Pike_sp[-args].type != T_STRING) +  Pike_error("font->read: illegal or wrong number of arguments\n"); +     if (!args)    { -  THIS=(struct font *)xalloc(sizeof(struct font)); -  THIS->mem=(void *)image_default_font; -  size=IMAGE_DEFAULT_FONT_SIZE; -  goto loading_default; -  } +  fh = (struct file_head *)image_default_font; +  size = IMAGE_DEFAULT_FONT_SIZE; +  } else { +  int fd = -1;    -  if (sp[-args].type!=T_STRING) -  Pike_error("font->read: illegal or wrong number of arguments\n"); -  +     do    {   #ifdef FONT_DEBUG
336:       if (fd >= 0)    { -  struct font *new_font; -  +     size = (size_t) file_size(fd);    if (size > 0)    { -  new_font=(struct font *)xalloc(sizeof(struct font)); -  +     THREADS_ALLOW();   #ifdef HAVE_MMAP -  new_font->mem = -  mmap(0,size,PROT_READ,MAP_SHARED,fd,0); - #ifdef MAP_FAILED -  if ((char *)new_font->mem == (char *)MAP_FAILED) - #else -  if (new_font->mem==(void*)-1) - #endif -  { -  new_font->mem=0; -  new_font->mmaped_size=0; -  } +  fh = (struct file_head *) +  mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); +  if (fh != (struct file_head *)MAP_FAILED) +  mmaped_size = size;    else -  new_font->mmaped_size=size; - #else -  new_font->mem = malloc(size); +  { + #endif +  fh = (struct file_head *)malloc(size);   #ifdef FONT_DEBUG -  fprintf(stderr,"FONT Malloced %p (%d)\n",new_font->mem,size); +  fprintf(stderr,"FONT Malloced %p (%d)\n", fh, size);   #endif -  if ((new_font->mem) && (!my_read(fd,new_font->mem,size))) +  if (fh && (!my_read(fd, fh, size)))    { -  free(new_font->mem); -  new_font->mem = NULL; +  free(fh); +  fh = NULL;    } -  + #ifdef HAVE_MMAP +  }   #endif    THREADS_DISALLOW();    -  +  } /* size failure */ + #ifdef FONT_DEBUG +  else fprintf(stderr,"FONT size failure\n"); + #endif +  fd_close(fd); +  } /* fd failure */ + #ifdef FONT_DEBUG +  else fprintf(stderr,"FONT fd failure\n"); + #endif +  } +     if (THIS) -  /* In case font_load got called again in the THREADS_ALLOW block. */ +  {    free_font_struct(THIS); -  THIS = new_font; +  THIS=NULL; +  }    - loading_default: -  -  if (THIS->mem) +  if (fh)    { -  struct file_head -  { -  unsigned INT32 cookie; -  unsigned INT32 version; -  unsigned INT32 chars; -  unsigned INT32 height; -  unsigned INT32 baseline; -  unsigned INT32 o[1]; -  } *fh; +     struct char_head    {    unsigned INT32 width;
400:    fprintf(stderr,"FONT mapped ok\n");   #endif    -  fh=(struct file_head*)THIS->mem; -  +     if (ntohl(fh->cookie)==0x464f4e54) /* "FONT" */    {   #ifdef FONT_DEBUG
409:   #endif    if (ntohl(fh->version)==1)    { +  struct font *new_font; +  unsigned long num_chars;    unsigned long i;      #ifdef FONT_DEBUG    fprintf(stderr,"FONT version 1\n");   #endif    -  THIS->chars=ntohl(fh->chars); +  num_chars = ntohl(fh->chars);       new_font=malloc(sizeof(struct font)+ -  sizeof(struct _char)*(THIS->chars-1)); +  sizeof(struct _char)*(num_chars-1));    if(!new_font) { -  free(THIS); +  if (args) { + #ifdef HAVE_MMAP +  if (mmaped_size) +  munmap((void *)fh, mmaped_size); +  else + #endif +  free(fh); +  }    SIMPLE_OUT_OF_MEMORY_ERROR(0,0);    } -  new_font->mem=THIS->mem; +  +  new_font->mem = (void *)fh;   #ifdef HAVE_MMAP -  new_font->mmaped_size=THIS->mmaped_size; +  new_font->mmaped_size = mmaped_size;   #endif -  new_font->chars=THIS->chars; +  new_font->chars = num_chars;    new_font->xspacing_scale = 1.0;    new_font->yspacing_scale = 1.0;    new_font->justification = J_LEFT; -  free(THIS); -  THIS=new_font; +  new_font->height=ntohl(fh->height); +  new_font->baseline=ntohl(fh->baseline);    -  THIS->height=ntohl(fh->height); -  THIS->baseline=ntohl(fh->baseline); -  -  for (i=0; i<THIS->chars; i++) +  for (i=0; i<num_chars; i++)    { -  if (i*sizeof(INT32)<(size_t)size -  && ntohl(fh->o[i])<(size_t)size +  if (i*sizeof(INT32)<size +  && ntohl(fh->o[i])<size    && ! ( ntohl(fh->o[i]) % 4) ) /* must be aligned */    { -  ch=(struct char_head*) -  ((char *)(THIS->mem)+ntohl(fh->o[i])); -  THIS->charinfo[i].width = ntohl(ch->width); -  THIS->charinfo[i].spacing = ntohl(ch->spacing); -  THIS->charinfo[i].pixels = ch->data; +  ch = (struct char_head*) +  (((char *)(fh)) + ntohl(fh->o[i])); +  new_font->charinfo[i].width = ntohl(ch->width); +  new_font->charinfo[i].spacing = ntohl(ch->spacing); +  new_font->charinfo[i].pixels = ch->data;    }    else /* illegal <tm> offset or illegal align */    {
456:    i,i,i);   #endif    free_font_struct(new_font); -  THIS=NULL; -  if (fd >= 0) { -  fd_close(fd); -  } +     pop_n_elems(args);    push_int(0);    return;    } -  +     }    -  if (!args) goto done; -  -  fd_close(fd); +     pop_n_elems(args); -  +  THIS = new_font;    ref_push_object(THISOBJ); /* success */   #ifdef FONT_DEBUG    fprintf(stderr,"FONT successfully loaded\n");
484: Inside #if defined(FONT_DEBUG)
  #ifdef FONT_DEBUG    else fprintf(stderr,"FONT wrong cookie\n");   #endif -  if (!args) goto done; /* just in case */ +  if (args) { + #ifdef HAVE_MMAP +  if (mmaped_size) +  munmap((void *)fh, mmaped_size); +  else + #endif +  free(fh); +  }    } /* mem failure */   #ifdef FONT_DEBUG    else fprintf(stderr,"FONT mem failure\n");   #endif -  free_font_struct(THIS); -  THIS=NULL; -  } /* size failure */ - #ifdef FONT_DEBUG -  else fprintf(stderr,"FONT size failure\n"); - #endif -  fd_close(fd); -  } /* fd failure */ - #ifdef FONT_DEBUG -  else fprintf(stderr,"FONT fd failure\n"); - #endif +     - done: -  +     pop_n_elems(args);    push_int(0);    return;   }    -  + /*! @decl void create(string filename) +  *! Loads a font file to this font object. +  *! Similar to @[load()]. +  */ +  + void font_create(INT32 args) + { +  font_load(args); +  pop_stack(); + } +    /*! @decl Image.Image write(string text, string ... more_text_lines)    *! Writes some text; thus creating an image object    *! that can be used as mask or as a complete picture.
705:    Pike_fatal("Illegal shift size!\n");    }    } -  UNSET_ONERROR(err); -  free(width_of); +  CALL_AND_UNSET_ONERROR(err);       pop_n_elems(args);    push_object(o);