(root)/
glibc-2.38/
sunrpc/
xdr_array.c
       1  /*
       2   * xdr_array.c, Generic XDR routines implementation.
       3   *
       4   * Copyright (c) 2010, Oracle America, Inc.
       5   *
       6   * Redistribution and use in source and binary forms, with or without
       7   * modification, are permitted provided that the following conditions are
       8   * met:
       9   *
      10   *     * Redistributions of source code must retain the above copyright
      11   *       notice, this list of conditions and the following disclaimer.
      12   *     * Redistributions in binary form must reproduce the above
      13   *       copyright notice, this list of conditions and the following
      14   *       disclaimer in the documentation and/or other materials
      15   *       provided with the distribution.
      16   *     * Neither the name of the "Oracle America, Inc." nor the names of its
      17   *       contributors may be used to endorse or promote products derived
      18   *       from this software without specific prior written permission.
      19   *
      20   *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21   *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22   *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
      23   *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      24   *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
      25   *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26   *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
      27   *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      28   *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      29   *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      30   *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      31   *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      32   *
      33   * These are the "non-trivial" xdr primitives used to serialize and
      34   * de-serialize arrays.  See xdr.h for more info on the interface to xdr.
      35   */
      36  
      37  #include <stdio.h>
      38  #include <string.h>
      39  #include <rpc/types.h>
      40  #include <rpc/xdr.h>
      41  #include <libintl.h>
      42  #include <limits.h>
      43  #include <wchar.h>
      44  #include <shlib-compat.h>
      45  
      46  #define LASTUNSIGNED	((u_int)0-1)
      47  
      48  
      49  /*
      50   * XDR an array of arbitrary elements
      51   * *addrp is a pointer to the array, *sizep is the number of elements.
      52   * If addrp is NULL (*sizep * elsize) bytes are allocated.
      53   * elsize is the size (in bytes) of each element, and elproc is the
      54   * xdr procedure to call to handle each element of the array.
      55   */
      56  bool_t
      57  xdr_array (XDR *xdrs,
      58  	   /* array pointer */
      59  	   caddr_t *addrp,
      60  	   /* number of elements */
      61  	   u_int *sizep,
      62  	   /* max numberof elements */
      63  	   u_int maxsize,
      64  	   /* size in bytes of each element */
      65  	   u_int elsize,
      66  	   /* xdr routine to handle each element */
      67  	   xdrproc_t elproc)
      68  {
      69    u_int i;
      70    caddr_t target = *addrp;
      71    u_int c;		/* the actual element count */
      72    bool_t stat = TRUE;
      73  
      74    /* like strings, arrays are really counted arrays */
      75    if (!xdr_u_int (xdrs, sizep))
      76      {
      77        return FALSE;
      78      }
      79    c = *sizep;
      80    /*
      81     * XXX: Let the overflow possibly happen with XDR_FREE because mem_free()
      82     * doesn't actually use its second argument anyway.
      83     */
      84    if ((c > maxsize || c > UINT_MAX / elsize) && (xdrs->x_op != XDR_FREE))
      85      {
      86        return FALSE;
      87      }
      88  
      89    /*
      90     * if we are deserializing, we may need to allocate an array.
      91     * We also save time by checking for a null array if we are freeing.
      92     */
      93    if (target == NULL)
      94      switch (xdrs->x_op)
      95        {
      96        case XDR_DECODE:
      97  	if (c == 0)
      98  	  return TRUE;
      99  	*addrp = target = calloc (c, elsize);
     100  	if (target == NULL)
     101  	  {
     102  	    (void) __fxprintf (NULL, "%s: %s", __func__, _("out of memory\n"));
     103  	    return FALSE;
     104  	  }
     105  	break;
     106  
     107        case XDR_FREE:
     108  	return TRUE;
     109        default:
     110  	break;
     111        }
     112  
     113    /*
     114     * now we xdr each element of array
     115     */
     116    for (i = 0; (i < c) && stat; i++)
     117      {
     118        stat = (*elproc) (xdrs, target, LASTUNSIGNED);
     119        target += elsize;
     120      }
     121  
     122    /*
     123     * the array may need freeing
     124     */
     125    if (xdrs->x_op == XDR_FREE)
     126      {
     127        mem_free (*addrp, c * elsize);
     128        *addrp = NULL;
     129      }
     130    return stat;
     131  }
     132  #ifdef EXPORT_RPC_SYMBOLS
     133  libc_hidden_def (xdr_array)
     134  #else
     135  libc_hidden_nolink_sunrpc (xdr_array, GLIBC_2_0)
     136  #endif
     137  
     138  /*
     139   * xdr_vector():
     140   *
     141   * XDR a fixed length array. Unlike variable-length arrays,
     142   * the storage of fixed length arrays is static and unfreeable.
     143   * > basep: base of the array
     144   * > size: size of the array
     145   * > elemsize: size of each element
     146   * > xdr_elem: routine to XDR each element
     147   */
     148  bool_t
     149  xdr_vector (XDR *xdrs, char *basep, u_int nelem, u_int elemsize,
     150  	    xdrproc_t xdr_elem)
     151  {
     152    u_int i;
     153    char *elptr;
     154  
     155    elptr = basep;
     156    for (i = 0; i < nelem; i++)
     157      {
     158        if (!(*xdr_elem) (xdrs, elptr, LASTUNSIGNED))
     159  	{
     160  	  return FALSE;
     161  	}
     162        elptr += elemsize;
     163      }
     164    return TRUE;
     165  }
     166  libc_hidden_nolink_sunrpc (xdr_vector, GLIBC_2_0)