1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
diff --git a/src/multibyte/wcsrtombs.c b/src/multibyte/wcsrtombs.c
index 5cf8f3e..30be415 100644
--- a/src/multibyte/wcsrtombs.c
+++ b/src/multibyte/wcsrtombs.c
@@ -21,8 +21,13 @@ size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstat
}
return n;
}
- while (n>=4 && **ws) {
- if (**ws >= 0x80u) {
+ while (n>=4) {
+ if (**ws-1u >= 0x7fu) {
+ if (!**ws) {
+ *s = 0;
+ *ws = 0;
+ return N-n;
+ }
l = wcrtomb(s, **ws, 0);
if (!(l+1)) return -1;
s += l;
@@ -33,8 +38,13 @@ size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstat
}
(*ws)++;
}
- while (n && **ws) {
- if (**ws >= 0x80u) {
+ while (n) {
+ if (**ws-1u >= 0x7fu) {
+ if (!**ws) {
+ *s = 0;
+ *ws = 0;
+ return N-n;
+ }
l = wcrtomb(buf, **ws, 0);
if (!(l+1)) return -1;
if (l>n) return N-n;
@@ -47,7 +57,5 @@ size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstat
}
(*ws)++;
}
- if (n) *s = 0;
- *ws = 0;
- return N-n;
+ return N;
}
diff --git a/src/network/dns_parse.c b/src/network/dns_parse.c
index aa0d39f..0c7a601 100644
--- a/src/network/dns_parse.c
+++ b/src/network/dns_parse.c
@@ -6,6 +6,7 @@ int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, c
const unsigned char *p;
int len;
+ if (rlen<12) return -1;
if ((r[3]&15)) return 0;
p = r+12;
qdcount = r[4]*256 + r[5];
@@ -13,13 +14,13 @@ int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, c
if (qdcount+ancount > 64) return -1;
while (qdcount--) {
while (p-r < rlen && *p-1U < 127) p++;
- if (*p>193 || (*p==193 && p[1]>254) || p>r+506)
+ if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
return -1;
p += 5 + !!*p;
}
while (ancount--) {
while (p-r < rlen && *p-1U < 127) p++;
- if (*p>193 || (*p==193 && p[1]>254) || p>r+506)
+ if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
return -1;
p += 1 + !!*p;
len = p[8]*256 + p[9];
diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
index 8d41627..0292093 100644
--- a/src/network/lookup_name.c
+++ b/src/network/lookup_name.c
@@ -151,7 +151,10 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static
for (i=0; i<nq; i++)
__dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
- return ctx.cnt;
+ if (ctx.cnt) return ctx.cnt;
+ if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
+ if ((abuf[0][3] & 15) == 3) return EAI_NONAME;
+ return EAI_FAIL;
}
int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)
|