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 */
apr_wastrtoastr(char const * const ** retarr,wchar_t const * const * arr,int args)40 int 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