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