1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <map>
17 #include <arpa/inet.h>
18 #include <cctype>
19 #include <cstddef>
20 #include <cstdlib>
21 #include <cstring>
22 #include <ctime>
23 #include <ifaddrs.h>
24 #include <malloc.h>
25 #include <netdb.h>
26 #include <string>
27 #include <unistd.h>
28
29 #include "pac_functions.h"
30
31 namespace OHOS {
32 namespace NetManagerStandard {
33 namespace {
34 constexpr size_t ARG_COUNT_1 = 1;
35 constexpr size_t ARG_COUNT_2 = 2;
36 constexpr size_t ARG_COUNT_3 = 3;
37 constexpr size_t ARG_COUNT_4 = 4;
38 constexpr size_t ARG_COUNT_5 = 5;
39 constexpr size_t ARG_COUNT_6 = 6;
40 constexpr size_t ARG_COUNT_7 = 7;
41 constexpr size_t ARG_COUNT_31 = 31;
42 constexpr size_t ARG_INDEX_0 = 0;
43 constexpr size_t ARG_INDEX_1 = 1;
44 constexpr size_t ARG_INDEX_2 = 2;
45 constexpr size_t ARG_INDEX_3 = 3;
46 constexpr size_t ARG_INDEX_4 = 4;
47 constexpr size_t ARG_INDEX_5 = 5;
48 constexpr size_t ARG_INDEX_6 = 6;
49 constexpr int YEAR_BASE = 1900;
50 constexpr int SECONDS_PER_HOUR = 3600;
51 constexpr int SECONDS_PER_MINUTE = 60;
52 constexpr int TEN_THOUSAND = 10000;
53 constexpr int HUNDRED = 100;
54 constexpr char SPACE_CHAR = ' ';
55 constexpr char COLON_CHAR = ':';
56 constexpr char PATH_CHAR = '/';
57 constexpr char NULL_CHAR = '\0';
58 constexpr char SEMICOLON_CHAR = ';';
59 constexpr char DOT_CHAR = '.';
60 constexpr char ASTERISK_CHAR = '*';
61 constexpr char QUESTION_CHAR = '?';
62 constexpr const char COMMA_SPACE[] = ", ";
63 constexpr const char GMT[] = "GMT";
64 constexpr const char DEFAULT_URL[] = "127.0.0.1";
65 constexpr const char DEFAULT_IPV6_ADDR[] = "::1";
66 constexpr const char IPV6_LINK_LOCAL_PREFIX[] = "fe80:";
67 constexpr const char INVALID_ARGUMENT[] = "Invalid argument";
68 constexpr const char MEMORY_ALLOCATION_FAILED[] = "Memory allocation failed";
69 constexpr const char *MONTH_NAMES[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
70 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
71 constexpr size_t MONTH_COUNT = std::size(MONTH_NAMES);
72 constexpr const char *DAY_NAMES[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
73 constexpr size_t DAY_COUNT = std::size(DAY_NAMES);
74 using Checker = std::function<bool(const jerry_length_t argsCnt, const jerry_value_t args[])>;
75 using Handler = std::function<jerry_value_t(const jerry_value_t args[], struct tm *timeinfo)>;
76 } // namespace
77
JERRY_CONCHAR(const char * str)78 static const jerry_char_t *JERRY_CONCHAR(const char *str)
79 {
80 return reinterpret_cast<const jerry_char_t *>(str);
81 }
82
JERRY_CHAR(char * str)83 static jerry_char_t *JERRY_CHAR(char *str)
84 {
85 return reinterpret_cast<jerry_char_t *>(str);
86 }
87
JerryStringToChar(jerry_value_t strVal)88 static char *JerryStringToChar(jerry_value_t strVal)
89 {
90 jerry_size_t strSize = jerry_get_string_size(strVal);
91 if (strSize > SIZE_MAX - 1) {
92 return nullptr;
93 }
94 char *str = (char *)malloc(strSize + 1);
95 if (str) {
96 jerry_string_to_char_buffer(strVal, JERRY_CHAR(str), strSize);
97 str[strSize] = NULL_CHAR;
98 }
99 return str;
100 }
101
CreateJerryString(const char * str)102 static jerry_value_t CreateJerryString(const char *str)
103 {
104 return jerry_create_string(reinterpret_cast<const jerry_char_t *>(str));
105 }
106
JsIsPlainHostname(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)107 jerry_value_t PacFunctions::JsIsPlainHostname(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
108 const jerry_value_t args[], const jerry_length_t argsCnt)
109 {
110 if (argsCnt < ARG_COUNT_1 || !jerry_value_is_string(args[ARG_INDEX_0])) {
111 return jerry_create_boolean(false);
112 }
113 char *host = JerryStringToChar(args[ARG_INDEX_0]);
114 if (host) {
115 if (host[0] == NULL_CHAR) {
116 free(host);
117 return jerry_create_boolean(true);
118 }
119 bool result = (strchr(host, DOT_CHAR) == nullptr);
120 free(host);
121 return jerry_create_boolean(result);
122 }
123 return jerry_create_boolean(false);
124 }
125
JsDnsDomainIs(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)126 jerry_value_t PacFunctions::JsDnsDomainIs(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
127 const jerry_value_t args[], const jerry_length_t argsCnt)
128 {
129 if (argsCnt < ARG_COUNT_2 || !jerry_value_is_string(args[ARG_INDEX_0]) ||
130 !jerry_value_is_string(args[ARG_INDEX_1])) {
131 return jerry_create_boolean(false);
132 }
133 char *host = JerryStringToChar(args[ARG_INDEX_0]);
134 char *domain = JerryStringToChar(args[ARG_INDEX_1]);
135 if (host && domain) {
136 if (strlen(domain) == 0) {
137 free(host);
138 free(domain);
139 return jerry_create_boolean(false);
140 }
141 bool result = false;
142 if (strcasecmp(host, domain) == 0) {
143 result = true;
144 } else if (domain[0] == DOT_CHAR && strcasecmp(host, domain + 1) == 0) {
145 result = true;
146 } else {
147 int hostLen = strlen(host);
148 int domainLen = strlen(domain);
149 if (hostLen >= domainLen) {
150 result = (strcasecmp(host + (hostLen - domainLen), domain) == 0);
151 }
152 }
153 free(host);
154 free(domain);
155 return jerry_create_boolean(result);
156 }
157 return jerry_create_boolean(false);
158 }
159
JsLocalHostOrDomainIs(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)160 jerry_value_t PacFunctions::JsLocalHostOrDomainIs(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
161 const jerry_value_t args[], const jerry_length_t argsCnt)
162 {
163 if (argsCnt < ARG_COUNT_2 || !jerry_value_is_string(args[ARG_INDEX_0]) ||
164 !jerry_value_is_string(args[ARG_INDEX_1])) {
165 return jerry_create_boolean(false);
166 }
167 char *host = JerryStringToChar(args[ARG_INDEX_0]);
168 char *hostdom = JerryStringToChar(args[ARG_INDEX_1]);
169 if (!host || !hostdom) {
170 free(host);
171 free(hostdom);
172 return jerry_create_boolean(false);
173 }
174 if (strcasecmp(host, hostdom) == 0) {
175 free(host);
176 free(hostdom);
177 return jerry_create_boolean(true);
178 }
179 if (strchr(host, DOT_CHAR) == nullptr) {
180 char *dot = strchr(hostdom, DOT_CHAR);
181 if (dot != nullptr) {
182 size_t hostLen = strlen(host);
183 size_t prefixLen = dot - hostdom;
184 if (hostLen == prefixLen && strncasecmp(host, hostdom, hostLen) == 0) {
185 free(host);
186 free(hostdom);
187 return jerry_create_boolean(true);
188 }
189 }
190 }
191 free(host);
192 free(hostdom);
193 return jerry_create_boolean(false);
194 }
195
JsIsResolvable(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)196 jerry_value_t PacFunctions::JsIsResolvable(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
197 const jerry_value_t args[], const jerry_length_t argsCnt)
198 {
199 if (argsCnt < ARG_COUNT_1 || !jerry_value_is_string(args[ARG_INDEX_0])) {
200 return jerry_create_boolean(false);
201 }
202 char *host = JerryStringToChar(args[ARG_INDEX_0]);
203 if (host) {
204 struct hostent *he = gethostbyname(host);
205 bool result = (he != nullptr);
206 free(host);
207 return jerry_create_boolean(result);
208 } else {
209 return jerry_create_boolean(false);
210 }
211 }
212
JsMyIpAddress(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)213 jerry_value_t PacFunctions::JsMyIpAddress(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
214 const jerry_value_t args[], const jerry_length_t argsCnt)
215 {
216 char hostname[256];
217 if (gethostname(hostname, sizeof(hostname)) != 0) {
218 return CreateJerryString(DEFAULT_URL);
219 }
220 struct hostent *he = gethostbyname(hostname);
221 if (!he || he->h_addr_list[0] == nullptr) {
222 return CreateJerryString(DEFAULT_URL);
223 }
224 char ip[INET_ADDRSTRLEN];
225 inet_ntop(AF_INET, he->h_addr_list[0], ip, sizeof(ip));
226 return CreateJerryString(ip);
227 }
228
JsMyIpAddressEx(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)229 jerry_value_t PacFunctions::JsMyIpAddressEx(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
230 const jerry_value_t args[], const jerry_length_t argsCnt)
231 {
232 struct ifaddrs *ifaddr;
233 struct ifaddrs *ifa;
234 std::string ipList;
235 int first = 1;
236 if (getifaddrs(&ifaddr) == -1) {
237 return CreateJerryString(DEFAULT_IPV6_ADDR);
238 }
239 for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
240 if (ifa->ifa_addr == nullptr) {
241 continue;
242 }
243 char ip[INET6_ADDRSTRLEN];
244 void *addr;
245 if (ifa->ifa_addr->sa_family == AF_INET) {
246 struct sockaddr_in *ipv4 = reinterpret_cast<sockaddr_in *>(ifa->ifa_addr);
247 addr = &(ipv4->sin_addr);
248 inet_ntop(AF_INET, addr, ip, INET_ADDRSTRLEN);
249 if (strcmp(ip, DEFAULT_URL) == 0) {
250 continue;
251 }
252 if (!first) {
253 ipList.append(COMMA_SPACE);
254 }
255 ipList.append(ip);
256 first = 0;
257 } else if (ifa->ifa_addr->sa_family == AF_INET6) {
258 struct sockaddr_in6 *ipv6 = reinterpret_cast<sockaddr_in6 *>(ifa->ifa_addr);
259 addr = &(ipv6->sin6_addr);
260 inet_ntop(AF_INET6, addr, ip, INET6_ADDRSTRLEN);
261 if (strcmp(ip, DEFAULT_IPV6_ADDR) == 0 || strncmp(ip, IPV6_LINK_LOCAL_PREFIX, ARG_COUNT_5) == 0) {
262 continue;
263 }
264 if (!first) {
265 ipList.append(COMMA_SPACE);
266 }
267 ipList.append(ip);
268 first = 0;
269 }
270 }
271 freeifaddrs(ifaddr);
272 if (first) {
273 return CreateJerryString(DEFAULT_IPV6_ADDR);
274 }
275 return CreateJerryString(ipList.c_str());
276 }
277
JsIsInNet(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)278 jerry_value_t PacFunctions::JsIsInNet(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
279 const jerry_value_t args[], const jerry_length_t argsCnt)
280 {
281 if (argsCnt < ARG_COUNT_3) {
282 return jerry_create_boolean(false);
283 }
284 char *ip = JerryStringToChar(args[ARG_INDEX_0]);
285 char *net = JerryStringToChar(args[ARG_INDEX_1]);
286 char *mask = JerryStringToChar(args[ARG_INDEX_2]);
287 if (ip && net && mask) {
288 struct in_addr ipAddr;
289 struct in_addr netAddr;
290 struct in_addr maskAddr;
291 bool result = false;
292 if (inet_pton(AF_INET, ip, &ipAddr) == 1 && inet_pton(AF_INET, net, &netAddr) == 1 &&
293 inet_pton(AF_INET, mask, &maskAddr) == 1) {
294 result = ((ipAddr.s_addr & maskAddr.s_addr) == (netAddr.s_addr & maskAddr.s_addr));
295 }
296 free(ip);
297 free(net);
298 free(mask);
299 return jerry_create_boolean(result);
300 } else {
301 return jerry_create_boolean(false);
302 }
303 }
304
JsSortIpAddressList(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)305 jerry_value_t PacFunctions::JsSortIpAddressList(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
306 const jerry_value_t args[], const jerry_length_t argsCnt)
307 {
308 return jerry_create_boolean(false);
309 }
310
JsDnsResolve(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)311 jerry_value_t PacFunctions::JsDnsResolve(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
312 const jerry_value_t args[], const jerry_length_t argsCnt)
313 {
314 if (argsCnt != ARG_COUNT_1) {
315 return jerry_create_error(JERRY_ERROR_TYPE, JERRY_CONCHAR(INVALID_ARGUMENT));
316 }
317 if (!jerry_value_is_string(args[ARG_INDEX_0])) {
318 return jerry_create_error(JERRY_ERROR_TYPE, JERRY_CONCHAR(INVALID_ARGUMENT));
319 }
320 jerry_size_t host_size = jerry_get_string_size(args[ARG_INDEX_0]);
321 if (host_size < 0) {
322 return jerry_create_boolean(false);
323 }
324 char *host = (char *)malloc(host_size + 1);
325 if (host == nullptr) {
326 return jerry_create_error(JERRY_ERROR_COMMON, JERRY_CONCHAR(MEMORY_ALLOCATION_FAILED));
327 }
328 jerry_string_to_char_buffer(args[ARG_INDEX_0], JERRY_CHAR(host), host_size);
329 host[host_size] = NULL_CHAR;
330 struct addrinfo hints;
331 explicit_bzero(&hints, sizeof(hints));
332 hints.ai_family = AF_INET;
333 hints.ai_socktype = SOCK_STREAM;
334 struct addrinfo *res = nullptr;
335 int status = getaddrinfo(host, nullptr, &hints, &res);
336 free(host);
337 if (status != 0 || res == nullptr) {
338 char empty[] = "";
339 return jerry_create_string_sz(JERRY_CHAR(empty), 0);
340 }
341 struct sockaddr_in *ipv4 = reinterpret_cast<sockaddr_in *>(res->ai_addr);
342 char ipStr[INET_ADDRSTRLEN];
343 inet_ntop(AF_INET, &(ipv4->sin_addr), ipStr, INET_ADDRSTRLEN);
344 freeaddrinfo(res);
345 return jerry_create_string_sz(JERRY_CHAR(ipStr), strlen(ipStr));
346 }
347
MatchPattern(const char * str,const char * pattern)348 static int MatchPattern(const char *str, const char *pattern)
349 {
350 if (pattern[0] == NULL_CHAR) {
351 return str[0] == NULL_CHAR;
352 }
353 if (*pattern == ASTERISK_CHAR) {
354 pattern++;
355 for (const char *s = str;; s++) {
356 if (MatchPattern(s, pattern)) {
357 return true;
358 }
359 if (*s == NULL_CHAR) {
360 return false;
361 }
362 }
363 }
364 if (*str == NULL_CHAR) {
365 return false;
366 }
367 if (*pattern == QUESTION_CHAR || *pattern == *str) {
368 return MatchPattern(str + 1, pattern + 1);
369 }
370 return false;
371 }
372
JsDnsDomainLevels(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)373 jerry_value_t PacFunctions::JsDnsDomainLevels(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
374 const jerry_value_t args[], const jerry_length_t argsCnt)
375 {
376 if (argsCnt != ARG_COUNT_1) {
377 return jerry_create_error(JERRY_ERROR_TYPE, JERRY_CONCHAR(INVALID_ARGUMENT));
378 }
379 if (!jerry_value_is_string(args[ARG_INDEX_0])) {
380 return jerry_create_error(JERRY_ERROR_TYPE, JERRY_CONCHAR(INVALID_ARGUMENT));
381 }
382 jerry_size_t host_size = jerry_get_string_size(args[ARG_INDEX_0]);
383 if (host_size < 0) {
384 return jerry_create_boolean(false);
385 }
386 char *host = (char *)malloc(host_size + 1);
387 if (host == nullptr) {
388 return jerry_create_error(JERRY_ERROR_COMMON, JERRY_CONCHAR(MEMORY_ALLOCATION_FAILED));
389 }
390 jerry_string_to_char_buffer(args[ARG_INDEX_0], JERRY_CHAR(host), host_size);
391 host[host_size] = NULL_CHAR;
392 int levels = 0;
393 char *p = host;
394 while ((p = strchr(p, DOT_CHAR)) != nullptr) {
395 levels++;
396 p++;
397 }
398 free(host);
399 return jerry_create_number(levels);
400 }
401
JsShExpMatch(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)402 jerry_value_t PacFunctions::JsShExpMatch(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
403 const jerry_value_t args[], const jerry_length_t argsCnt)
404 {
405 if (argsCnt != ARG_COUNT_2) {
406 return jerry_create_error(JERRY_ERROR_TYPE, JERRY_CONCHAR(INVALID_ARGUMENT));
407 }
408 if (!jerry_value_is_string(args[ARG_INDEX_0]) || !jerry_value_is_string(args[ARG_INDEX_1])) {
409 return jerry_create_error(JERRY_ERROR_TYPE, JERRY_CONCHAR(INVALID_ARGUMENT));
410 }
411 jerry_size_t str_size = jerry_get_string_size(args[ARG_INDEX_0]);
412 jerry_size_t pattern_size = jerry_get_string_size(args[ARG_INDEX_1]);
413 if (str_size < 0) {
414 return jerry_create_error(JERRY_ERROR_COMMON, JERRY_CONCHAR(INVALID_ARGUMENT));
415 }
416 char *str = (char *)malloc(str_size + 1);
417 if (str == nullptr) {
418 return jerry_create_error(JERRY_ERROR_COMMON, JERRY_CONCHAR(MEMORY_ALLOCATION_FAILED));
419 }
420 if (pattern_size < 0) {
421 free(str);
422 return jerry_create_error(JERRY_ERROR_COMMON, JERRY_CONCHAR(INVALID_ARGUMENT));
423 }
424 char *pattern = (char *)malloc(pattern_size + 1);
425 if (pattern == nullptr) {
426 free(str);
427 return jerry_create_error(JERRY_ERROR_COMMON, JERRY_CONCHAR(MEMORY_ALLOCATION_FAILED));
428 }
429 jerry_string_to_char_buffer(args[ARG_INDEX_0], JERRY_CHAR(str), str_size);
430 jerry_string_to_char_buffer(args[ARG_INDEX_1], JERRY_CHAR(pattern), pattern_size);
431 str[str_size] = NULL_CHAR;
432 pattern[pattern_size] = NULL_CHAR;
433 int result = MatchPattern(str, pattern);
434 free(str);
435 free(pattern);
436 return jerry_create_boolean(result);
437 }
438
MonthAbbrToNumber(const char * abbr)439 static int MonthAbbrToNumber(const char *abbr)
440 {
441 if (abbr == nullptr || strlen(abbr) < ARG_COUNT_3) {
442 return -1;
443 }
444 char upperAbbr[ARG_INDEX_4];
445 for (int i = 0; i < ARG_COUNT_3; i++) {
446 upperAbbr[i] = toupper(abbr[i]);
447 }
448 upperAbbr[ARG_INDEX_3] = NULL_CHAR;
449 for (int i = 0; i < MONTH_COUNT; i++) {
450 if (strcmp(upperAbbr, MONTH_NAMES[i]) == 0) {
451 return i;
452 }
453 }
454 return -1;
455 }
456
JsDateRangeArg1Num(const jerry_value_t args[],struct tm * timeinfo)457 static jerry_value_t JsDateRangeArg1Num(const jerry_value_t args[], struct tm *timeinfo)
458 {
459 int num = jerry_get_number_value(args[ARG_INDEX_0]);
460 if (num >= ARG_COUNT_1 && num <= ARG_COUNT_31) {
461 return jerry_create_boolean(timeinfo->tm_mday == num);
462 } else {
463 return jerry_create_boolean(timeinfo->tm_year + YEAR_BASE == num);
464 }
465 }
466
JsDateRangeArg61(const jerry_value_t args[],struct tm * timeinfo)467 static jerry_value_t JsDateRangeArg61(const jerry_value_t args[], struct tm *timeinfo)
468 {
469 int day0 = jerry_get_number_value(args[ARG_INDEX_0]);
470 jerry_size_t mon0_size = jerry_get_string_size(args[ARG_INDEX_1]);
471 jerry_char_t mon0_buff[mon0_size+1];
472 jerry_string_to_char_buffer(args[ARG_INDEX_1], mon0_buff, mon0_size);
473 mon0_buff[mon0_size] = NULL_CHAR;
474 int m0 = MonthAbbrToNumber((const char *)mon0_buff);
475 int year0 = jerry_get_number_value(args[ARG_INDEX_2]);
476 int day1 = jerry_get_number_value(args[ARG_INDEX_3]);
477 jerry_size_t mon1_size = jerry_get_string_size(args[ARG_INDEX_4]);
478 jerry_char_t mon1_buff[mon1_size+1];
479 jerry_string_to_char_buffer(args[ARG_INDEX_4], mon1_buff, mon1_size);
480 mon1_buff[mon1_size] = NULL_CHAR;
481 int m1 = MonthAbbrToNumber((const char *)mon1_buff);
482 int year1 = jerry_get_number_value(args[ARG_INDEX_5]);
483 int value0 = (year0) * TEN_THOUSAND + (m0 + 1) * HUNDRED + day0;
484 int value1 = (year1) * TEN_THOUSAND + (m1 + 1) * HUNDRED + day1;
485 int currentValue = (timeinfo->tm_year + YEAR_BASE) * TEN_THOUSAND +
486 (timeinfo->tm_mon + 1) * HUNDRED + timeinfo->tm_mday;
487 return jerry_create_boolean(currentValue >= value0 && currentValue <= value1);
488 }
489
JsDateRangeArg42(const jerry_value_t args[],struct tm * timeinfo)490 static jerry_value_t JsDateRangeArg42(const jerry_value_t args[], struct tm *timeinfo)
491 {
492 int day0 = 1;
493 jerry_size_t mon0_size = jerry_get_string_size(args[ARG_INDEX_0]);
494 jerry_char_t mon0_buff[mon0_size+1];
495 jerry_string_to_char_buffer(args[ARG_INDEX_0], mon0_buff, mon0_size);
496 mon0_buff[mon0_size] = NULL_CHAR;
497 int m0 = MonthAbbrToNumber((const char *)mon0_buff);
498 int year0 = jerry_get_number_value(args[ARG_INDEX_1]);
499 int day1 = ARG_COUNT_31;
500 jerry_size_t mon1_size = jerry_get_string_size(args[ARG_INDEX_2]);
501 jerry_char_t mon1_buff[mon1_size+1];
502 jerry_string_to_char_buffer(args[ARG_INDEX_2], mon1_buff, mon1_size);
503 mon1_buff[mon1_size] = NULL_CHAR;
504 int m1 = MonthAbbrToNumber((const char *)mon1_buff);
505 int year1 = jerry_get_number_value(args[ARG_INDEX_3]);
506 int value0 = (year0) * TEN_THOUSAND + (m0 + 1) * HUNDRED + day0;
507 int value1 = (year1) * TEN_THOUSAND + (m1 + 1) * HUNDRED + day1;
508 int currentValue = (timeinfo->tm_year + YEAR_BASE) * TEN_THOUSAND +
509 (timeinfo->tm_mon + 1) * HUNDRED + timeinfo->tm_mday;
510 return jerry_create_boolean(currentValue >= value0 && currentValue <= value1);
511 }
512
JsDateRangeArg41(const jerry_value_t args[],struct tm * timeinfo)513 static jerry_value_t JsDateRangeArg41(const jerry_value_t args[], struct tm *timeinfo)
514 {
515 int day0 = jerry_get_number_value(args[ARG_INDEX_0]);
516 jerry_size_t mon0_size = jerry_get_string_size(args[ARG_INDEX_1]);
517 jerry_char_t mon0_buff[mon0_size+1];
518 jerry_string_to_char_buffer(args[ARG_INDEX_1], mon0_buff, mon0_size);
519 mon0_buff[mon0_size] = NULL_CHAR;
520 int m0 = MonthAbbrToNumber((const char *)mon0_buff);
521 int day1 = jerry_get_number_value(args[ARG_INDEX_2]);
522 jerry_size_t mon1_size = jerry_get_string_size(args[ARG_INDEX_3]);
523 jerry_char_t mon1_buff[mon1_size+1];
524 jerry_string_to_char_buffer(args[ARG_INDEX_3], mon1_buff, mon1_size);
525 mon1_buff[mon1_size] = NULL_CHAR;
526 int m1 = MonthAbbrToNumber((const char *)mon1_buff);
527 int currentValue = (timeinfo->tm_mon + 1) * HUNDRED + timeinfo->tm_mday;
528 int value0 = (m0 + 1) * HUNDRED + day0;
529 int value1 = (m1 + 1) * HUNDRED + day1;
530 return jerry_create_boolean(currentValue >= value0 && currentValue <= value1);
531 }
532
JsDateRangeArg2StrStr(const jerry_value_t args[],struct tm * timeinfo)533 static jerry_value_t JsDateRangeArg2StrStr(const jerry_value_t args[], struct tm *timeinfo)
534 {
535 jerry_size_t mon0_size = jerry_get_string_size(args[ARG_INDEX_0]);
536 jerry_char_t mon0_buff[mon0_size+1];
537 jerry_string_to_char_buffer(args[ARG_INDEX_0], mon0_buff, mon0_size);
538 mon0_buff[mon0_size] = NULL_CHAR;
539 jerry_size_t mon1_size = jerry_get_string_size(args[ARG_INDEX_1]);
540 jerry_char_t mon1_buff[mon1_size+1];
541 jerry_string_to_char_buffer(args[ARG_INDEX_1], mon1_buff, mon1_size);
542 mon1_buff[mon1_size] = NULL_CHAR;
543 int m0 = MonthAbbrToNumber((const char *)mon0_buff);
544 int m1 = MonthAbbrToNumber((const char *)mon1_buff);
545 return jerry_create_boolean(timeinfo->tm_mon >= m0 && timeinfo->tm_mon <= m1);
546 }
547
JsDateRangeArg2NumNum(const jerry_value_t args[],struct tm * timeinfo)548 static jerry_value_t JsDateRangeArg2NumNum(const jerry_value_t args[], struct tm *timeinfo)
549 {
550 int num1 = jerry_get_number_value(args[ARG_INDEX_0]);
551 int num2 = jerry_get_number_value(args[ARG_INDEX_1]);
552 if (num1 > YEAR_BASE && num2 > YEAR_BASE) {
553 return jerry_create_boolean(timeinfo->tm_year + YEAR_BASE >= num1 && timeinfo->tm_year + YEAR_BASE <= num2);
554 } else {
555 return jerry_create_boolean(timeinfo->tm_mday >= num1 && timeinfo->tm_mday <= num2);
556 }
557 }
558
JsDateRangeArg2NumStr(const jerry_value_t args[],struct tm * timeinfo)559 static jerry_value_t JsDateRangeArg2NumStr(const jerry_value_t args[], struct tm *timeinfo)
560 {
561 int num = jerry_get_number_value(args[ARG_INDEX_0]);
562 jerry_size_t str_size = jerry_get_string_size(args[ARG_INDEX_1]);
563 jerry_char_t str_buff[str_size+1];
564 jerry_string_to_char_buffer(args[ARG_INDEX_1], str_buff, str_size);
565 str_buff[str_size] = NULL_CHAR;
566 if (strcmp((const char *)(str_buff), GMT) == 0) {
567 time_t rawtimeGmt;
568 struct tm *timeinfoGmt;
569 time(&rawtimeGmt);
570 timeinfoGmt = gmtime(&rawtimeGmt);
571 return jerry_create_boolean(timeinfoGmt->tm_mday == num);
572 } else {
573 int mon = MonthAbbrToNumber((const char *)(str_buff));
574 return jerry_create_boolean(mon == timeinfo->tm_mon && num == timeinfo->tm_mday);
575 }
576 }
577
578 static std::vector<Checker> jsDateRangeCheckers = {
__anonab2fece70202() 579 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
580 return argsCnt < ARG_COUNT_1 || argsCnt > ARG_COUNT_7;
581 },
__anonab2fece70302() 582 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
583 return argsCnt == ARG_COUNT_1 && jerry_value_is_number(args[ARG_INDEX_0]);
584 },
__anonab2fece70402() 585 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
586 return argsCnt == ARG_COUNT_2 && jerry_value_is_number(args[ARG_INDEX_0]) &&
587 jerry_value_is_string(args[ARG_INDEX_1]);
588 },
__anonab2fece70502() 589 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
590 return argsCnt == ARG_COUNT_2 && jerry_value_is_number(args[ARG_INDEX_0]) &&
591 jerry_value_is_number(args[ARG_INDEX_1]);
592 },
__anonab2fece70602() 593 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
594 return argsCnt == ARG_COUNT_2 && jerry_value_is_string(args[ARG_INDEX_0]) &&
595 jerry_value_is_string(args[ARG_INDEX_1]);
596 },
__anonab2fece70702() 597 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
598 return argsCnt == ARG_COUNT_4 && jerry_value_is_number(args[ARG_INDEX_0]) &&
599 jerry_value_is_string(args[ARG_INDEX_1]) && jerry_value_is_number(args[ARG_INDEX_2]) &&
600 jerry_value_is_string(args[ARG_INDEX_3]);
601 },
__anonab2fece70802() 602 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
603 return argsCnt == ARG_COUNT_6 && jerry_value_is_number(args[ARG_INDEX_0]) &&
604 jerry_value_is_string(args[ARG_INDEX_1]) && jerry_value_is_number(args[ARG_INDEX_2]) &&
605 jerry_value_is_number(args[ARG_INDEX_3]) && jerry_value_is_string(args[ARG_INDEX_4]) &&
606 jerry_value_is_number(args[ARG_INDEX_5]);
607 },
__anonab2fece70902() 608 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
609 return argsCnt == ARG_COUNT_4 && jerry_value_is_string(args[ARG_INDEX_0]) &&
610 jerry_value_is_number(args[ARG_INDEX_1]) && jerry_value_is_string(args[ARG_INDEX_2]) &&
611 jerry_value_is_number(args[ARG_INDEX_3]);
612 },
__anonab2fece70a02() 613 [](const jerry_length_t argsCnt, const jerry_value_t args[]) {
614 return argsCnt == ARG_COUNT_3 && jerry_value_is_number(args[0]) && jerry_value_is_string(args[1]) &&
615 jerry_value_is_number(args[2]);
616 },
617 };
618
JsDateRangeArg3(const jerry_value_t args[],struct tm * timeinfo)619 static jerry_value_t JsDateRangeArg3(const jerry_value_t args[], struct tm *timeinfo)
620 {
621 int day = jerry_get_number_value(args[0]);
622 jerry_size_t mon_size = jerry_get_string_size(args[1]);
623 jerry_char_t mon_buff[mon_size+11];
624 jerry_string_to_char_buffer(args[1], mon_buff, mon_size);
625 mon_buff[mon_size] = NULL_CHAR;
626 int month = MonthAbbrToNumber((const char *)mon_buff);
627 int year = jerry_get_number_value(args[2]);
628 if (month < 0) {
629 return jerry_create_boolean(false);
630 }
631 return jerry_create_boolean(timeinfo->tm_mday == day && timeinfo->tm_mon == month &&
632 timeinfo->tm_year + YEAR_BASE == year);
633 }
634
635 static std::vector<Handler> jsDateRangeHandler = {
__anonab2fece70b02() 636 [](const jerry_value_t args[], struct tm *timeinfo) { return jerry_create_boolean(false); },
__anonab2fece70c02() 637 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg1Num(args, timeinfo); },
__anonab2fece70d02() 638 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg2NumStr(args, timeinfo); },
__anonab2fece70e02() 639 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg2NumNum(args, timeinfo); },
__anonab2fece70f02() 640 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg2StrStr(args, timeinfo); },
__anonab2fece71002() 641 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg41(args, timeinfo); },
__anonab2fece71102() 642 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg61(args, timeinfo); },
__anonab2fece71202() 643 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg42(args, timeinfo); },
__anonab2fece71302() 644 [](const jerry_value_t args[], struct tm *timeinfo) { return JsDateRangeArg3(args, timeinfo); },
645 };
646
JsDateRange(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)647 jerry_value_t PacFunctions::JsDateRange(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
648 const jerry_value_t args[], const jerry_length_t argsCnt)
649 {
650 time_t rawtime;
651 struct tm *timeinfo;
652 if (time(&rawtime) == static_cast<time_t>(-1)) {
653 return jerry_create_boolean(false);
654 }
655 int useGmt = 0;
656 timeinfo = localtime(&rawtime);
657 for (int i = 0; i < jsDateRangeCheckers.size(); i++) {
658 if (jsDateRangeCheckers[i](argsCnt, args)) {
659 return jsDateRangeHandler[i](args, timeinfo);
660 }
661 }
662 return jerry_create_boolean(false);
663 }
664
665 struct TimeParam {
666 int h0;
667 int m0;
668 int s0;
669 int h1;
670 int m1;
671 int s1;
672 };
673
IsBetweenTime(TimeParam param,struct tm * timeinfo)674 static bool IsBetweenTime(TimeParam param, struct tm *timeinfo)
675 {
676 int h = timeinfo->tm_hour;
677 int m = timeinfo->tm_min;
678 int s = timeinfo->tm_sec;
679 int timeSeconds = h * SECONDS_PER_HOUR + m * SECONDS_PER_MINUTE + s;
680 int startSeconds = param.h0 * SECONDS_PER_HOUR + param.m0 * SECONDS_PER_MINUTE + param.s0;
681 int endSeconds = param.h1 * SECONDS_PER_HOUR + param.m1 * SECONDS_PER_MINUTE + param.s1;
682 if (startSeconds <= endSeconds) {
683 return (timeSeconds >= startSeconds && timeSeconds <= endSeconds);
684 } else {
685 return (timeSeconds >= startSeconds || timeSeconds <= endSeconds);
686 }
687 }
688
ValidateBasicConditions(time_t rawtime,const jerry_length_t argsCnt)689 static bool ValidateBasicConditions(time_t rawtime, const jerry_length_t argsCnt)
690 {
691 return rawtime != static_cast<time_t>(-1) && argsCnt >= ARG_COUNT_1 && argsCnt <= ARG_COUNT_7;
692 }
693
694 struct TimezoneResult {
695 struct tm *timeinfo;
696 bool useGMT;
697 bool isValid;
698 };
699
ProcessTimezone(time_t rawtime,const jerry_value_t args[],const jerry_length_t argsCnt)700 static TimezoneResult ProcessTimezone(time_t rawtime, const jerry_value_t args[], const jerry_length_t argsCnt)
701 {
702 struct tm *timeinfo = localtime(&rawtime);
703 bool useGMT = false;
704 if (argsCnt < ARG_COUNT_2 || !jerry_value_is_string(args[ARG_INDEX_1])) {
705 return {timeinfo, useGMT, true};
706 }
707 jerry_size_t str_size = jerry_get_string_size(args[ARG_INDEX_1]);
708 jerry_char_t str_buf[str_size+1];
709 jerry_string_to_char_buffer(args[ARG_INDEX_1], str_buf, str_size);
710 str_buf[str_size] = NULL_CHAR;
711 if (strcmp((char *)str_buf, GMT) == 0) {
712 timeinfo = gmtime(&rawtime);
713 useGMT = true;
714 return {timeinfo, useGMT, true};
715 }
716 return {nullptr, false, false};
717 }
718
ParseSingleHourArg(const jerry_value_t args[],TimeParam & range)719 static bool ParseSingleHourArg(const jerry_value_t args[], TimeParam &range)
720 {
721 if (!jerry_value_is_number(args[ARG_INDEX_0])) {
722 return false;
723 }
724 int h = jerry_get_number_value(args[ARG_INDEX_0]);
725 range = {h, 0, 0, h + 1, 0, 0};
726 return true;
727 }
728
ParseTwoArgs(const jerry_value_t args[],bool useGMT,TimeParam & range)729 static bool ParseTwoArgs(const jerry_value_t args[], bool useGMT, TimeParam &range)
730 {
731 if (!jerry_value_is_number(args[ARG_INDEX_0])) {
732 return false;
733 }
734 int h0 = jerry_get_number_value(args[ARG_INDEX_0]);
735 int h1;
736 if (useGMT) {
737 h1 = h0 + 1;
738 } else {
739 if (!jerry_value_is_number(args[ARG_INDEX_1])) {
740 return false;
741 }
742 h1 = jerry_get_number_value(args[ARG_INDEX_1]);
743 }
744 range = {h0, 0, 0, h1, 0, 0};
745 return true;
746 }
747
ParseFourArgs(const jerry_value_t args[],TimeParam & range)748 static bool ParseFourArgs(const jerry_value_t args[], TimeParam &range)
749 {
750 for (int i = 0; i < ARG_COUNT_4; i++) {
751 if (!jerry_value_is_number(args[i])) {
752 return false;
753 }
754 }
755 range = {jerry_get_number_value(args[ARG_INDEX_0]), jerry_get_number_value(args[ARG_INDEX_1]), 0,
756 jerry_get_number_value(args[ARG_INDEX_2]), jerry_get_number_value(args[ARG_INDEX_3]), 0};
757 return true;
758 }
759
ParseSixArgs(const jerry_value_t args[],TimeParam & range)760 static bool ParseSixArgs(const jerry_value_t args[], TimeParam &range)
761 {
762 for (int i = 0; i < ARG_COUNT_6; i++) {
763 if (!jerry_value_is_number(args[i])) {
764 return false;
765 }
766 }
767 range = {jerry_get_number_value(args[ARG_INDEX_0]), jerry_get_number_value(args[ARG_INDEX_1]),
768 jerry_get_number_value(args[ARG_INDEX_2]), jerry_get_number_value(args[ARG_INDEX_3]),
769 jerry_get_number_value(args[ARG_INDEX_4]), jerry_get_number_value(args[ARG_INDEX_5])};
770 return true;
771 }
772
ParseTimeRangeArgs(const jerry_value_t args[],const jerry_length_t argsCnt,bool useGMT,TimeParam & range)773 static bool ParseTimeRangeArgs(const jerry_value_t args[], const jerry_length_t argsCnt, bool useGMT, TimeParam &range)
774 {
775 switch (argsCnt) {
776 case ARG_COUNT_1:
777 return ParseSingleHourArg(args, range);
778 case ARG_COUNT_2:
779 return ParseTwoArgs(args, useGMT, range);
780 case ARG_COUNT_4:
781 return ParseFourArgs(args, range);
782 case ARG_COUNT_6:
783 return ParseSixArgs(args, range);
784 default:
785 return false;
786 }
787 }
788
JsTimeRange(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)789 jerry_value_t PacFunctions::JsTimeRange(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
790 const jerry_value_t args[], const jerry_length_t argsCnt)
791 {
792 time_t rawtime;
793 if (time(&rawtime) == static_cast<time_t>(-1)) {
794 return jerry_create_boolean(false);
795 }
796 if (!ValidateBasicConditions(rawtime, argsCnt)) {
797 return jerry_create_boolean(false);
798 }
799 TimezoneResult tzResult = ProcessTimezone(rawtime, args, argsCnt);
800 if (!tzResult.isValid) {
801 return jerry_create_boolean(false);
802 }
803 TimeParam range = {0, 0, 0, 0, 0, 0};
804 if (!ParseTimeRangeArgs(args, argsCnt, tzResult.useGMT, range)) {
805 return jerry_create_boolean(false);
806 }
807 return jerry_create_boolean(IsBetweenTime(range, tzResult.timeinfo));
808 }
809
ParseDayName(jerry_value_t dayArg)810 static int ParseDayName(jerry_value_t dayArg)
811 {
812 if (!jerry_value_is_string(dayArg)) {
813 return -1;
814 }
815 jerry_size_t strSize = jerry_get_string_size(dayArg);
816 if (strSize < 0) {
817 return -1;
818 }
819 char strBuf[strSize + 1];
820 jerry_string_to_char_buffer(dayArg, reinterpret_cast<jerry_char_t *>(strBuf), strSize);
821 strBuf[strSize] = NULL_CHAR;
822 for (int i = 0; i < DAY_COUNT; i++) {
823 if (strcmp(reinterpret_cast<char *>(strBuf), DAY_NAMES[i]) == 0) {
824 return i;
825 }
826 }
827 return -1;
828 }
829
830 struct TimeResult {
831 struct tm *timeinfo;
832 bool valid;
833 };
834
GetTimeInfo(bool useGmt)835 static TimeResult GetTimeInfo(bool useGmt)
836 {
837 time_t rawtime;
838 if (time(&rawtime) == static_cast<time_t>(-1)) {
839 return {nullptr, false};
840 }
841 struct tm *timeinfo = useGmt ? gmtime(&rawtime) : localtime(&rawtime);
842 return {timeinfo, timeinfo != nullptr};
843 }
844
ShouldUseGmt(const jerry_value_t args[],jerry_length_t argsCnt)845 static bool ShouldUseGmt(const jerry_value_t args[], jerry_length_t argsCnt)
846 {
847 if (argsCnt <= ARG_COUNT_1) {
848 return false;
849 }
850 jerry_value_t lastArg = args[argsCnt - 1];
851 if (!jerry_value_is_string(lastArg)) {
852 return false;
853 }
854 jerry_size_t strSize = jerry_get_string_size(lastArg);
855 if (strSize == 0) {
856 return false;
857 }
858 char str_buf[strSize + 1];
859 jerry_string_to_char_buffer(lastArg, reinterpret_cast<jerry_char_t *>(str_buf), strSize);
860 str_buf[strSize] = NULL_CHAR;
861 return strcmp(str_buf, GMT) == 0;
862 }
863
864 struct DayRange {
865 int startDay;
866 int endDay;
867 bool valid;
868 };
869
ParseDayRange(const jerry_value_t args[],jerry_length_t argsCnt,bool useGmt)870 static DayRange ParseDayRange(const jerry_value_t args[], jerry_length_t argsCnt, bool useGmt)
871 {
872 int startDay = ParseDayName(args[ARG_INDEX_0]);
873 if (startDay == -1) {
874 return {-1, -1, false};
875 }
876 int endDay = startDay;
877 bool hasSecondDay = (argsCnt == ARG_COUNT_2 && !useGmt) || (argsCnt == ARG_COUNT_3 && useGmt);
878 if (hasSecondDay) {
879 int secondArgIndex = useGmt ? 1 : ARG_INDEX_1;
880 endDay = ParseDayName(args[secondArgIndex]);
881 if (endDay == -1) {
882 return {-1, -1, false};
883 }
884 }
885 return {startDay, endDay, true};
886 }
887
IsWeekdayInRange(int currentWeekday,int startDay,int endDay)888 static bool IsWeekdayInRange(int currentWeekday, int startDay, int endDay)
889 {
890 return (startDay <= endDay) ? (currentWeekday >= startDay && currentWeekday <= endDay)
891 : (currentWeekday >= startDay || currentWeekday <= endDay);
892 }
893
JsWeekdayRange(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)894 jerry_value_t PacFunctions::JsWeekdayRange(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
895 const jerry_value_t args[], const jerry_length_t argsCnt)
896 {
897 if (argsCnt < ARG_COUNT_1 || argsCnt > ARG_COUNT_3) {
898 return jerry_create_boolean(false);
899 }
900 bool useGmt = ShouldUseGmt(args, argsCnt);
901 TimeResult timeResult = GetTimeInfo(useGmt);
902 if (!timeResult.valid) {
903 return jerry_create_boolean(false);
904 }
905 DayRange dayRange = ParseDayRange(args, argsCnt, useGmt);
906 if (!dayRange.valid) {
907 return jerry_create_boolean(false);
908 }
909 int currentWeekday = timeResult.timeinfo->tm_wday;
910 bool inRange = IsWeekdayInRange(currentWeekday, dayRange.startDay, dayRange.endDay);
911 return jerry_create_boolean(inRange);
912 }
913
CheckIpv4InNet(const char * ip,const char * cidr,int prefixLen)914 static bool CheckIpv4InNet(const char *ip, const char *cidr, int prefixLen)
915 {
916 struct in_addr ip4;
917 struct in_addr net4;
918 if (inet_pton(AF_INET, ip, &ip4) != 1 || inet_pton(AF_INET, cidr, &net4) != 1) {
919 return false;
920 }
921 uint32_t mask = (prefixLen == 32) ? 0xffffffff : ~((1 << (32 - prefixLen)) - 1);
922 return (ip4.s_addr & htonl(mask)) == (net4.s_addr & htonl(mask));
923 }
924
CheckIpv6InNet(const char * ip,const char * cidr,int prefixLen)925 static bool CheckIpv6InNet(const char *ip, const char *cidr, int prefixLen)
926 {
927 struct in6_addr ipAddr;
928 struct in6_addr netAddr;
929 if (inet_pton(AF_INET6, ip, &ipAddr) != 1 || inet_pton(AF_INET6, cidr, &netAddr) != 1) {
930 return false;
931 }
932 int bytes = prefixLen / 8;
933 int bits = prefixLen % 8;
934 for (int i = 0; i < bytes; i++) {
935 if (ipAddr.s6_addr[i] != netAddr.s6_addr[i]) {
936 return false;
937 }
938 }
939 if (bits > 0) {
940 uint8_t mask = 0xff << (8 - bits);
941 return (ipAddr.s6_addr[bytes] & mask) == (netAddr.s6_addr[bytes] & mask);
942 }
943 return true;
944 }
945
JsIsInNetEx(const jerry_value_t funcObjVal,const jerry_value_t thisVal,const jerry_value_t args[],const jerry_length_t argsCnt)946 jerry_value_t PacFunctions::JsIsInNetEx(const jerry_value_t funcObjVal, const jerry_value_t thisVal,
947 const jerry_value_t args[], const jerry_length_t argsCnt)
948 {
949 if (argsCnt < ARG_COUNT_2) {
950 return jerry_create_boolean(false);
951 }
952 char *ip = JerryStringToChar(args[ARG_INDEX_0]);
953 char *cidr = JerryStringToChar(args[ARG_INDEX_1]);
954 if (!ip || !cidr) {
955 free(ip);
956 free(cidr);
957 return jerry_create_boolean(false);
958 }
959 char *slash = strchr(cidr, PATH_CHAR);
960 if (!slash) {
961 free(ip);
962 free(cidr);
963 return jerry_create_boolean(false);
964 }
965 *slash = NULL_CHAR;
966 int prefixLen = atoi(slash + 1);
967 bool isIpv4 = (strchr(ip, COLON_CHAR) == nullptr && strchr(cidr, COLON_CHAR) == nullptr);
968 bool result = isIpv4 ? CheckIpv4InNet(ip, cidr, prefixLen) : CheckIpv6InNet(ip, cidr, prefixLen);
969 free(ip);
970 free(cidr);
971 return jerry_create_boolean(result);
972 }
973
RegisterGlobalFunction(jerry_value_t globalObj,const char * funcName,jerry_external_handler_t handler)974 void PacFunctions::RegisterGlobalFunction(jerry_value_t globalObj,
975 const char *funcName, jerry_external_handler_t handler)
976 {
977 jerry_value_t funcNameVal = CreateJerryString(funcName);
978 jerry_value_t funcObj = jerry_create_external_function(handler);
979 jerry_release_value(jerry_set_property(globalObj, funcNameVal, funcObj));
980 jerry_release_value(funcNameVal);
981 jerry_release_value(funcObj);
982 }
983
RegisterHostDomainFunctions(jerry_value_t globalObj)984 void PacFunctions::RegisterHostDomainFunctions(jerry_value_t globalObj)
985 {
986 RegisterGlobalFunction(globalObj, "isPlainHostName", JsIsPlainHostname);
987 RegisterGlobalFunction(globalObj, "dnsDomainIs", JsDnsDomainIs);
988 RegisterGlobalFunction(globalObj, "localHostOrDomainIs", JsLocalHostOrDomainIs);
989 RegisterGlobalFunction(globalObj, "dnsDomainLevels", JsDnsDomainLevels);
990 }
991
RegisterDnsResolveFunctions(jerry_value_t globalObj)992 void PacFunctions::RegisterDnsResolveFunctions(jerry_value_t globalObj)
993 {
994 RegisterGlobalFunction(globalObj, "isResolvable", JsIsResolvable);
995 RegisterGlobalFunction(globalObj, "isResolvableEx", JsIsResolvable);
996 RegisterGlobalFunction(globalObj, "dnsResolve", JsDnsResolve);
997 RegisterGlobalFunction(globalObj, "dnsResolveEx", JsDnsResolve);
998 RegisterGlobalFunction(globalObj, "sortIpAddressList", JsSortIpAddressList);
999 }
1000
RegisterIpAddressFunctions(jerry_value_t globalObj)1001 void PacFunctions::RegisterIpAddressFunctions(jerry_value_t globalObj)
1002 {
1003 RegisterGlobalFunction(globalObj, "myIpAddress", JsMyIpAddress);
1004 RegisterGlobalFunction(globalObj, "myIpAddressEx", JsMyIpAddressEx);
1005 RegisterGlobalFunction(globalObj, "isInNet", JsIsInNet);
1006 RegisterGlobalFunction(globalObj, "isInNetEx", JsIsInNetEx);
1007 }
1008
RegisterTimeAndDateFunctions(jerry_value_t globalObj)1009 void PacFunctions::RegisterTimeAndDateFunctions(jerry_value_t globalObj)
1010 {
1011 RegisterGlobalFunction(globalObj, "weekdayRange", JsWeekdayRange);
1012 RegisterGlobalFunction(globalObj, "timeRange", JsTimeRange);
1013 RegisterGlobalFunction(globalObj, "dateRange", JsDateRange);
1014 }
1015
RegisterPatternMatchingFunctions(jerry_value_t globalObj)1016 void PacFunctions::RegisterPatternMatchingFunctions(jerry_value_t globalObj)
1017 {
1018 RegisterGlobalFunction(globalObj, "shExpMatch", JsShExpMatch);
1019 }
1020
RegisterPacFunctions(void)1021 void PacFunctions::RegisterPacFunctions(void)
1022 {
1023 jerry_value_t globalObj = jerry_get_global_object();
1024 RegisterHostDomainFunctions(globalObj);
1025 RegisterDnsResolveFunctions(globalObj);
1026 RegisterIpAddressFunctions(globalObj);
1027 RegisterTimeAndDateFunctions(globalObj);
1028 RegisterPatternMatchingFunctions(globalObj);
1029 jerry_release_value(globalObj);
1030 }
1031 } // namespace NetManagerStandard
1032 } // namespace OHOS
1033