Пример #1
0
/*
 * The method tables passed to construction do not contain "intrinsic" methods
 * such as service discovery and shutdown.  Build a complete table including
 * those from a given input.
 */
static NaClSrpcMethodDesc* BuildMethods(
    const struct NaClSrpcHandlerDesc* methods,
    uint32_t* method_count) {
  static const char* kSDDescString = "service_discovery::C";
  NaClSrpcMethodDesc* complete_methods = NULL;
  uint32_t i;
  const char* nul_loc;

  /* Compute the number of methods to export. */
  *method_count = 0;
  while (NULL != methods[*method_count].entry_fmt)
    ++*method_count;
  /* Add one extra method for service discovery. */
  ++*method_count;
  /* Allocate the method descriptors. One extra for NULL termination. */
  complete_methods = (NaClSrpcMethodDesc*)
      calloc(*method_count + 1, sizeof(*complete_methods));
  if (NULL == complete_methods) {
    return NULL;
  }
  /* Copy the methods passed in, adding service discovery as element zero. */
  nul_loc = ParseOneEntry(kSDDescString,
                          (char**) &complete_methods[0].name,
                          (char**) &complete_methods[0].input_types,
                          (char**) &complete_methods[0].output_types);
  if (nul_loc == NULL) {
    goto cleanup;
  }
  complete_methods[0].handler = ServiceDiscovery;
  for (i = 0; i < *method_count - 1; ++i) {
    nul_loc = ParseOneEntry(methods[i].entry_fmt,
                            (char**) &complete_methods[i + 1].name,
                            (char**) &complete_methods[i + 1].input_types,
                            (char**) &complete_methods[i + 1].output_types);
    if (nul_loc == NULL) {
      goto cleanup;
    }
    complete_methods[i + 1].handler = methods[i].handler;
  }
  /* Add the NULL terminator */
  complete_methods[*method_count].name = NULL;
  complete_methods[*method_count].input_types = NULL;
  complete_methods[*method_count].output_types = NULL;
  complete_methods[*method_count].handler = NULL;
  /* Return the array */
  return complete_methods;

 cleanup:
  FreeMethods(complete_methods, *method_count);
  return NULL;
}
Пример #2
0
int NaClSrpcServiceStringCtor(NaClSrpcService* service, const char* str) {
  NaClSrpcMethodDesc* methods = NULL;
  const char* p;
  uint32_t i;
  uint32_t rpc_count;
  size_t rpc_count_size_t;

  /* Count the number of rpc methods */
  rpc_count = 0;
  for (p = str; *p != '\0'; ) {
    char* next_p = strchr(p, '\n');
    if (NULL == next_p) {
      /* malformed input -- no remaining \n character was found */
      goto cleanup;
    }
    p = next_p + 1;
    ++rpc_count;
    if (0 == rpc_count) {
      /* uint32_t overflow detected. */
      goto cleanup;
    }
  }
  /*
   * The front end knows the next comparison is useless due to the range of
   * uint32_t.  And furthermore at least one version of gcc knows that a
   * cast doesn't really change that fact.  Hence, assign to a new variable
   * of size_t type.
   */
  rpc_count_size_t = (size_t) rpc_count;
  /* Allocate and clear the descriptor array */
  if (rpc_count_size_t >= SIZE_T_MAX / sizeof(*methods)) {
    goto cleanup;
  }
  methods = (NaClSrpcMethodDesc*) malloc(rpc_count_size_t * sizeof(*methods));
  if (NULL == methods) {
    goto cleanup;
  }
  memset(methods, 0, rpc_count_size_t * sizeof(*methods));
  /* Parse the list of method descriptions */
  p = str;
  for (i = 0; i < rpc_count; ++i) {
    const char* newline_loc;

    newline_loc = ParseOneEntry(p,
                                (char**) &methods[i].name,
                                (char**) &methods[i].input_types,
                                (char**) &methods[i].output_types);
    if (NULL == newline_loc || '\n' != *newline_loc) {
      goto cleanup;
    }
    p = newline_loc + 1;
    /* The handler is not set from service_discovery strings */
    methods[i].handler = NULL;
  }
  service->service_string = strdup(str);
  service->service_string_length = nacl_abi_size_t_saturate(strlen(str));
  service->rpc_descr = methods;
  service->rpc_count = rpc_count;
  return 1;

 cleanup:
  FreeMethods(methods, rpc_count);
  return 0;
}