1 /*
2  * Copyright (c) 2023 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 #include "napi/native_api.h"
16 #include <cerrno>
17 #include <cstdio>
18 #include <cstring>
19 #include <fcntl.h>
20 #include <iconv.h>
21 #include <js_native_api.h>
22 #include <malloc.h>
23 #include <node_api.h>
24 
25 #define BUFF_SIZE 1024
26 #define NO_ERR 0
27 #define SUCCESS 1
28 #define FAIL (-1)
29 #define PARAM_100 100
30 #define PARAM_0 0
31 
Iconv(napi_env env, napi_callback_info info)32 static napi_value Iconv(napi_env env, napi_callback_info info)
33 {
34     iconv_t cd;
35     char buf[PARAM_100];
36     char *inbuf = static_cast<char *>(malloc(sizeof("hello,world!")));
37     memcpy(inbuf, "hello,world!", sizeof("hello,world!"));
38     char *outbuf = buf;
39     size_t inlen = strlen(inbuf);
40     size_t outlen;
41     size_t r;
42     const char *bad = "bad-codeset";
43     cd = iconv_open(bad, bad);
44     cd = iconv_open("UTF-8", "UTF-8");
45     errno = PARAM_0;
46     outlen = PARAM_0;
47     r = iconv(cd, &inbuf, &inlen, &outbuf, &outlen);
48     outlen = sizeof buf;
49     r = iconv(cd, &inbuf, &inlen, &outbuf, &outlen);
50     napi_value result = nullptr;
51     iconv_close(cd);
52     napi_create_int32(env, r, &result);
53     return result;
54 }
55 
IconvOpen(napi_env env, napi_callback_info info)56 static napi_value IconvOpen(napi_env env, napi_callback_info info)
57 {
58     iconv_t cd;
59     char buf[PARAM_100];
60     char *inbuf = static_cast<char *>(malloc(sizeof("hello,world!")));
61     memcpy(inbuf, "hello,world!", sizeof("hello,world!"));
62     char *outbuf = buf;
63     size_t inlen = strlen(inbuf);
64     size_t outlen;
65     const char *bad = "bad-codeset";
66     cd = iconv_open(bad, bad);
67     cd = iconv_open("UTF-8", "UTF-8");
68     errno = PARAM_0;
69     outlen = PARAM_0;
70     iconv(cd, &inbuf, &inlen, &outbuf, &outlen);
71     outlen = sizeof buf;
72     iconv(cd, &inbuf, &inlen, &outbuf, &outlen);
73     napi_value result = nullptr;
74     if (cd == nullptr) {
75         napi_create_int32(env, FAIL, &result);
76     } else {
77         napi_create_int32(env, NO_ERR, &result);
78     }
79     iconv_close(cd);
80     return result;
81 }
82 
IconvClose(napi_env env, napi_callback_info info)83 static napi_value IconvClose(napi_env env, napi_callback_info info)
84 {
85     iconv_t cd;
86     char buf[PARAM_100];
87     char *inbuf = static_cast<char *>(malloc(sizeof("hello,world!")));
88     memcpy(inbuf, "hello,world!", sizeof("hello,world!"));
89     char *outbuf = buf;
90     size_t inlen = strlen(inbuf);
91     size_t outlen;
92     const char *bad = "bad-codeset";
93     cd = iconv_open(bad, bad);
94     cd = iconv_open("UTF-8", "UTF-8");
95     errno = PARAM_0;
96     outlen = PARAM_0;
97     iconv(cd, &inbuf, &inlen, &outbuf, &outlen);
98     outlen = sizeof buf;
99     iconv(cd, &inbuf, &inlen, &outbuf, &outlen);
100     int ret = iconv_close(cd);
101     napi_value result = nullptr;
102     if (ret == FAIL) {
103         napi_create_int32(env, FAIL, &result);
104     } else {
105         napi_create_int32(env, NO_ERR, &result);
106     }
107     return result;
108 }
109 
110 EXTERN_C_START
Init(napi_env env, napi_value exports)111 static napi_value Init(napi_env env, napi_value exports)
112 {
113     napi_property_descriptor desc[] = {
114         {"iconv", nullptr, Iconv, nullptr, nullptr, nullptr, napi_default, nullptr},
115         {"iconvOpen", nullptr, IconvOpen, nullptr, nullptr, nullptr, napi_default, nullptr},
116         {"iconvClose", nullptr, IconvClose, nullptr, nullptr, nullptr, napi_default, nullptr},
117     };
118     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
119     return exports;
120 }
121 EXTERN_C_END
122 
123 static napi_module demoModule = {
124     .nm_version = 1,
125     .nm_flags = 0,
126     .nm_filename = nullptr,
127     .nm_register_func = Init,
128     .nm_modname = "wchar",
129     .nm_priv = ((void *)0),
130     .reserved = {0},
131 };
132 
RegisterEntryModule(void)133 extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&demoModule); }
134