1/* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "apr_private.h" 18 19#include "apr_arch_misc.h" 20#include "apr_arch_file_io.h" 21#include <assert.h> 22 23/* This module is the source of -static- helper functions that are 24 * entirely internal to apr. If the fn is exported - it does not 25 * belong here. 26 * 27 * Namespace decoration is still required to protect us from symbol 28 * clashes in static linkages. 29 */ 30 31 32/* Shared by apr_app.c and start.c 33 * 34 * An internal apr function to convert an array of strings (either 35 * a counted or NULL terminated list, such as an argv[argc] or env[] 36 * list respectively) from wide Unicode strings to narrow utf-8 strings. 37 * These are allocated from the MSVCRT's _CRT_BLOCK to trick the system 38 * into trusting our store. 39 */ 40int apr_wastrtoastr(char const * const * *retarr, 41 wchar_t const * const *arr, int args) 42{ 43 apr_size_t elesize = 0; 44 char **newarr; 45 char *elements; 46 char *ele; 47 int arg; 48 49 if (args < 0) { 50 for (args = 0; arr[args]; ++args) 51 ; 52 } 53 54 newarr = apr_malloc_dbg((args + 1) * sizeof(char *), 55 __FILE__, __LINE__); 56 57 for (arg = 0; arg < args; ++arg) { 58 newarr[arg] = (void*)(wcslen(arr[arg]) + 1); 59 elesize += (apr_size_t)newarr[arg]; 60 } 61 62 /* This is a safe max allocation, we will realloc after 63 * processing and return the excess to the free store. 64 * 3 ucs bytes hold any single wchar_t value (16 bits) 65 * 4 ucs bytes will hold a wchar_t pair value (20 bits) 66 */ 67 elesize = elesize * 3 + 1; 68 ele = elements = apr_malloc_dbg(elesize * sizeof(char), 69 __FILE__, __LINE__); 70 71 for (arg = 0; arg < args; ++arg) { 72 apr_size_t len = (apr_size_t)newarr[arg]; 73 apr_size_t newlen = elesize; 74 75 newarr[arg] = ele; 76 (void)apr_conv_ucs2_to_utf8(arr[arg], &len, 77 newarr[arg], &elesize); 78 79 newlen -= elesize; 80 ele += newlen; 81 assert(elesize && (len == 0)); 82 } 83 84 newarr[arg] = NULL; 85 *(ele++) = '\0'; 86 87 /* Return to the free store if the heap realloc is the least bit optimized 88 */ 89 ele = apr_realloc_dbg(elements, ele - elements, 90 __FILE__, __LINE__); 91 92 if (ele != elements) { 93 apr_size_t diff = ele - elements; 94 for (arg = 0; arg < args; ++arg) { 95 newarr[arg] += diff; 96 } 97 } 98 99 *retarr = (char const * const *)newarr; 100 return args; 101} 102