summaryrefslogtreecommitdiff
blob: 12eabc213f577a69a7ef276fccd66b09a6fc523e (plain)
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
From f58b02f2cf068e1bed10bf9f632bad396d907de9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= <saghul@gmail.com>
Date: Fri, 23 May 2014 09:25:23 +0200
Subject: [PATCH] unix, windows: fix parsing scoped IPv6 addresses

---
 src/inet.c | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/src/inet.c b/src/inet.c
index 0eb9438..36457f4 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -17,6 +17,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
 #if defined(_MSC_VER) && _MSC_VER < 1600
 # include "stdint-msvc2008.h"
@@ -159,11 +160,27 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
 
 
 int uv_inet_pton(int af, const char* src, void* dst) {
+  if (src == NULL || dst == NULL)
+    return UV_EINVAL;
+
   switch (af) {
   case AF_INET:
     return (inet_pton4(src, dst));
-  case AF_INET6:
-    return (inet_pton6(src, dst));
+  case AF_INET6: {
+    int len;
+    char tmp[UV__INET6_ADDRSTRLEN], *s, *p;
+    s = (char*) src;
+    p = strchr(src, '%');
+    if (p != NULL) {
+      s = tmp;
+      len = p - src;
+      if (len > UV__INET6_ADDRSTRLEN-1)
+        len = UV__INET6_ADDRSTRLEN-1;
+      memcpy(s, src, len);
+      s[len] = '\0';
+    }
+    return inet_pton6(s, dst);
+  }
   default:
     return UV_EAFNOSUPPORT;
   }
@@ -228,7 +245,7 @@ static int inet_pton6(const char *src, unsigned char *dst) {
   curtok = src;
   seen_xdigits = 0;
   val = 0;
-  while ((ch = *src++) != '\0' && ch != '%') {
+  while ((ch = *src++) != '\0') {
     const char *pch;
 
     if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
@@ -259,19 +276,7 @@ static int inet_pton6(const char *src, unsigned char *dst) {
       continue;
     }
     if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) {
-      int err;
-
-      /* Scope id present, parse ipv4 addr without it */
-      pch = strchr(curtok, '%');
-      if (pch != NULL) {
-        char tmp[sizeof "255.255.255.255"];
-
-        memcpy(tmp, curtok, pch - curtok);
-        curtok = tmp;
-        src = pch;
-      }
-
-      err = inet_pton4(curtok, tp);
+      int err = inet_pton4(curtok, tp);
       if (err == 0) {
         tp += sizeof(struct in_addr);
         seen_xdigits = 0;
-- 
1.9.3