non-ascii.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 
23 #include "curl_setup.h"
24 
25 #ifdef CURL_DOES_CONVERSIONS
26 
27 #include <curl/curl.h>
28 
29 #include "non-ascii.h"
30 #include "formdata.h"
31 #include "sendf.h"
32 #include "urldata.h"
33 
34 #include "curl_memory.h"
35 /* The last #include file should be: */
36 #include "memdebug.h"
37 
38 #ifdef HAVE_ICONV
39 #include <iconv.h>
40 /* set default codesets for iconv */
41 #ifndef CURL_ICONV_CODESET_OF_NETWORK
42 #define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
43 #endif
44 #ifndef CURL_ICONV_CODESET_FOR_UTF8
45 #define CURL_ICONV_CODESET_FOR_UTF8 "UTF-8"
46 #endif
47 #define ICONV_ERROR (size_t)-1
48 #endif /* HAVE_ICONV */
49 
50 /*
51  * Curl_convert_clone() returns a malloced copy of the source string (if
52  * returning CURLE_OK), with the data converted to network format.
53  */
55  const char *indata,
56  size_t insize,
57  char **outbuf)
58 {
59  char *convbuf;
61 
62  convbuf = malloc(insize);
63  if(!convbuf)
64  return CURLE_OUT_OF_MEMORY;
65 
66  memcpy(convbuf, indata, insize);
67  result = Curl_convert_to_network(data, convbuf, insize);
68  if(result) {
69  free(convbuf);
70  return result;
71  }
72 
73  *outbuf = convbuf; /* return the converted buffer */
74 
75  return CURLE_OK;
76 }
77 
78 /*
79  * Curl_convert_to_network() is an internal function for performing ASCII
80  * conversions on non-ASCII platforms. It convers the buffer _in place_.
81  */
83  char *buffer, size_t length)
84 {
85  if(data && data->set.convtonetwork) {
86  /* use translation callback */
87  CURLcode result = data->set.convtonetwork(buffer, length);
88  if(result) {
89  failf(data,
90  "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
91  (int)result, curl_easy_strerror(result));
92  }
93 
94  return result;
95  }
96  else {
97 #ifdef HAVE_ICONV
98  /* do the translation ourselves */
99  iconv_t tmpcd = (iconv_t) -1;
100  iconv_t *cd = &tmpcd;
101  char *input_ptr, *output_ptr;
102  size_t in_bytes, out_bytes, rc;
103 
104  /* open an iconv conversion descriptor if necessary */
105  if(data)
106  cd = &data->outbound_cd;
107  if(*cd == (iconv_t)-1) {
108  *cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
110  if(*cd == (iconv_t)-1) {
111  failf(data,
112  "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
113  CURL_ICONV_CODESET_OF_NETWORK,
115  errno, strerror(errno));
116  return CURLE_CONV_FAILED;
117  }
118  }
119  /* call iconv */
120  input_ptr = output_ptr = buffer;
121  in_bytes = out_bytes = length;
122  rc = iconv(*cd, &input_ptr, &in_bytes,
123  &output_ptr, &out_bytes);
124  if(!data)
125  iconv_close(tmpcd);
126  if((rc == ICONV_ERROR) || (in_bytes != 0)) {
127  failf(data,
128  "The Curl_convert_to_network iconv call failed with errno %i: %s",
129  errno, strerror(errno));
130  return CURLE_CONV_FAILED;
131  }
132 #else
133  failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
134  return CURLE_CONV_REQD;
135 #endif /* HAVE_ICONV */
136  }
137 
138  return CURLE_OK;
139 }
140 
141 /*
142  * Curl_convert_from_network() is an internal function for performing ASCII
143  * conversions on non-ASCII platforms. It convers the buffer _in place_.
144  */
146  char *buffer, size_t length)
147 {
148  if(data && data->set.convfromnetwork) {
149  /* use translation callback */
150  CURLcode result = data->set.convfromnetwork(buffer, length);
151  if(result) {
152  failf(data,
153  "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
154  (int)result, curl_easy_strerror(result));
155  }
156 
157  return result;
158  }
159  else {
160 #ifdef HAVE_ICONV
161  /* do the translation ourselves */
162  iconv_t tmpcd = (iconv_t) -1;
163  iconv_t *cd = &tmpcd;
164  char *input_ptr, *output_ptr;
165  size_t in_bytes, out_bytes, rc;
166 
167  /* open an iconv conversion descriptor if necessary */
168  if(data)
169  cd = &data->inbound_cd;
170  if(*cd == (iconv_t)-1) {
171  *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
172  CURL_ICONV_CODESET_OF_NETWORK);
173  if(*cd == (iconv_t)-1) {
174  failf(data,
175  "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
177  CURL_ICONV_CODESET_OF_NETWORK,
178  errno, strerror(errno));
179  return CURLE_CONV_FAILED;
180  }
181  }
182  /* call iconv */
183  input_ptr = output_ptr = buffer;
184  in_bytes = out_bytes = length;
185  rc = iconv(*cd, &input_ptr, &in_bytes,
186  &output_ptr, &out_bytes);
187  if(!data)
188  iconv_close(tmpcd);
189  if((rc == ICONV_ERROR) || (in_bytes != 0)) {
190  failf(data,
191  "Curl_convert_from_network iconv call failed with errno %i: %s",
192  errno, strerror(errno));
193  return CURLE_CONV_FAILED;
194  }
195 #else
196  failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
197  return CURLE_CONV_REQD;
198 #endif /* HAVE_ICONV */
199  }
200 
201  return CURLE_OK;
202 }
203 
204 /*
205  * Curl_convert_from_utf8() is an internal function for performing UTF-8
206  * conversions on non-ASCII platforms.
207  */
209  char *buffer, size_t length)
210 {
211  if(data && data->set.convfromutf8) {
212  /* use translation callback */
213  CURLcode result = data->set.convfromutf8(buffer, length);
214  if(result) {
215  failf(data,
216  "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
217  (int)result, curl_easy_strerror(result));
218  }
219 
220  return result;
221  }
222  else {
223 #ifdef HAVE_ICONV
224  /* do the translation ourselves */
225  iconv_t tmpcd = (iconv_t) -1;
226  iconv_t *cd = &tmpcd;
227  char *input_ptr;
228  char *output_ptr;
229  size_t in_bytes, out_bytes, rc;
230 
231  /* open an iconv conversion descriptor if necessary */
232  if(data)
233  cd = &data->utf8_cd;
234  if(*cd == (iconv_t)-1) {
235  *cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
236  CURL_ICONV_CODESET_FOR_UTF8);
237  if(*cd == (iconv_t)-1) {
238  failf(data,
239  "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
241  CURL_ICONV_CODESET_FOR_UTF8,
242  errno, strerror(errno));
243  return CURLE_CONV_FAILED;
244  }
245  }
246  /* call iconv */
247  input_ptr = output_ptr = buffer;
248  in_bytes = out_bytes = length;
249  rc = iconv(*cd, &input_ptr, &in_bytes,
250  &output_ptr, &out_bytes);
251  if(!data)
252  iconv_close(tmpcd);
253  if((rc == ICONV_ERROR) || (in_bytes != 0)) {
254  failf(data,
255  "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
256  errno, strerror(errno));
257  return CURLE_CONV_FAILED;
258  }
259  if(output_ptr < input_ptr) {
260  /* null terminate the now shorter output string */
261  *output_ptr = 0x00;
262  }
263 #else
264  failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
265  return CURLE_CONV_REQD;
266 #endif /* HAVE_ICONV */
267  }
268 
269  return CURLE_OK;
270 }
271 
272 /*
273  * Init conversion stuff for a Curl_easy
274  */
275 void Curl_convert_init(struct Curl_easy *data)
276 {
277 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
278  /* conversion descriptors for iconv calls */
279  data->outbound_cd = (iconv_t)-1;
280  data->inbound_cd = (iconv_t)-1;
281  data->utf8_cd = (iconv_t)-1;
282 #else
283  (void)data;
284 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
285 }
286 
287 /*
288  * Setup conversion stuff for a Curl_easy
289  */
290 void Curl_convert_setup(struct Curl_easy *data)
291 {
292  data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
293  CURL_ICONV_CODESET_OF_NETWORK);
294  data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
296  data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
297  CURL_ICONV_CODESET_FOR_UTF8);
298 }
299 
300 /*
301  * Close conversion stuff for a Curl_easy
302  */
303 
304 void Curl_convert_close(struct Curl_easy *data)
305 {
306 #ifdef HAVE_ICONV
307  /* close iconv conversion descriptors */
308  if(data->inbound_cd != (iconv_t)-1) {
309  iconv_close(data->inbound_cd);
310  }
311  if(data->outbound_cd != (iconv_t)-1) {
312  iconv_close(data->outbound_cd);
313  }
314  if(data->utf8_cd != (iconv_t)-1) {
315  iconv_close(data->utf8_cd);
316  }
317 #else
318  (void)data;
319 #endif /* HAVE_ICONV */
320 }
321 
322 #endif /* CURL_DOES_CONVERSIONS */
#define free(ptr)
Definition: curl_memory.h:130
CURLcode Curl_convert_clone(struct Curl_easy *data, const char *indata, size_t insize, char **outbuf)
Definition: getpart.c:81
#define CURL_ICONV_CODESET_OF_HOST
Definition: config-tpf.h:771
struct UserDefined set
Definition: urldata.h:1762
#define failf
Definition: sendf.h:48
CURLcode
Definition: curl.h:454
curl_conv_callback convtonetwork
Definition: urldata.h:1541
#define malloc(size)
Definition: curl_memory.h:124
UNITTEST_START int result
Definition: unit1304.c:49
char buffer[]
Definition: unit1308.c:48
memcpy(filename, filename1, strlen(filename1))
static struct input indata[NUM_HANDLES]
Definition: http2-upload.c:183
UNITTEST_START int rc
Definition: unit1301.c:31
#define Curl_convert_from_network(a, b, c)
Definition: non-ascii.h:57
#define Curl_convert_to_network(a, b, c)
Definition: non-ascii.h:56
Definition: curl.h:455
curl_conv_callback convfromutf8
Definition: urldata.h:1543
#define Curl_convert_from_utf8(a, b, c)
Definition: non-ascii.h:58
#define Curl_convert_close(x)
Definition: non-ascii.h:55
CURL_EXTERN const char * curl_easy_strerror(CURLcode)
Definition: strerror.c:57
#define Curl_convert_init(x)
Definition: non-ascii.h:53
Definition: debug.c:29
curl_conv_callback convfromnetwork
Definition: urldata.h:1539
#define Curl_convert_setup(x)
Definition: non-ascii.h:54


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16