1 #include "libc.h"
2 #include <resolv.h>
3 
__dn_expand(const unsigned char * base,const unsigned char * end,const unsigned char * src,char * dest,int space)4 int __dn_expand(const unsigned char* base, const unsigned char* end, const unsigned char* src,
5                 char* dest, int space) {
6     const unsigned char* p = src;
7     char *dend, *dbegin = dest;
8     int len = -1, i, j;
9     if (p == end || space <= 0)
10         return -1;
11     dend = dest + (space > 254 ? 254 : space);
12     /* detect reference loop using an iteration counter */
13     for (i = 0; i < end - base; i += 2) {
14         /* loop invariants: p<end, dest<dend */
15         if (*p & 0xc0) {
16             if (p + 1 == end)
17                 return -1;
18             j = ((p[0] & 0x3f) << 8) | p[1];
19             if (len < 0)
20                 len = p + 2 - src;
21             if (j >= end - base)
22                 return -1;
23             p = base + j;
24         } else if (*p) {
25             if (dest != dbegin)
26                 *dest++ = '.';
27             j = *p++;
28             if (j >= end - p || j >= dend - dest)
29                 return -1;
30             while (j--)
31                 *dest++ = *p++;
32         } else {
33             *dest = 0;
34             if (len < 0)
35                 len = p + 1 - src;
36             return len;
37         }
38     }
39     return -1;
40 }
41 
42 weak_alias(__dn_expand, dn_expand);
43