summaryrefslogtreecommitdiff
path: root/external/liborcus/overrun.patch.0
blob: 8b5bc5366da1df9798f7fd5b7adfe835d13a296a (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
--- src/parser/sax_token_parser.cpp
+++ src/parser/sax_token_parser.cpp
@@ -10,6 +10,7 @@
 
 #include <mdds/sorted_string_map.hpp>
 #include <cctype>
+#include <limits>
 
 namespace orcus {
 
@@ -329,6 +330,28 @@
     m_elem.raw_name = elem.name;
 }
 
+static uint8_t readUint8(char const * begin, char const * end, char const ** endptr) {
+    unsigned n = 0;
+    char const * p = begin;
+    for (; p != end; ++p) {
+        char const c = *p;
+        if (c < '0' || c > '9') {
+            break;
+        }
+        n = 10 * n + (c - '0');
+        if (n > std::numeric_limits<uint8_t>::max()) {
+            *endptr = nullptr;
+            return 0;
+        }
+    }
+    if (p == begin) {
+        *endptr = nullptr;
+        return 0;
+    }
+    *endptr = p;
+    return n;
+}
+
 void sax_token_handler_wrapper_base::attribute(const pstring& name, const pstring& val)
 {
     decl_attr_type dat = decl_attr::get().find(name.data(), name.size());
@@ -340,18 +362,18 @@
             const char* p = val.data();
             const char* p_end = p + val.size();
 
-            char* endptr = nullptr;
-            long v = std::strtol(p, &endptr, 10);
+            const char* endptr = nullptr;
+            uint8_t v = readUint8(p, p_end, &endptr);
 
-            if (!endptr || endptr >= p_end || *endptr != '.')
+            if (!endptr || endptr == p_end || *endptr != '.')
                 break;
 
             m_declaration.version_major = v;
             p = endptr + 1;
 
-            v = std::strtol(p, &endptr, 10);
+            v = readUint8(p, p_end, &endptr);
 
-            if (!endptr || endptr > p_end)
+            if (!endptr)
                 break;
 
             m_declaration.version_minor = v;