1 | /*************************************************************************** |
2 | * _ _ ____ _ |
3 | * Project ___| | | | _ \| | |
4 | * / __| | | | |_) | | |
5 | * | (__| |_| | _ <| |___ |
6 | * \___|\___/|_| \_\_____| |
7 | * |
8 | * Copyright (C) 1998 - 2019, 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 | #include "tool_setup.h" |
23 | |
24 | #ifdef CURL_DOES_CONVERSIONS |
25 | |
26 | #ifdef HAVE_ICONV |
27 | # include <iconv.h> |
28 | #endif |
29 | |
30 | #include "tool_convert.h" |
31 | |
32 | #include "memdebug.h" /* keep this as LAST include */ |
33 | |
34 | #ifdef HAVE_ICONV |
35 | |
36 | /* curl tool iconv conversion descriptors */ |
37 | static iconv_t inbound_cd = (iconv_t)-1; |
38 | static iconv_t outbound_cd = (iconv_t)-1; |
39 | |
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 | |
45 | /* |
46 | * convert_to_network() is a curl tool function to convert |
47 | * from the host encoding to ASCII on non-ASCII platforms. |
48 | */ |
49 | CURLcode convert_to_network(char *buffer, size_t length) |
50 | { |
51 | /* translate from the host encoding to the network encoding */ |
52 | char *input_ptr, *output_ptr; |
53 | size_t res, in_bytes, out_bytes; |
54 | |
55 | /* open an iconv conversion descriptor if necessary */ |
56 | if(outbound_cd == (iconv_t)-1) { |
57 | outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, |
58 | CURL_ICONV_CODESET_OF_HOST); |
59 | if(outbound_cd == (iconv_t)-1) { |
60 | return CURLE_CONV_FAILED; |
61 | } |
62 | } |
63 | /* call iconv */ |
64 | input_ptr = output_ptr = buffer; |
65 | in_bytes = out_bytes = length; |
66 | res = iconv(outbound_cd, &input_ptr, &in_bytes, |
67 | &output_ptr, &out_bytes); |
68 | if((res == (size_t)-1) || (in_bytes != 0)) { |
69 | return CURLE_CONV_FAILED; |
70 | } |
71 | |
72 | return CURLE_OK; |
73 | } |
74 | |
75 | /* |
76 | * convert_from_network() is a curl tool function |
77 | * for performing ASCII conversions on non-ASCII platforms. |
78 | */ |
79 | CURLcode convert_from_network(char *buffer, size_t length) |
80 | { |
81 | /* translate from the network encoding to the host encoding */ |
82 | char *input_ptr, *output_ptr; |
83 | size_t res, in_bytes, out_bytes; |
84 | |
85 | /* open an iconv conversion descriptor if necessary */ |
86 | if(inbound_cd == (iconv_t)-1) { |
87 | inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, |
88 | CURL_ICONV_CODESET_OF_NETWORK); |
89 | if(inbound_cd == (iconv_t)-1) { |
90 | return CURLE_CONV_FAILED; |
91 | } |
92 | } |
93 | /* call iconv */ |
94 | input_ptr = output_ptr = buffer; |
95 | in_bytes = out_bytes = length; |
96 | res = iconv(inbound_cd, &input_ptr, &in_bytes, |
97 | &output_ptr, &out_bytes); |
98 | if((res == (size_t)-1) || (in_bytes != 0)) { |
99 | return CURLE_CONV_FAILED; |
100 | } |
101 | |
102 | return CURLE_OK; |
103 | } |
104 | |
105 | void convert_cleanup(void) |
106 | { |
107 | /* close iconv conversion descriptors */ |
108 | if(inbound_cd != (iconv_t)-1) |
109 | (void)iconv_close(inbound_cd); |
110 | if(outbound_cd != (iconv_t)-1) |
111 | (void)iconv_close(outbound_cd); |
112 | } |
113 | |
114 | #endif /* HAVE_ICONV */ |
115 | |
116 | char convert_char(curl_infotype infotype, char this_char) |
117 | { |
118 | /* determine how this specific character should be displayed */ |
119 | switch(infotype) { |
120 | case CURLINFO_DATA_IN: |
121 | case CURLINFO_DATA_OUT: |
122 | case CURLINFO_SSL_DATA_IN: |
123 | case CURLINFO_SSL_DATA_OUT: |
124 | /* data, treat as ASCII */ |
125 | if(this_char < 0x20 || this_char >= 0x7f) { |
126 | /* non-printable ASCII, use a replacement character */ |
127 | return UNPRINTABLE_CHAR; |
128 | } |
129 | /* printable ASCII hex value: convert to host encoding */ |
130 | (void)convert_from_network(&this_char, 1); |
131 | /* FALLTHROUGH */ |
132 | default: |
133 | /* treat as host encoding */ |
134 | if(ISPRINT(this_char) |
135 | && (this_char != '\t') |
136 | && (this_char != '\r') |
137 | && (this_char != '\n')) { |
138 | /* printable characters excluding tabs and line end characters */ |
139 | return this_char; |
140 | } |
141 | break; |
142 | } |
143 | /* non-printable, use a replacement character */ |
144 | return UNPRINTABLE_CHAR; |
145 | } |
146 | |
147 | #endif /* CURL_DOES_CONVERSIONS */ |
148 | |