|  | @@ -90,7 +90,7 @@ static void *method_parameters_create_from_json(const grpc_json *json) {
 | 
	
		
			
				|  |  |    gpr_timespec timeout = {0, 0, GPR_TIMESPAN};
 | 
	
		
			
				|  |  |    for (grpc_json *field = json->child; field != NULL; field = field->next) {
 | 
	
		
			
				|  |  |      if (field->key == NULL) continue;
 | 
	
		
			
				|  |  | -    if (strcmp(field->key, "wait_for_ready") == 0) {
 | 
	
		
			
				|  |  | +    if (strcmp(field->key, "waitForReady") == 0) {
 | 
	
		
			
				|  |  |        if (wait_for_ready != WAIT_FOR_READY_UNSET) return NULL;  // Duplicate.
 | 
	
		
			
				|  |  |        if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
 | 
	
		
			
				|  |  |          return NULL;
 | 
	
	
		
			
				|  | @@ -99,26 +99,39 @@ static void *method_parameters_create_from_json(const grpc_json *json) {
 | 
	
		
			
				|  |  |                                                       : WAIT_FOR_READY_FALSE;
 | 
	
		
			
				|  |  |      } else if (strcmp(field->key, "timeout") == 0) {
 | 
	
		
			
				|  |  |        if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) return NULL;  // Duplicate.
 | 
	
		
			
				|  |  | -      if (field->type != GRPC_JSON_OBJECT) return NULL;
 | 
	
		
			
				|  |  | -      if (field->child == NULL) return NULL;
 | 
	
		
			
				|  |  | -      for (grpc_json *subfield = field->child; subfield != NULL;
 | 
	
		
			
				|  |  | -           subfield = subfield->next) {
 | 
	
		
			
				|  |  | -        if (subfield->key == NULL) return NULL;
 | 
	
		
			
				|  |  | -        if (strcmp(subfield->key, "seconds") == 0) {
 | 
	
		
			
				|  |  | -          if (timeout.tv_sec > 0) return NULL;  // Duplicate.
 | 
	
		
			
				|  |  | -          if (subfield->type != GRPC_JSON_NUMBER) return NULL;
 | 
	
		
			
				|  |  | -          timeout.tv_sec = gpr_parse_nonnegative_number(subfield->value);
 | 
	
		
			
				|  |  | -          if (timeout.tv_sec == -1) return NULL;
 | 
	
		
			
				|  |  | -        } else if (strcmp(subfield->key, "nanos") == 0) {
 | 
	
		
			
				|  |  | -          if (timeout.tv_nsec > 0) return NULL;  // Duplicate.
 | 
	
		
			
				|  |  | -          if (subfield->type != GRPC_JSON_NUMBER) return NULL;
 | 
	
		
			
				|  |  | -          timeout.tv_nsec = gpr_parse_nonnegative_number(subfield->value);
 | 
	
		
			
				|  |  | -          if (timeout.tv_nsec == -1) return NULL;
 | 
	
		
			
				|  |  | -        } else {
 | 
	
		
			
				|  |  | -          // Unknown key.
 | 
	
		
			
				|  |  | +      if (field->type != GRPC_JSON_STRING) return NULL;
 | 
	
		
			
				|  |  | +      size_t len = strlen(field->value);
 | 
	
		
			
				|  |  | +      if (field->value[len - 1] != 's') return NULL;
 | 
	
		
			
				|  |  | +      char* buf = gpr_strdup(field->value);
 | 
	
		
			
				|  |  | +      buf[len - 1] = '\0';  // Remove trailing 's'.
 | 
	
		
			
				|  |  | +      char* decimal_point = strchr(buf, '.');
 | 
	
		
			
				|  |  | +      if (decimal_point != NULL) {
 | 
	
		
			
				|  |  | +        *decimal_point = '\0';
 | 
	
		
			
				|  |  | +        timeout.tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1);
 | 
	
		
			
				|  |  | +        if (timeout.tv_nsec == -1) {
 | 
	
		
			
				|  |  | +          gpr_free(buf);
 | 
	
		
			
				|  |  |            return NULL;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        // There should always be exactly 3, 6, or 9 fractional digits.
 | 
	
		
			
				|  |  | +        int multiplier = 1;
 | 
	
		
			
				|  |  | +        switch (strlen(decimal_point + 1)) {
 | 
	
		
			
				|  |  | +          case 9:
 | 
	
		
			
				|  |  | +            break;
 | 
	
		
			
				|  |  | +          case 6:
 | 
	
		
			
				|  |  | +            multiplier *= 1000;
 | 
	
		
			
				|  |  | +            break;
 | 
	
		
			
				|  |  | +          case 3:
 | 
	
		
			
				|  |  | +            multiplier *= 1000000;
 | 
	
		
			
				|  |  | +            break;
 | 
	
		
			
				|  |  | +          default:  // Unsupported number of digits.
 | 
	
		
			
				|  |  | +            gpr_free(buf);
 | 
	
		
			
				|  |  | +            return NULL;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        timeout.tv_nsec *= multiplier;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | +      timeout.tv_sec = gpr_parse_nonnegative_int(buf);
 | 
	
		
			
				|  |  | +      if (timeout.tv_sec == -1) return NULL;
 | 
	
		
			
				|  |  | +      gpr_free(buf);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    method_parameters *value = gpr_malloc(sizeof(method_parameters));
 |