• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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