/*
 * Adds IOV entries for the non-fixed portions of the arguments in vec.
 * This could also add handles/descriptors to the array to send.
 */
static BoolValue AddNonfixedForWrite(NaClSrpcArg** vec,
                                     size_t vec_len,
                                     size_t max_iov_len,
                                     struct NaClImcMsgIoVec* iov,
                                     size_t* iov_len,
                                     NaClSrpcImcDescType* descs,
                                     size_t* desc_len,
                                     size_t* expected_bytes) {
  size_t i;
  size_t element_size;
  nacl_abi_size_t count;
  void* base;

  /* Add IOV entries for the array/string types in vec. */
  for (i = 0; i < vec_len; ++i) {
    switch (vec[i]->tag) {
      case NACL_SRPC_ARG_TYPE_BOOL:
      case NACL_SRPC_ARG_TYPE_DOUBLE:
      case NACL_SRPC_ARG_TYPE_INT:
      case NACL_SRPC_ARG_TYPE_INVALID:
      case NACL_SRPC_ARG_TYPE_LONG:
      case NACL_SRPC_ARG_TYPE_OBJECT:
      case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY:
       /* Scalar types are handled by fixed iovs alone. */
       break;

      case NACL_SRPC_ARG_TYPE_HANDLE:
        /* Handles are added into the desc array. */
        descs[*desc_len] = vec[i]->u.hval;
        ++*desc_len;
        break;

      case NACL_SRPC_ARG_TYPE_CHAR_ARRAY:
      case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY:
      case NACL_SRPC_ARG_TYPE_INT_ARRAY:
      case NACL_SRPC_ARG_TYPE_LONG_ARRAY:
        count = vec[i]->u.count;
        base = vec[i]->arrays.oval;
        element_size = ArrayElementSize(vec[i]);
        /* Check that computing the number of bytes will not overflow. */
        if (SIZE_T_MAX / element_size < count) {
          return BoolFalse;
        }
        AddIovEntry(base, element_size * count, max_iov_len, iov, iov_len,
                    expected_bytes);
        break;

      case NACL_SRPC_ARG_TYPE_STRING:
        count = (nacl_abi_size_t) strlen(vec[i]->arrays.str) + 1;
        base = vec[i]->arrays.oval;
        vec[i]->u.count = count;
        AddIovEntry(base, count, max_iov_len, iov, iov_len, expected_bytes);
        break;
    }
  }
  return BoolTrue;
}
Example #2
0
unsigned int ArrayHash(void *arr1) {
  char *arr = arr1;
  int i,len = ArrayElementSize(arr1) * ArrayLength(arr1);
  unsigned int hash = 5381;
  int c;

  for (i=0;i<len;i++) {
    c = arr[i];
    hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
  }
  return hash;
}
/*
 * Adds the IOV entries for the nonfixed portions of an argument vector to
 * read.  For receiving requests we need to allocate memory for the nonfixed
 * portions of both the inputs and results, but we do not read the results
 * vector's nonfixed portion.  For receiving responses we do not allocate
 * memory for the nonfixed portion (the caller has already done that), but we
 * read the nonfixed portion of results.
 * If it returns BoolFalse, some memory may have been allocated.  It is the
 * caller's responsibility to clean up in that case.
 */
static BoolValue AddNonfixedForRead(NaClSrpcArg** vec,
                                    size_t vec_len,
                                    size_t max_iov_len,
                                    BoolValue alloc_value,
                                    BoolValue read_value,
                                    struct NaClImcMsgIoVec* iov,
                                    size_t* iov_len,
                                    size_t* expected_bytes) {
  size_t i;

  /* Initialize the array pointers to allow cleanup if errors happen. */
  if (alloc_value) {
    for (i = 0; i < vec_len; ++i) {
      vec[i]->arrays.oval = NULL;
    }
  }

  for (i = 0; i < vec_len; ++i) {
    size_t count = vec[i]->u.count;
    void* base = 0;
    size_t element_size = ArrayElementSize(vec[i]);

    if (element_size == 0) {
      /* Skip fixed size arguments. */
      continue;
    }
    if (SIZE_T_MAX / element_size < count) {
      return BoolFalse;
    }
    base = vec[i]->arrays.oval;
    if (alloc_value) {
      base = malloc(element_size * count);
      if (base == 0) {
        return BoolFalse;
      }
      vec[i]->arrays.oval = base;
    }
    if (read_value) {
      AddIovEntry(base, element_size * count, max_iov_len, iov, iov_len,
                  expected_bytes);
    }
  }
  return BoolTrue;
}
Example #4
0
int WriteArray(Stream *st,void *arr) {
  return st->Write(st,arr,ArrayLength(arr)*ArrayElementSize(arr));
}