Edit

IABSD.fr/xenocara/app/ssh-askpass/resources.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2008-03-20 20:45:10
    Hash : b3afb49c
    Message : Get rid of strcat() and strcpy(), fixing a potential stack overflow. With help and ok deraadt@, millert@, oga@.

  • app/ssh-askpass/resources.c
  • /* xscreensaver, Copyright (c) 1992, 1997, 1998
     *  Jamie Zawinski <jwz@jwz.org>
     *
     * Permission to use, copy, modify, distribute, and sell this software and its
     * documentation for any purpose is hereby granted without fee, provided that
     * the above copyright notice appear in all copies and that both that
     * copyright notice and this permission notice appear in supporting
     * documentation.  No representations are made about the suitability of this
     * software for any purpose.  It is provided "as is" without express or 
     * implied warranty.
     */
    
    /* 1999-Nov-21 Modified by Jim Knoble <jmknoble@jmknoble.cx>.
     * Modifications:
     * 
     *   - Made get_boolean_resource() accept a third parameter, default_value,
     *     which determines the result of get_boolean_resource if either (a)
     *     no such resource exists, or (b) the resource value does not conform
     *     to the syntax of a boolean resource.
     * 
     *   - Same for get_integer_resource(), get_pixel_resource().
     * 
     *   - 1999-Dec-24 Moved header includes from utils.h to here.
     *     Trimmed unused functions.
     */
    
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <X11/Xlib.h>
    #include <X11/Xos.h>
    #include <X11/Xresource.h>
    #include "resources.h"
    
    
    /* Resource functions.  Assumes: */
    
    extern char *progname;
    extern char *progclass;
    extern XrmDatabase db;
    
    #ifndef isupper
    # define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
    #endif
    #ifndef _tolower
    # define _tolower(c)  ((c) - 'A' + 'a')
    #endif
    
    char *
    get_string_resource (char *res_name, char *res_class)
    {
      XrmValue value;
      char	*type;
      char full_name [1024], full_class [1024];
      int result;
    
      result = snprintf(full_name, sizeof(full_name), "%s.%s", 
          progname, res_name);
      if (result == -1 || result >= sizeof(full_name)) {
    	  fprintf(stderr, "%s: resource name too long: %s.%s\n", progname,
    	      progname, res_name);
    	  return 0;
      }
      result = snprintf(full_class, sizeof(full_class), "%s.%s", 
          progclass, res_class);
      if (result == -1 || result >= sizeof(full_class)) {
    	 fprintf(stderr, "%s: resource name too long: %s.%s\n", progname,
    	      progclass, res_class);
    	  return 0;
      }
      if (XrmGetResource (db, full_name, full_class, &type, &value))
        {
          char *str = (char *) malloc (value.size + 1);
          strncpy (str, (char *) value.addr, value.size);
          str [value.size] = 0;
          return str;
        }
      return 0;
    }
    
    Bool 
    get_boolean_resource (char *res_name, char *res_class, Bool default_value)
    {
      char *tmp, buf [100];
      char *s = get_string_resource (res_name, res_class);
      char *os = s;
      if (! s) return default_value;
      for (tmp = buf; *s; s++)
        *tmp++ = isupper (*s) ? _tolower (*s) : *s;
      *tmp = 0;
      free (os);
    
      while (*buf &&
    	 (buf[strlen(buf)-1] == ' ' ||
    	  buf[strlen(buf)-1] == '\t'))
        buf[strlen(buf)-1] = 0;
    
      if (!strcmp (buf, "on") || !strcmp (buf, "true") || !strcmp (buf, "yes"))
        return 1;
      if (!strcmp (buf,"off") || !strcmp (buf, "false") || !strcmp (buf,"no"))
        return 0;
      fprintf (stderr, "%s: %s must be boolean, not %s.\n",
    	   progname, res_name, buf);
      return default_value;
    }
    
    int 
    get_integer_resource (char *res_name, char *res_class, int default_value)
    {
      int val;
      char c, *s = get_string_resource (res_name, res_class);
      char *ss = s;
      if (!s) return default_value;
    
      while (*ss && *ss <= ' ') ss++;			/* skip whitespace */
    
      if (ss[0] == '0' && (ss[1] == 'x' || ss[1] == 'X'))	/* 0x: parse as hex */
        {
          if (1 == sscanf (ss+2, "%x %c", &val, &c))
    	{
    	  free (s);
    	  return val;
    	}
        }
      else							/* else parse as dec */
        {
          if (1 == sscanf (ss, "%d %c", &val, &c))
    	{
    	  free (s);
    	  return val;
    	}
        }
    
      fprintf (stderr, "%s: %s must be an integer, not %s.\n",
    	   progname, res_name, s);
      free (s);
      return default_value;
    }
    
    double
    get_float_resource (char *res_name, char *res_class)
    {
      double val;
      char c, *s = get_string_resource (res_name, res_class);
      if (! s) return 0.0;
      if (1 == sscanf (s, " %lf %c", &val, &c))
        {
          free (s);
          return val;
        }
      fprintf (stderr, "%s: %s must be a float, not %s.\n",
    	   progname, res_name, s);
      free (s);
      return 0.0;
    }
    
    
    unsigned int
    get_pixel_resource (char *res_name, char *res_class,
    		    Display *dpy, Colormap cmap, unsigned int default_value)
    {
      XColor color;
      char *s = get_string_resource (res_name, res_class);
      char *s2;
      if (!s) goto DEFAULT;
    
      for (s2 = s + strlen(s) - 1; s2 > s; s2--)
        if (*s2 == ' ' || *s2 == '\t')
          *s2 = 0;
        else
          break;
    
      if (! XParseColor (dpy, cmap, s, &color))
        {
          fprintf (stderr, "%s: can't parse color %s\n", progname, s);
          goto DEFAULT;
        }
      if (! XAllocColor (dpy, cmap, &color))
        {
          fprintf (stderr, "%s: couldn't allocate color %s\n", progname, s);
          goto DEFAULT;
        }
      free (s);
      return color.pixel;
     DEFAULT:
      if (s) free (s);
      return default_value;
    }