xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/misc/win32/internal.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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