1 /* Copyright (c) 2010, 2021, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
24 @file windeps/sunrpc/xdr_array.c
25 Generic XDR routines implementation.
26 These are the "non-trivial" xdr primitives used to serialize and
27 de-serialize arrays. See xdr.h for more info on the interface to xdr.
28 */
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <rpc/types.h>
33 #include <rpc/xdr.h>
34 #include <libintl.h>
35 #include <limits.h>
36
37 #ifdef USE_IN_LIBIO
38 # include <wchar.h>
39 #endif
40
41 #define LASTUNSIGNED ((u_int)0-1)
42
43
44 /*
45 * XDR an array of arbitrary elements
46 * *addrp is a pointer to the array, *sizep is the number of elements.
47 * If addrp is NULL (*sizep * elsize) bytes are allocated.
48 * elsize is the size (in bytes) of each element, and elproc is the
49 * xdr procedure to call to handle each element of the array.
50 */
51 bool_t
xdr_array(xdrs,addrp,sizep,maxsize,elsize,elproc)52 xdr_array (xdrs, addrp, sizep, maxsize, elsize, elproc)
53 XDR *xdrs;
54 caddr_t *addrp; /* array pointer */
55 u_int *sizep; /* number of elements */
56 u_int maxsize; /* max numberof elements */
57 u_int elsize; /* size in bytes of each element */
58 xdrproc_t elproc; /* xdr routine to handle each element */
59 {
60 u_int i;
61 caddr_t target = *addrp;
62 u_int c; /* the actual element count */
63 bool_t stat = TRUE;
64
65 /* like strings, arrays are really counted arrays */
66 if (!INTUSE(xdr_u_int) (xdrs, sizep))
67 {
68 return FALSE;
69 }
70 c = *sizep;
71 /*
72 * XXX: Let the overflow possibly happen with XDR_FREE because mem_free()
73 * doesn't actually use its second argument anyway.
74 */
75 if ((c > maxsize || c > UINT_MAX / elsize) && (xdrs->x_op != XDR_FREE))
76 {
77 return FALSE;
78 }
79
80 /*
81 * if we are deserializing, we may need to allocate an array.
82 * We also save time by checking for a null array if we are freeing.
83 */
84 if (target == NULL)
85 switch (xdrs->x_op)
86 {
87 case XDR_DECODE:
88 if (c == 0)
89 return TRUE;
90 *addrp = target = calloc (c, elsize);
91 if (target == NULL)
92 {
93 (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
94 return FALSE;
95 }
96 break;
97
98 case XDR_FREE:
99 return TRUE;
100 default:
101 break;
102 }
103
104 /*
105 * now we xdr each element of array
106 */
107 for (i = 0; (i < c) && stat; i++)
108 {
109 stat = (*elproc) (xdrs, target, LASTUNSIGNED);
110 target += elsize;
111 }
112
113 /*
114 * the array may need freeing
115 */
116 if (xdrs->x_op == XDR_FREE)
117 {
118 mem_free (*addrp, c * elsize);
119 *addrp = NULL;
120 }
121 return stat;
122 }
123 INTDEF(xdr_array)
124
125 /*
126 * xdr_vector():
127 *
128 * XDR a fixed length array. Unlike variable-length arrays,
129 * the storage of fixed length arrays is static and unfreeable.
130 * > basep: base of the array
131 * > size: size of the array
132 * > elemsize: size of each element
133 * > xdr_elem: routine to XDR each element
134 */
135 bool_t
136 xdr_vector (xdrs, basep, nelem, elemsize, xdr_elem)
137 XDR *xdrs;
138 char *basep;
139 u_int nelem;
140 u_int elemsize;
141 xdrproc_t xdr_elem;
142 {
143 u_int i;
144 char *elptr;
145
146 elptr = basep;
147 for (i = 0; i < nelem; i++)
148 {
149 if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED))
150 {
151 return FALSE;
152 }
153 elptr += elemsize;
154 }
155 return TRUE;
156 }
157