libs/web: fix error in wep key validation
[project/luci.git] / libs / web / luasrc / cbi / datatypes.lua
1 --[[
2
3 LuCI - Configuration Bind Interface - Datatype Tests
4 (c) 2010 Jo-Philipp Wich <xm@subsignal.org>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13
14 ]]--
15
16 local fs = require "nixio.fs"
17 local ip = require "luci.ip"
18 local math = require "math"
19 local util = require "luci.util"
20
21 local tonumber = tonumber
22
23 module "luci.cbi.datatypes"
24
25
26 function bool(val)
27 if val == "1" or val == "yes" or val == "on" or val == "true" then
28 return true
29 elseif val == "0" or val == "no" or val == "off" or val == "false" then
30 return true
31 elseif val == "" or val == nil then
32 return true
33 end
34
35 return false
36 end
37
38 function uinteger(val)
39 local n = tonumber(val)
40 if n ~= nil and math.floor(n) == n and n >= 0 then
41 return true
42 end
43
44 return false
45 end
46
47 function integer(val)
48 local n = tonumber(val)
49 if n ~= nil and math.floor(n) == n then
50 return true
51 end
52
53 return false
54 end
55
56 function ufloat(val)
57 local n = tonumber(val)
58 return ( n ~= nil and n >= 0 )
59 end
60
61 function float(val)
62 return ( tonumber(val) ~= nil )
63 end
64
65 function ipaddr(val)
66 return ip4addr(val) or ip6addr(val)
67 end
68
69 function ip4addr(val)
70 if val then
71 return ip.IPv4(val) and true or false
72 end
73
74 return false
75 end
76
77 function ip4prefix(val)
78 val = tonumber(val)
79 return ( val and val >= 0 and val <= 32 )
80 end
81
82 function ip6addr(val)
83 if val then
84 return ip.IPv6(val) and true or false
85 end
86
87 return false
88 end
89
90 function ip6prefix(val)
91 val = tonumber(val)
92 return ( val and val >= 0 and val <= 128 )
93 end
94
95 function port(val)
96 val = tonumber(val)
97 return ( val and val >= 1 and val <= 65535 )
98 end
99
100 function portrange(val)
101 local p1, p2 = val:match("^(%d+)%-(%d+)$")
102 if p1 and p2 and port(p1) and port(p2) then
103 return true
104 else
105 return port(val)
106 end
107 end
108
109 function macaddr(val)
110 if val and val:match(
111 "^[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+:" ..
112 "[a-fA-F0-9]+:[a-fA-F0-9]+:[a-fA-F0-9]+$"
113 ) then
114 local parts = util.split( val, ":" )
115
116 for i = 1,6 do
117 parts[i] = tonumber( parts[i], 16 )
118 if parts[i] < 0 or parts[i] > 255 then
119 return false
120 end
121 end
122
123 return true
124 end
125
126 return false
127 end
128
129 function hostname(val)
130 if val and val:match("[a-zA-Z0-9_][a-zA-Z0-9_%-%.]*") then
131 return true -- XXX: ToDo: need better solution
132 end
133
134 return false
135 end
136
137 function host(val)
138 return hostname(val) or ipaddr(val)
139 end
140
141 function wpakey(val)
142 if #val == 64 then
143 return (val:match("^[a-fA-F0-9]+$") ~= nil)
144 else
145 return (#val >= 8) and (#val <= 63)
146 end
147 end
148
149 function wepkey(val)
150 if val:sub(1, 2) == "s:" then
151 val = val:sub(3)
152 end
153
154 if (#val == 10) or (#val == 26) then
155 return (val:match("^[a-fA-F0-9]+$") ~= nil)
156 else
157 return (#val == 5) or (#val == 13)
158 end
159 end
160
161 function string(val)
162 return true -- Everything qualifies as valid string
163 end
164
165 function directory( val, seen )
166 local s = fs.stat(val)
167 seen = seen or { }
168
169 if s and not seen[s.ino] then
170 seen[s.ino] = true
171 if s.type == "dir" then
172 return true
173 elseif s.type == "lnk" then
174 return directory( fs.readlink(val), seen )
175 end
176 end
177
178 return false
179 end
180
181 function file( val, seen )
182 local s = fs.stat(val)
183 seen = seen or { }
184
185 if s and not seen[s.ino] then
186 seen[s.ino] = true
187 if s.type == "reg" then
188 return true
189 elseif s.type == "lnk" then
190 return file( fs.readlink(val), seen )
191 end
192 end
193
194 return false
195 end
196
197 function device( val, seen )
198 local s = fs.stat(val)
199 seen = seen or { }
200
201 if s and not seen[s.ino] then
202 seen[s.ino] = true
203 if s.type == "chr" or s.type == "blk" then
204 return true
205 elseif s.type == "lnk" then
206 return device( fs.readlink(val), seen )
207 end
208 end
209
210 return false
211 end
212
213 function uciname(val)
214 return (val:match("^[a-zA-Z0-9_]+$") ~= nil)
215 end
216
217 function range(val, min, max)
218 val = tonumber(val)
219 min = tonumber(min)
220 max = tonumber(max)
221
222 if val ~= nil and min ~= nil and max ~= nil then
223 return ((val >= min) and (val <= max))
224 end
225
226 return false
227 end