Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/networking/udhcp/domain_codec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 983 by niro, Fri Apr 24 18:33:46 2009 UTC revision 984 by niro, Sun May 30 11:32:42 2010 UTC
# Line 25  Line 25 
25   */   */
26  char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre)  char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre)
27  {  {
28   const uint8_t *c;   char *ret = ret; /* for compiler */
  int crtpos, retpos, depth, plen = 0, len = 0;  
29   char *dst = NULL;   char *dst = NULL;
30    
  if (!cstr)  
  return NULL;  
   
  if (pre)  
  plen = strlen(pre);  
   
31   /* We make two passes over the cstr string. First, we compute   /* We make two passes over the cstr string. First, we compute
32   * how long the resulting string would be. Then we allocate a   * how long the resulting string would be. Then we allocate a
33   * new buffer of the required length, and fill it in with the   * new buffer of the required length, and fill it in with the
# Line 42  char* FAST_FUNC dname_dec(const uint8_t Line 35  char* FAST_FUNC dname_dec(const uint8_t
35   * having to deal with requiring callers to supply their own   * having to deal with requiring callers to supply their own
36   * buffer, then having to check if it's sufficiently large, etc.   * buffer, then having to check if it's sufficiently large, etc.
37   */   */
38     while (1) {
39   while (!dst) {   /* note: "return NULL" below are leak-safe since
40     * dst isn't yet allocated */
41   if (len > 0) { /* second pass? allocate dst buffer and copy pre */   const uint8_t *c;
42   dst = xmalloc(len + plen);   unsigned crtpos, retpos, depth, len;
  memcpy(dst, pre, plen);  
  }  
43    
44   crtpos = retpos = depth = len = 0;   crtpos = retpos = depth = len = 0;
   
45   while (crtpos < clen) {   while (crtpos < clen) {
46   c = cstr + crtpos;   c = cstr + crtpos;
47    
48   if ((*c & NS_CMPRSFLGS) != 0) { /* pointer */   if (*c & NS_CMPRSFLGS) {
49   if (crtpos + 2 > clen) /* no offset to jump to? abort */   /* pointer */
50     if (crtpos + 2 > clen) /* no offset to jump to? abort */
51   return NULL;   return NULL;
52   if (retpos == 0) /* toplevel? save return spot */   if (retpos == 0) /* toplevel? save return spot */
53   retpos = crtpos + 2;   retpos = crtpos + 2;
54   depth++;   depth++;
55   crtpos = ((*c & 0x3f) << 8) | (*(c + 1) & 0xff); /* jump */   crtpos = ((c[0] & 0x3f) << 8) | (c[1] & 0xff); /* jump */
56   } else if (*c) { /* label */   } else if (*c) {
57   if (crtpos + *c + 1 > clen) /* label too long? abort */   /* label */
58     if (crtpos + *c + 1 > clen) /* label too long? abort */
59   return NULL;   return NULL;
60   if (dst)   if (dst)
61   memcpy(dst + plen + len, c + 1, *c);   memcpy(dst + len, c + 1, *c);
62   len += *c + 1;   len += *c + 1;
63   crtpos += *c + 1;   crtpos += *c + 1;
64   if (dst)   if (dst)
65   *(dst + plen + len - 1) = '.';   dst[len - 1] = '.';
66   } else { /* null: end of current domain name */   } else {
67   if (retpos == 0) { /* toplevel? keep going */   /* null: end of current domain name */
68     if (retpos == 0) {
69     /* toplevel? keep going */
70   crtpos++;   crtpos++;
71   } else { /* return to toplevel saved spot */   } else {
72     /* return to toplevel saved spot */
73   crtpos = retpos;   crtpos = retpos;
74   retpos = depth = 0;   retpos = depth = 0;
75   }   }
76   if (dst)   if (dst)
77   *(dst + plen + len - 1) = ' ';   dst[len - 1] = ' ';
78   }   }
79    
80   if (depth > NS_MAXDNSRCH || /* too many jumps? abort, it's a loop */   if (depth > NS_MAXDNSRCH /* too many jumps? abort, it's a loop */
81   len > NS_MAXDNAME * NS_MAXDNSRCH) /* result too long? abort */   || len > NS_MAXDNAME * NS_MAXDNSRCH /* result too long? abort */
82     ) {
83   return NULL;   return NULL;
84     }
85   }   }
86    
87   if (!len) /* expanded string has 0 length? abort */   if (!len) /* expanded string has 0 length? abort */
88   return NULL;   return NULL;
89    
90   if (dst)   if (!dst) { /* first pass? */
91   *(dst + plen + len - 1) = '\0';   /* allocate dst buffer and copy pre */
92     unsigned plen = strlen(pre);
93     ret = dst = xmalloc(plen + len);
94     memcpy(dst, pre, plen);
95     dst += plen;
96     } else {
97     dst[len - 1] = '\0';
98     break;
99     }
100   }   }
101    
102   return dst;   return ret;
103  }  }
104    
105  /* Convert a domain name (src) from human-readable "foo.blah.com" format into  /* Convert a domain name (src) from human-readable "foo.blah.com" format into

Legend:
Removed from v.983  
changed lines
  Added in v.984