non-ascii.c
Go to the documentation of this file.
00001 /***************************************************************************
00002  *                                  _   _ ____  _
00003  *  Project                     ___| | | |  _ \| |
00004  *                             / __| | | | |_) | |
00005  *                            | (__| |_| |  _ <| |___
00006  *                             \___|\___/|_| \_\_____|
00007  *
00008  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
00009  *
00010  * This software is licensed as described in the file COPYING, which
00011  * you should have received as part of this distribution. The terms
00012  * are also available at https://curl.haxx.se/docs/copyright.html.
00013  *
00014  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
00015  * copies of the Software, and permit persons to whom the Software is
00016  * furnished to do so, under the terms of the COPYING file.
00017  *
00018  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
00019  * KIND, either express or implied.
00020  *
00021  ***************************************************************************/
00022 
00023 #include "curl_setup.h"
00024 
00025 #ifdef CURL_DOES_CONVERSIONS
00026 
00027 #include <curl/curl.h>
00028 
00029 #include "non-ascii.h"
00030 #include "formdata.h"
00031 #include "sendf.h"
00032 #include "urldata.h"
00033 
00034 #include "curl_memory.h"
00035 /* The last #include file should be: */
00036 #include "memdebug.h"
00037 
00038 #ifdef HAVE_ICONV
00039 #include <iconv.h>
00040 /* set default codesets for iconv */
00041 #ifndef CURL_ICONV_CODESET_OF_NETWORK
00042 #define CURL_ICONV_CODESET_OF_NETWORK "ISO8859-1"
00043 #endif
00044 #ifndef CURL_ICONV_CODESET_FOR_UTF8
00045 #define CURL_ICONV_CODESET_FOR_UTF8   "UTF-8"
00046 #endif
00047 #define ICONV_ERROR  (size_t)-1
00048 #endif /* HAVE_ICONV */
00049 
00050 /*
00051  * Curl_convert_clone() returns a malloced copy of the source string (if
00052  * returning CURLE_OK), with the data converted to network format.
00053  */
00054 CURLcode Curl_convert_clone(struct Curl_easy *data,
00055                            const char *indata,
00056                            size_t insize,
00057                            char **outbuf)
00058 {
00059   char *convbuf;
00060   CURLcode result;
00061 
00062   convbuf = malloc(insize);
00063   if(!convbuf)
00064     return CURLE_OUT_OF_MEMORY;
00065 
00066   memcpy(convbuf, indata, insize);
00067   result = Curl_convert_to_network(data, convbuf, insize);
00068   if(result) {
00069     free(convbuf);
00070     return result;
00071   }
00072 
00073   *outbuf = convbuf; /* return the converted buffer */
00074 
00075   return CURLE_OK;
00076 }
00077 
00078 /*
00079  * Curl_convert_to_network() is an internal function for performing ASCII
00080  * conversions on non-ASCII platforms. It convers the buffer _in place_.
00081  */
00082 CURLcode Curl_convert_to_network(struct Curl_easy *data,
00083                                  char *buffer, size_t length)
00084 {
00085   if(data->set.convtonetwork) {
00086     /* use translation callback */
00087     CURLcode result = data->set.convtonetwork(buffer, length);
00088     if(result) {
00089       failf(data,
00090             "CURLOPT_CONV_TO_NETWORK_FUNCTION callback returned %d: %s",
00091             (int)result, curl_easy_strerror(result));
00092     }
00093 
00094     return result;
00095   }
00096   else {
00097 #ifdef HAVE_ICONV
00098     /* do the translation ourselves */
00099     char *input_ptr, *output_ptr;
00100     size_t in_bytes, out_bytes, rc;
00101     int error;
00102 
00103     /* open an iconv conversion descriptor if necessary */
00104     if(data->outbound_cd == (iconv_t)-1) {
00105       data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
00106                                      CURL_ICONV_CODESET_OF_HOST);
00107       if(data->outbound_cd == (iconv_t)-1) {
00108         error = ERRNO;
00109         failf(data,
00110               "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
00111               CURL_ICONV_CODESET_OF_NETWORK,
00112               CURL_ICONV_CODESET_OF_HOST,
00113               error, strerror(error));
00114         return CURLE_CONV_FAILED;
00115       }
00116     }
00117     /* call iconv */
00118     input_ptr = output_ptr = buffer;
00119     in_bytes = out_bytes = length;
00120     rc = iconv(data->outbound_cd, (const char **)&input_ptr, &in_bytes,
00121                &output_ptr, &out_bytes);
00122     if((rc == ICONV_ERROR) || (in_bytes != 0)) {
00123       error = ERRNO;
00124       failf(data,
00125             "The Curl_convert_to_network iconv call failed with errno %i: %s",
00126             error, strerror(error));
00127       return CURLE_CONV_FAILED;
00128     }
00129 #else
00130     failf(data, "CURLOPT_CONV_TO_NETWORK_FUNCTION callback required");
00131     return CURLE_CONV_REQD;
00132 #endif /* HAVE_ICONV */
00133   }
00134 
00135   return CURLE_OK;
00136 }
00137 
00138 /*
00139  * Curl_convert_from_network() is an internal function for performing ASCII
00140  * conversions on non-ASCII platforms. It convers the buffer _in place_.
00141  */
00142 CURLcode Curl_convert_from_network(struct Curl_easy *data,
00143                                    char *buffer, size_t length)
00144 {
00145   if(data->set.convfromnetwork) {
00146     /* use translation callback */
00147     CURLcode result = data->set.convfromnetwork(buffer, length);
00148     if(result) {
00149       failf(data,
00150             "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback returned %d: %s",
00151             (int)result, curl_easy_strerror(result));
00152     }
00153 
00154     return result;
00155   }
00156   else {
00157 #ifdef HAVE_ICONV
00158     /* do the translation ourselves */
00159     char *input_ptr, *output_ptr;
00160     size_t in_bytes, out_bytes, rc;
00161     int error;
00162 
00163     /* open an iconv conversion descriptor if necessary */
00164     if(data->inbound_cd == (iconv_t)-1) {
00165       data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00166                                     CURL_ICONV_CODESET_OF_NETWORK);
00167       if(data->inbound_cd == (iconv_t)-1) {
00168         error = ERRNO;
00169         failf(data,
00170               "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
00171               CURL_ICONV_CODESET_OF_HOST,
00172               CURL_ICONV_CODESET_OF_NETWORK,
00173               error, strerror(error));
00174         return CURLE_CONV_FAILED;
00175       }
00176     }
00177     /* call iconv */
00178     input_ptr = output_ptr = buffer;
00179     in_bytes = out_bytes = length;
00180     rc = iconv(data->inbound_cd, (const char **)&input_ptr, &in_bytes,
00181                &output_ptr, &out_bytes);
00182     if((rc == ICONV_ERROR) || (in_bytes != 0)) {
00183       error = ERRNO;
00184       failf(data,
00185             "Curl_convert_from_network iconv call failed with errno %i: %s",
00186             error, strerror(error));
00187       return CURLE_CONV_FAILED;
00188     }
00189 #else
00190     failf(data, "CURLOPT_CONV_FROM_NETWORK_FUNCTION callback required");
00191     return CURLE_CONV_REQD;
00192 #endif /* HAVE_ICONV */
00193   }
00194 
00195   return CURLE_OK;
00196 }
00197 
00198 /*
00199  * Curl_convert_from_utf8() is an internal function for performing UTF-8
00200  * conversions on non-ASCII platforms.
00201  */
00202 CURLcode Curl_convert_from_utf8(struct Curl_easy *data,
00203                                 char *buffer, size_t length)
00204 {
00205   if(data->set.convfromutf8) {
00206     /* use translation callback */
00207     CURLcode result = data->set.convfromutf8(buffer, length);
00208     if(result) {
00209       failf(data,
00210             "CURLOPT_CONV_FROM_UTF8_FUNCTION callback returned %d: %s",
00211             (int)result, curl_easy_strerror(result));
00212     }
00213 
00214     return result;
00215   }
00216   else {
00217 #ifdef HAVE_ICONV
00218     /* do the translation ourselves */
00219     const char *input_ptr;
00220     char *output_ptr;
00221     size_t in_bytes, out_bytes, rc;
00222     int error;
00223 
00224     /* open an iconv conversion descriptor if necessary */
00225     if(data->utf8_cd == (iconv_t)-1) {
00226       data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00227                                  CURL_ICONV_CODESET_FOR_UTF8);
00228       if(data->utf8_cd == (iconv_t)-1) {
00229         error = ERRNO;
00230         failf(data,
00231               "The iconv_open(\"%s\", \"%s\") call failed with errno %i: %s",
00232               CURL_ICONV_CODESET_OF_HOST,
00233               CURL_ICONV_CODESET_FOR_UTF8,
00234               error, strerror(error));
00235         return CURLE_CONV_FAILED;
00236       }
00237     }
00238     /* call iconv */
00239     input_ptr = output_ptr = buffer;
00240     in_bytes = out_bytes = length;
00241     rc = iconv(data->utf8_cd, &input_ptr, &in_bytes,
00242                &output_ptr, &out_bytes);
00243     if((rc == ICONV_ERROR) || (in_bytes != 0)) {
00244       error = ERRNO;
00245       failf(data,
00246             "The Curl_convert_from_utf8 iconv call failed with errno %i: %s",
00247             error, strerror(error));
00248       return CURLE_CONV_FAILED;
00249     }
00250     if(output_ptr < input_ptr) {
00251       /* null terminate the now shorter output string */
00252       *output_ptr = 0x00;
00253     }
00254 #else
00255     failf(data, "CURLOPT_CONV_FROM_UTF8_FUNCTION callback required");
00256     return CURLE_CONV_REQD;
00257 #endif /* HAVE_ICONV */
00258   }
00259 
00260   return CURLE_OK;
00261 }
00262 
00263 /*
00264  * Init conversion stuff for a Curl_easy
00265  */
00266 void Curl_convert_init(struct Curl_easy *data)
00267 {
00268 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
00269   /* conversion descriptors for iconv calls */
00270   data->outbound_cd = (iconv_t)-1;
00271   data->inbound_cd  = (iconv_t)-1;
00272   data->utf8_cd     = (iconv_t)-1;
00273 #else
00274   (void)data;
00275 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
00276 }
00277 
00278 /*
00279  * Setup conversion stuff for a Curl_easy
00280  */
00281 void Curl_convert_setup(struct Curl_easy *data)
00282 {
00283   data->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00284                                 CURL_ICONV_CODESET_OF_NETWORK);
00285   data->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK,
00286                                  CURL_ICONV_CODESET_OF_HOST);
00287   data->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST,
00288                              CURL_ICONV_CODESET_FOR_UTF8);
00289 }
00290 
00291 /*
00292  * Close conversion stuff for a Curl_easy
00293  */
00294 
00295 void Curl_convert_close(struct Curl_easy *data)
00296 {
00297 #ifdef HAVE_ICONV
00298   /* close iconv conversion descriptors */
00299   if(data->inbound_cd != (iconv_t)-1) {
00300     iconv_close(data->inbound_cd);
00301   }
00302   if(data->outbound_cd != (iconv_t)-1) {
00303     iconv_close(data->outbound_cd);
00304   }
00305   if(data->utf8_cd != (iconv_t)-1) {
00306     iconv_close(data->utf8_cd);
00307   }
00308 #else
00309   (void)data;
00310 #endif /* HAVE_ICONV */
00311 }
00312 
00313 /*
00314  * Curl_convert_form() is used from http.c, this converts any form items that
00315    need to be sent in the network encoding.  Returns CURLE_OK on success.
00316  */
00317 CURLcode Curl_convert_form(struct Curl_easy *data, struct FormData *form)
00318 {
00319   CURLcode result;
00320 
00321   if(!data)
00322     return CURLE_BAD_FUNCTION_ARGUMENT;
00323 
00324   while(form) {
00325     if(form->type == FORM_DATA) {
00326       result = Curl_convert_to_network(data, form->line, form->length);
00327       /* Curl_convert_to_network calls failf if unsuccessful */
00328       if(result)
00329         return result;
00330     }
00331 
00332     form = form->next;
00333   }
00334 
00335   return CURLE_OK;
00336 }
00337 
00338 #endif /* CURL_DOES_CONVERSIONS */


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:05