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