Changeset 835:6f4b052f193a for charset.c

Show
Ignore:
Timestamp:
1999-02-03 14:14:08 (10 years ago)
Author:
Thomas Roessler <roessler@…>
Branch:
HEAD
Message:

[unstable] Produce some reasonable character set support when
postponing messages.

Additionally, this patch fixes a nasty pointer leak in
load_charset() [noted with electric fence], and a completely
mis-lead attempt to use bsearch(). Apparently, nobody ever tested
the utf8 decoder for quite some time.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • charset.c

    r827 r835  
    3333#include <dirent.h> 
    3434#include <unistd.h> 
     35#include <errno.h> 
    3536 
    3637#include "mutt.h" 
     
    7879static void canonical_charset (char *dest, size_t dlen, const char *name) 
    7980{ 
    80   int i; 
     81  size_t i; 
    8182 
    8283  if (!strncasecmp (name, "x-", 2)) 
     
    9798{ 
    9899  CHARSET *cp = safe_malloc (sizeof (CHARSET)); 
    99   short i; 
     100  size_t i; 
    100101 
    101102  cp->n_symb = 256; 
     
    245246  for (s = symbol, d = symbol; *s; *d++ = *s++) 
    246247  { 
    247     if (*s == m->escape_char) 
    248       s++; 
    249   } 
    250  
     248    if (*s == m->escape_char && !*++s) 
     249      break; 
     250  } 
     251   
    251252  *d = *s; 
    252253} 
     
    421422    else if (i == CL_DESCR) 
    422423    { 
    423       dprint (5, (debugfile, "load_charset: Got character description: < %s > -> %x\n", 
     424      dprint (5, (debugfile, "load_charset: Got character description: <%s> -> %x\n", 
    424425                  cd->symbol, cd->repr)); 
    425       hash_delete (cs->symb_to_repr, cd->symbol, NULL, NULL); 
    426       hash_insert (cs->symb_to_repr, cd->symbol, cd, 0); 
    427426 
    428427      if (!multbyte) 
     
    430429        if (0 <= cd->repr && cd->repr < 256) 
    431430        { 
     431          hash_delete (cs->symb_to_repr, cd->symbol, NULL, NULL); 
     432          hash_insert (cs->symb_to_repr, cd->symbol, cd, 0); 
     433 
    432434          if (cs->description[cd->repr]) 
     435          { 
     436            hash_delete (cs->symb_to_repr, cs->description[cd->repr]->symbol, cs->description[cd->repr], NULL); 
    433437            chardesc_free (&cs->description[cd->repr]); 
     438          } 
    434439          else 
    435440            cs->u_symb++; 
     
    451456          cs->n_symb = new_size; 
    452457        } 
    453  
     458        hash_delete (cs->symb_to_repr, cd->symbol, NULL, NULL); 
     459        hash_insert (cs->symb_to_repr, cd->symbol, cd, 0); 
    454460        cs->description[cs->u_symb++] = cd; 
    455461        cd = NULL; 
    456462      } 
    457463    } 
    458  
     464    if (cd) 
     465    { 
     466      dprint (5, (debugfile, "load_charset: character description still present: <%s>->%x\n", 
     467                  cd->symbol, cd->repr)); 
     468    } 
    459469    chardesc_free (&cd); 
    460470  } 
     
    477487static CHARDESC *repr2descr (int repr, CHARSET * cs) 
    478488{ 
    479   CHARDESC key; 
    480  
     489  CHARDESC *key; 
     490  CHARDESC **r; 
     491   
    481492  if (!cs || repr < 0) 
    482493    return NULL; 
     
    490501  } 
    491502 
    492   key.repr = repr; 
    493   return bsearch (&key, cs->description, cs->u_symb, 
    494                   sizeof (CHARDESC *), _cd_compar); 
     503  key = safe_malloc (sizeof(CHARDESC)); 
     504  key->repr = repr; 
     505  key->symbol = "<unknown>"; /* otherwise, the 
     506                             * debug code may  
     507                             * segfault. ouch. 
     508                             */ 
     509 
     510  r = bsearch (&key, cs->description, cs->u_symb, 
     511               sizeof (CHARDESC *), _cd_compar); 
     512 
     513  safe_free ((void **) &key); 
     514 
     515  if (r) return *r; 
     516   
     517  return NULL; 
    495518} 
    496519 
     
    833856static struct utf8_state *new_utf8_state (void) 
    834857{ 
    835   return safe_calloc (sizeof (struct utf8_state), 1); 
     858  return safe_calloc (1, sizeof (struct utf8_state)); 
    836859} 
    837860 
     
    879902    { 
    880903      sfu->blen = (sfu->blen + 80) * 2; 
    881       safe_realloc((void **) &sfu->buffer, sfu->blen); 
     904      safe_realloc((void **) &sfu->buffer, sfu->blen + 1); 
    882905    } 
    883906    sfu->buffer[sfu->bp++] = u; 
     
    889912DECODER *mutt_open_decoder (STATE *s, BODY *b, int istext) 
    890913{ 
    891   DECODER *dp = safe_calloc (sizeof (DECODER), 1); 
     914  DECODER *dp = safe_calloc (1, sizeof (DECODER)); 
    892915   
    893916  dp->s = s; 
     
    931954    state_prefix_putc (mutt_display_char ((unsigned char) c, dp->map), dp->s); 
    932955} 
     956 
     957/* FIXME: utf-8 support */ 
     958 
     959int mutt_recode_file (const char *fname, const char *src, const char *dest) 
     960{ 
     961  FILE *fp, *tmpfp; 
     962  char tempfile[_POSIX_PATH_MAX]; 
     963  int c; 
     964  int rv = -1; 
     965   
     966  CHARSET_MAP *map; 
     967 
     968  if (mutt_is_utf8 (dest) ^ mutt_is_utf8(src)) 
     969  { 
     970    mutt_error (_("We can't currently handle utf-8 at this point.")); 
     971    return -1; 
     972  } 
     973 
     974  if ((fp = fopen (fname, "r+")) == NULL) 
     975  { 
     976    mutt_error (_("Can't open %s: %s."), fname, strerror (errno)); 
     977    return -1; 
     978  } 
     979   
     980  mutt_mktemp (tempfile); 
     981  if ((tmpfp = safe_fopen (tempfile, "w+")) == NULL) 
     982  { 
     983    mutt_error (_("Can't open %s: %s."), tempfile, strerror (errno)); 
     984    fclose (fp); 
     985    return -1; 
     986  } 
     987 
     988  map = mutt_get_translation (src, dest); 
     989   
     990  while ((c = fgetc (fp)) != EOF) 
     991    if (fputc (mutt_display_char ((unsigned char) c, map), tmpfp) == EOF) 
     992      goto bail; 
     993 
     994  fclose (fp); fp = NULL; 
     995  rewind (tmpfp); 
     996 
     997  /* don't use safe_fopen here - we're just going 
     998   * to overwrite the old file. 
     999   */ 
     1000 
     1001  if ((fp = fopen (fname, "w")) == NULL) 
     1002    goto bail; 
     1003   
     1004  while ((c = fgetc (tmpfp)) != EOF) 
     1005    if (fputc (c, fp) == EOF) 
     1006      goto bail; 
     1007 
     1008  rv = 0; 
     1009  unlink (tempfile); 
     1010   
     1011bail: 
     1012  if (rv == -1) 
     1013    mutt_error (_("Error while recoding %s. See %s for recovering your data."), 
     1014                fname, tempfile); 
     1015 
     1016  if (fp) fclose (fp); 
     1017  if (tmpfp) fclose (tmpfp); 
     1018  return rv; 
     1019}