Addressing latest comments.

pull/168/head
Nicolas Noble 10 years ago committed by Nicolas "Pixel" Noble
parent a2fa1d778f
commit 8c2be9bbff
  1. 12
      src/core/json/json.c
  2. 6
      src/core/json/json.h
  3. 148
      src/core/json/json_reader.c
  4. 50
      src/core/json/json_reader.h
  5. 186
      src/core/json/json_string.c
  6. 135
      src/core/json/json_writer.c
  7. 21
      src/core/json/json_writer.h
  8. 2
      src/core/security/credentials.c
  9. 12
      src/core/security/json_token.c
  10. 4
      test/core/security/json_token_test.c

@ -31,23 +31,23 @@
*
*/
#include <string.h>
#include <grpc/support/alloc.h>
#include "src/core/json/json.h"
grpc_json *grpc_json_new(grpc_json_type type) {
grpc_json *grpc_json_create(grpc_json_type type) {
grpc_json *json = gpr_malloc(sizeof(grpc_json));
json->parent = json->child = json->next = json->prev = NULL;
memset(json, 0, sizeof(grpc_json));
json->type = type;
json->value = json->key = NULL;
return json;
}
void grpc_json_delete(grpc_json *json) {
void grpc_json_destroy(grpc_json *json) {
while (json->child) {
grpc_json_delete(json->child);
grpc_json_destroy(json->child);
}
if (json->next) {

@ -63,7 +63,7 @@ typedef struct grpc_json {
* All the keys and values in the grpc_json_t objects will be strings
* pointing at your input buffer.
*
* Delete the allocated tree afterward using grpc_json_delete().
* Delete the allocated tree afterward using grpc_json_destroy().
*/
grpc_json* grpc_json_parse_string_with_len(char* input, size_t size);
grpc_json* grpc_json_parse_string(char* input);
@ -82,7 +82,7 @@ char* grpc_json_dump_to_string(grpc_json* json, int indent);
* Deletion is recursive. We will not attempt to free any of the strings
* in any of the objects of that tree.
*/
grpc_json* grpc_json_new(grpc_json_type type);
void grpc_json_delete(grpc_json* json);
grpc_json* grpc_json_create(grpc_json_type type);
void grpc_json_destroy(grpc_json* json);
#endif /* __GRPC_SRC_CORE_JSON_JSON_H__ */

@ -31,69 +31,72 @@
*
*/
#include <string.h>
#include <grpc/support/port_platform.h>
#include "src/core/json/json_reader.h"
static void grpc_json_reader_string_clear(grpc_json_reader* reader) {
reader->string_clear(reader);
static void json_reader_string_clear(grpc_json_reader* reader) {
reader->vtable->string_clear(reader->userdata);
}
static void grpc_json_reader_string_add_char(grpc_json_reader* reader,
static void json_reader_string_add_char(grpc_json_reader* reader,
gpr_uint32 c) {
reader->string_add_char(reader, c);
reader->vtable->string_add_char(reader->userdata, c);
}
static void grpc_json_reader_string_add_utf32(grpc_json_reader* reader,
static void json_reader_string_add_utf32(grpc_json_reader* reader,
gpr_uint32 utf32) {
reader->string_add_utf32(reader, utf32);
reader->vtable->string_add_utf32(reader->userdata, utf32);
}
static gpr_uint32
grpc_json_reader_read_char(grpc_json_reader* reader) {
return reader->read_char(reader);
return reader->vtable->read_char(reader->userdata);
}
static void grpc_json_reader_container_begins(grpc_json_reader* reader,
static void json_reader_container_begins(grpc_json_reader* reader,
grpc_json_type type) {
reader->container_begins(reader, type);
reader->vtable->container_begins(reader->userdata, type);
}
static grpc_json_type
grpc_json_reader_container_ends(grpc_json_reader* reader) {
return reader->container_ends(reader);
return reader->vtable->container_ends(reader->userdata);
}
static void grpc_json_reader_set_key(grpc_json_reader* reader) {
reader->set_key(reader);
static void json_reader_set_key(grpc_json_reader* reader) {
reader->vtable->set_key(reader->userdata);
}
static void grpc_json_reader_set_string(grpc_json_reader* reader) {
reader->set_string(reader);
static void json_reader_set_string(grpc_json_reader* reader) {
reader->vtable->set_string(reader->userdata);
}
static int grpc_json_reader_set_number(grpc_json_reader* reader) {
return reader->set_number(reader);
static int json_reader_set_number(grpc_json_reader* reader) {
return reader->vtable->set_number(reader->userdata);
}
static void grpc_json_reader_set_true(grpc_json_reader* reader) {
reader->set_true(reader);
static void json_reader_set_true(grpc_json_reader* reader) {
reader->vtable->set_true(reader->userdata);
}
static void grpc_json_reader_set_false(grpc_json_reader* reader) {
reader->set_false(reader);
static void json_reader_set_false(grpc_json_reader* reader) {
reader->vtable->set_false(reader->userdata);
}
static void grpc_json_reader_set_null(grpc_json_reader* reader) {
reader->set_null(reader);
static void json_reader_set_null(grpc_json_reader* reader) {
reader->vtable->set_null(reader->userdata);
}
/* Call this function to initialize the reader structure. */
void grpc_json_reader_init(grpc_json_reader* reader) {
reader->depth = 0;
reader->in_object = 0;
reader->in_array = 0;
reader->unicode_high_surrogate = 0;
grpc_json_reader_string_clear(reader);
void grpc_json_reader_init(grpc_json_reader* reader,
grpc_json_reader_vtable* vtable, void* userdata) {
memset(reader, 0, sizeof(grpc_json_reader));
reader->vtable = vtable;
reader->userdata = userdata;
json_reader_string_clear(reader);
reader->state = GRPC_JSON_STATE_VALUE_BEGIN;
}
@ -102,7 +105,7 @@ int grpc_json_reader_is_complete(grpc_json_reader* reader) {
(reader->state == GRPC_JSON_STATE_VALUE_END)));
}
grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
grpc_json_reader_status grpc_json_reader_run(grpc_json_reader* reader) {
gpr_uint32 c, success;
/* This state-machine is a strict implementation of ECMA-404 */
@ -140,17 +143,17 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
case GRPC_JSON_STATE_OBJECT_KEY_STRING:
case GRPC_JSON_STATE_VALUE_STRING:
if (c != ' ') return GRPC_JSON_PARSE_ERROR;
if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_add_char(reader, c);
if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR;
json_reader_string_add_char(reader, c);
break;
case GRPC_JSON_STATE_VALUE_NUMBER:
case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
success = grpc_json_reader_set_number(reader);
success = json_reader_set_number(reader);
if (!success) return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_clear(reader);
json_reader_string_clear(reader);
reader->state = GRPC_JSON_STATE_VALUE_END;
break;
@ -166,17 +169,17 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
switch (reader->state) {
case GRPC_JSON_STATE_OBJECT_KEY_STRING:
case GRPC_JSON_STATE_VALUE_STRING:
if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_add_char(reader, c);
if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR;
json_reader_string_add_char(reader, c);
break;
case GRPC_JSON_STATE_VALUE_NUMBER:
case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
success = grpc_json_reader_set_number(reader);
success = json_reader_set_number(reader);
if (!success) return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_clear(reader);
json_reader_string_clear(reader);
reader->state = GRPC_JSON_STATE_VALUE_END;
/* The missing break here is intentional. */
@ -250,8 +253,8 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
/* This is the \\ case. */
case GRPC_JSON_STATE_STRING_ESCAPE:
if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_add_char(reader, '\\');
if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR;
json_reader_string_add_char(reader, '\\');
if (reader->escaped_string_was_key) {
reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
} else {
@ -273,26 +276,26 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
break;
case GRPC_JSON_STATE_OBJECT_KEY_STRING:
if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR;
if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR;
if (c == '"') {
reader->state = GRPC_JSON_STATE_OBJECT_KEY_END;
grpc_json_reader_set_key(reader);
grpc_json_reader_string_clear(reader);
json_reader_set_key(reader);
json_reader_string_clear(reader);
} else {
if (c < 32) return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_add_char(reader, c);
if (c <= 0x001f) return GRPC_JSON_PARSE_ERROR;
json_reader_string_add_char(reader, c);
}
break;
case GRPC_JSON_STATE_VALUE_STRING:
if (reader->unicode_high_surrogate) return GRPC_JSON_PARSE_ERROR;
if (reader->unicode_high_surrogate != 0) return GRPC_JSON_PARSE_ERROR;
if (c == '"') {
reader->state = GRPC_JSON_STATE_VALUE_END;
grpc_json_reader_set_string(reader);
grpc_json_reader_string_clear(reader);
json_reader_set_string(reader);
json_reader_string_clear(reader);
} else {
if (c < 32) return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
}
break;
@ -333,13 +336,13 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
case '8':
case '9':
case '-':
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
reader->state = GRPC_JSON_STATE_VALUE_NUMBER;
break;
case '{':
reader->container_just_begun = 1;
grpc_json_reader_container_begins(reader, GRPC_JSON_OBJECT);
json_reader_container_begins(reader, GRPC_JSON_OBJECT);
reader->depth++;
reader->state = GRPC_JSON_STATE_OBJECT_KEY_BEGIN;
reader->in_object = 1;
@ -348,7 +351,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
case '[':
reader->container_just_begun = 1;
grpc_json_reader_container_begins(reader, GRPC_JSON_ARRAY);
json_reader_container_begins(reader, GRPC_JSON_ARRAY);
reader->depth++;
reader->in_object = 0;
reader->in_array = 1;
@ -367,22 +370,22 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
switch (c) {
case '"':
case '/':
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
break;
case 'b':
grpc_json_reader_string_add_char(reader, '\b');
json_reader_string_add_char(reader, '\b');
break;
case 'f':
grpc_json_reader_string_add_char(reader, '\f');
json_reader_string_add_char(reader, '\f');
break;
case 'n':
grpc_json_reader_string_add_char(reader, '\n');
json_reader_string_add_char(reader, '\n');
break;
case 'r':
grpc_json_reader_string_add_char(reader, '\r');
json_reader_string_add_char(reader, '\r');
break;
case 't':
grpc_json_reader_string_add_char(reader, '\t');
json_reader_string_add_char(reader, '\t');
break;
case 'u':
reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U1;
@ -420,26 +423,29 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
reader->state = GRPC_JSON_STATE_STRING_ESCAPE_U4;
break;
case GRPC_JSON_STATE_STRING_ESCAPE_U4:
/* See grpc_json_writer_escape_string to have a description
* of what's going on here.
*/
if ((reader->unicode_char & 0xfc00) == 0xd800) {
/* high surrogate utf-16 */
if (reader->unicode_high_surrogate)
if (reader->unicode_high_surrogate != 0)
return GRPC_JSON_PARSE_ERROR;
reader->unicode_high_surrogate = reader->unicode_char;
} else if ((reader->unicode_char & 0xfc00) == 0xdc00) {
/* low surrogate utf-16 */
gpr_uint32 utf32;
if (!reader->unicode_high_surrogate)
if (reader->unicode_high_surrogate == 0)
return GRPC_JSON_PARSE_ERROR;
utf32 = 0x10000;
utf32 += (reader->unicode_high_surrogate - 0xd800) * 0x400;
utf32 += reader->unicode_char - 0xdc00;
grpc_json_reader_string_add_utf32(reader, utf32);
json_reader_string_add_utf32(reader, utf32);
reader->unicode_high_surrogate = 0;
} else {
/* anything else */
if (reader->unicode_high_surrogate)
if (reader->unicode_high_surrogate != 0)
return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_add_utf32(reader, reader->unicode_char);
json_reader_string_add_utf32(reader, reader->unicode_char);
}
if (reader->escaped_string_was_key) {
reader->state = GRPC_JSON_STATE_OBJECT_KEY_STRING;
@ -453,7 +459,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
break;
case GRPC_JSON_STATE_VALUE_NUMBER:
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
switch (c) {
case '0':
case '1':
@ -475,7 +481,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
break;
case GRPC_JSON_STATE_VALUE_NUMBER_WITH_DECIMAL:
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
switch (c) {
case '0':
case '1':
@ -499,12 +505,12 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
case GRPC_JSON_STATE_VALUE_NUMBER_ZERO:
if (c != '.') return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
reader->state = GRPC_JSON_STATE_VALUE_NUMBER_DOT;
break;
case GRPC_JSON_STATE_VALUE_NUMBER_DOT:
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
switch (c) {
case '0':
case '1':
@ -524,7 +530,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
break;
case GRPC_JSON_STATE_VALUE_NUMBER_E:
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
switch (c) {
case '0':
case '1':
@ -545,7 +551,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
}
case GRPC_JSON_STATE_VALUE_NUMBER_EPM:
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(reader, c);
switch (c) {
case '0':
case '1':
@ -574,7 +580,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
case GRPC_JSON_STATE_VALUE_TRUE_E:
if (c != 'e') return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_set_true(reader);
json_reader_set_true(reader);
reader->state = GRPC_JSON_STATE_VALUE_END;
break;
@ -595,7 +601,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
case GRPC_JSON_STATE_VALUE_FALSE_E:
if (c != 'e') return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_set_false(reader);
json_reader_set_false(reader);
reader->state = GRPC_JSON_STATE_VALUE_END;
break;
@ -611,7 +617,7 @@ grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader) {
case GRPC_JSON_STATE_VALUE_NULL_L2:
if (c != 'l') return GRPC_JSON_PARSE_ERROR;
grpc_json_reader_set_null(reader);
json_reader_set_null(reader);
reader->state = GRPC_JSON_STATE_VALUE_END;
break;

@ -78,39 +78,40 @@ enum {
GRPC_JSON_READ_CHAR_ERROR
};
typedef struct grpc_json_reader {
/* You are responsible for your own opaque userdata.
* Among other things, it needs to hold a string scratchpad.
*/
void* userdata;
/* You also need to set up these callbacks. */
struct grpc_json_reader;
typedef struct grpc_json_reader_vtable {
/* Clears your internal string scratchpad. */
void (*string_clear)(struct grpc_json_reader*);
void (*string_clear)(void* userdata);
/* Adds a char to the string scratchpad. */
void (*string_add_char)(struct grpc_json_reader*, gpr_uint32 c);
void (*string_add_char)(void* userdata, gpr_uint32 c);
/* Adds a utf32 char to the string scratchpad. */
void (*string_add_utf32)(struct grpc_json_reader*, gpr_uint32 c);
void (*string_add_utf32)(void* userdata, gpr_uint32 c);
/* Reads a character from your input. May be utf-8, 16 or 32. */
gpr_uint32 (*read_char)(struct grpc_json_reader*);
gpr_uint32 (*read_char)(void* userdata);
/* Starts a container of type GRPC_JSON_ARRAY or GRPC_JSON_OBJECT. */
void (*container_begins)(struct grpc_json_reader*, grpc_json_type type);
void (*container_begins)(void* userdata, grpc_json_type type);
/* Ends the current container. Must return the type of its parent. */
grpc_json_type (*container_ends)(struct grpc_json_reader*);
grpc_json_type (*container_ends)(void* userdata);
/* Your internal string scratchpad is an object's key. */
void (*set_key)(struct grpc_json_reader*);
void (*set_key)(void* userdata);
/* Your internal string scratchpad is a string value. */
void (*set_string)(struct grpc_json_reader*);
void (*set_string)(void* userdata);
/* Your internal string scratchpad is a numerical value. Return 1 if valid. */
int (*set_number)(struct grpc_json_reader*);
int (*set_number)(void* userdata);
/* Sets the values true, false or null. */
void (*set_true)(struct grpc_json_reader*);
void (*set_false)(struct grpc_json_reader*);
void (*set_null)(struct grpc_json_reader*);
void (*set_true)(void* userdata);
void (*set_false)(void* userdata);
void (*set_null)(void* userdata);
} grpc_json_reader_vtable;
/* Everything down here is private,
and initialized by grpc_json_reader_init. */
typedef struct grpc_json_reader {
/* That structure is fully private, and initialized by grpc_json_reader_init.
* The definition is public so you can put it on your stack.
*/
void* userdata;
grpc_json_reader_vtable* vtable;
int depth;
int in_object;
int in_array;
@ -127,7 +128,7 @@ typedef enum {
GRPC_JSON_READ_ERROR, /* The parser passes through a read error. */
GRPC_JSON_PARSE_ERROR, /* The parser found an error in the json stream. */
GRPC_JSON_INTERNAL_ERROR /* The parser got an internal error. */
} grpc_json_reader_ret;
} grpc_json_reader_status;
/* Call this function to start parsing the input. It will return the following:
* . GRPC_JSON_DONE if the input got eof, and the parsing finished
@ -143,10 +144,11 @@ typedef enum {
* . GRPC_JSON_INTERNAL_ERROR if the parser somehow ended into an invalid
* internal state.
*/
grpc_json_reader_ret grpc_json_reader_run(grpc_json_reader* reader);
grpc_json_reader_status grpc_json_reader_run(grpc_json_reader* reader);
/* Call this function to initialize the reader structure. */
void grpc_json_reader_init(grpc_json_reader* reader);
void grpc_json_reader_init(grpc_json_reader* reader,
grpc_json_reader_vtable* vtable, void* userdata);
/* You may call this from the read_char callback if you don't know where is the
* end of your input stream, and you'd like the json reader to hint you that it

@ -61,24 +61,25 @@ typedef struct {
char* string;
char* string_ptr;
size_t remaining_input;
} grpc_json_reader_opaque;
} json_reader_userdata;
/* This json writer will put everything in a big string.
* The point is that we allocate that string in chunks of 256 bytes.
*/
typedef struct {
char* output;
size_t free_space, string_len, allocated;
} grpc_json_writer_opaque;
size_t free_space;
size_t string_len;
size_t allocated;
} json_writer_userdata;
/* This function checks if there's enough space left in the output buffer,
* and will enlarge it if necessary. We're only allocating chunks of 256
* bytes at a time (or multiples thereof).
*/
static void grpc_json_writer_output_check(grpc_json_writer* writer,
size_t needed) {
grpc_json_writer_opaque* state = writer->userdata;
static void json_writer_output_check(void* userdata, size_t needed) {
json_writer_userdata* state = userdata;
if (state->free_space >= needed) return;
needed -= state->free_space;
/* Round up by 256 bytes. */
@ -89,34 +90,33 @@ static void grpc_json_writer_output_check(grpc_json_writer* writer,
}
/* These are needed by the writer's implementation. */
static void grpc_json_writer_output_char(grpc_json_writer* writer,
char c) {
grpc_json_writer_opaque* state = writer->userdata;
grpc_json_writer_output_check(writer, 1);
static void json_writer_output_char(void* userdata, char c) {
json_writer_userdata* state = userdata;
json_writer_output_check(userdata, 1);
state->output[state->string_len++] = c;
state->free_space--;
}
static void grpc_json_writer_output_string_with_len(
grpc_json_writer* writer, const char* str, size_t len) {
grpc_json_writer_opaque* state = writer->userdata;
grpc_json_writer_output_check(writer, len);
static void json_writer_output_string_with_len(void* userdata,
const char* str, size_t len) {
json_writer_userdata* state = userdata;
json_writer_output_check(userdata, len);
memcpy(state->output + state->string_len, str, len);
state->string_len += len;
state->free_space -= len;
}
static void grpc_json_writer_output_string(grpc_json_writer* writer,
static void json_writer_output_string(void* userdata,
const char* str) {
size_t len = strlen(str);
grpc_json_writer_output_string_with_len(writer, str, len);
json_writer_output_string_with_len(userdata, str, len);
}
/* The reader asks us to clear our scratchpad. In our case, we'll simply mark
* the end of the current string, and advance our output pointer.
*/
static void grpc_json_reader_string_clear(grpc_json_reader* reader) {
grpc_json_reader_opaque* state = reader->userdata;
static void json_reader_string_clear(void* userdata) {
json_reader_userdata* state = userdata;
if (state->string) {
GPR_ASSERT(state->string_ptr < state->input);
*state->string_ptr++ = 0;
@ -124,47 +124,49 @@ static void grpc_json_reader_string_clear(grpc_json_reader* reader) {
state->string = state->string_ptr;
}
static void grpc_json_reader_string_add_char(grpc_json_reader* reader, gpr_uint32 c) {
grpc_json_reader_opaque* state = reader->userdata;
static void json_reader_string_add_char(void* userdata, gpr_uint32 c) {
json_reader_userdata* state = userdata;
GPR_ASSERT(state->string_ptr < state->input);
GPR_ASSERT(c <= 0xff);
*state->string_ptr++ = (char)c;
}
/* We are converting a UTF-32 character into UTF-8 here. */
static void grpc_json_reader_string_add_utf32(grpc_json_reader* reader, gpr_uint32 c) {
/* We are converting a UTF-32 character into UTF-8 here,
* as described by RFC3629.
*/
static void json_reader_string_add_utf32(void* userdata, gpr_uint32 c) {
if (c <= 0x7f) {
grpc_json_reader_string_add_char(reader, c);
json_reader_string_add_char(userdata, c);
} else if (c <= 0x7ff) {
int b1 = 0xc0 | ((c >> 6) & 0x1f);
int b2 = 0x80 | (c & 0x3f);
grpc_json_reader_string_add_char(reader, b1);
grpc_json_reader_string_add_char(reader, b2);
json_reader_string_add_char(userdata, b1);
json_reader_string_add_char(userdata, b2);
} else if (c <= 0xffff) {
int b1 = 0xe0 | ((c >> 12) & 0x0f);
int b2 = 0x80 | ((c >> 6) & 0x3f);
int b3 = 0x80 | (c & 0x3f);
grpc_json_reader_string_add_char(reader, b1);
grpc_json_reader_string_add_char(reader, b2);
grpc_json_reader_string_add_char(reader, b3);
json_reader_string_add_char(userdata, b1);
json_reader_string_add_char(userdata, b2);
json_reader_string_add_char(userdata, b3);
} else if (c <= 0x1fffff) {
int b1 = 0xf0 | ((c >> 18) & 0x07);
int b2 = 0x80 | ((c >> 12) & 0x3f);
int b3 = 0x80 | ((c >> 6) & 0x3f);
int b4 = 0x80 | (c & 0x3f);
grpc_json_reader_string_add_char(reader, b1);
grpc_json_reader_string_add_char(reader, b2);
grpc_json_reader_string_add_char(reader, b3);
grpc_json_reader_string_add_char(reader, b4);
json_reader_string_add_char(userdata, b1);
json_reader_string_add_char(userdata, b2);
json_reader_string_add_char(userdata, b3);
json_reader_string_add_char(userdata, b4);
}
}
/* We consider that the input may be a zero-terminated string. So we
* can end up hitting eof before the end of the alleged string length.
*/
static gpr_uint32 grpc_json_reader_read_char(grpc_json_reader* reader) {
static gpr_uint32 json_reader_read_char(void* userdata) {
gpr_uint32 r;
grpc_json_reader_opaque* state = reader->userdata;
json_reader_userdata* state = userdata;
if (state->remaining_input == 0) return GRPC_JSON_READ_CHAR_EOF;
@ -182,10 +184,10 @@ static gpr_uint32 grpc_json_reader_read_char(grpc_json_reader* reader) {
/* Helper function to create a new grpc_json object and link it into
* our tree-in-progress inside our opaque structure.
*/
static grpc_json* grpc_json_new_and_link(grpc_json_reader* reader,
grpc_json_type type) {
grpc_json_reader_opaque* state = reader->userdata;
grpc_json* json = grpc_json_new(type);
static grpc_json* json_create_and_link(void* userdata,
grpc_json_type type) {
json_reader_userdata* state = userdata;
grpc_json* json = grpc_json_create(type);
json->parent = state->current_container;
json->prev = state->current_value;
@ -209,14 +211,13 @@ static grpc_json* grpc_json_new_and_link(grpc_json_reader* reader,
return json;
}
static void grpc_json_reader_container_begins(grpc_json_reader* reader,
grpc_json_type type) {
grpc_json_reader_opaque* state = reader->userdata;
static void json_reader_container_begins(void* userdata, grpc_json_type type) {
json_reader_userdata* state = userdata;
grpc_json* container;
GPR_ASSERT(type == GRPC_JSON_ARRAY || type == GRPC_JSON_OBJECT);
container = grpc_json_new_and_link(reader, type);
container = json_create_and_link(userdata, type);
state->current_container = container;
state->current_value = NULL;
}
@ -230,10 +231,9 @@ static void grpc_json_reader_container_begins(grpc_json_reader* reader,
* Also note that if we're at the top of the tree, and the last container
* ends, we have to return GRPC_JSON_TOP_LEVEL.
*/
static grpc_json_type grpc_json_reader_container_ends(
grpc_json_reader* reader) {
static grpc_json_type json_reader_container_ends(void* userdata) {
grpc_json_type container_type = GRPC_JSON_TOP_LEVEL;
grpc_json_reader_opaque* state = reader->userdata;
json_reader_userdata* state = userdata;
GPR_ASSERT(state->current_container);
@ -253,22 +253,20 @@ static grpc_json_type grpc_json_reader_container_ends(
* Note that in the set_number case, we're not going to try interpreting it.
* We'll keep it as a string, and leave it to the caller to evaluate it.
*/
static void grpc_json_reader_set_key(grpc_json_reader* reader) {
grpc_json_reader_opaque* state = reader->userdata;
static void json_reader_set_key(void* userdata) {
json_reader_userdata* state = userdata;
state->key = state->string;
}
static void grpc_json_reader_set_string(
grpc_json_reader* reader) {
grpc_json_reader_opaque* state = reader->userdata;
grpc_json* json = grpc_json_new_and_link(reader, GRPC_JSON_STRING);
static void json_reader_set_string(void* userdata) {
json_reader_userdata* state = userdata;
grpc_json* json = json_create_and_link(userdata, GRPC_JSON_STRING);
json->value = state->string;
}
static int grpc_json_reader_set_number(
grpc_json_reader* reader) {
grpc_json_reader_opaque* state = reader->userdata;
grpc_json* json = grpc_json_new_and_link(reader, GRPC_JSON_NUMBER);
static int json_reader_set_number(void* userdata) {
json_reader_userdata* state = userdata;
grpc_json* json = json_create_and_link(userdata, GRPC_JSON_NUMBER);
json->value = state->string;
return 1;
}
@ -276,27 +274,39 @@ static int grpc_json_reader_set_number(
/* The object types true, false and null are self-sufficient, and don't need
* any more information beside their type.
*/
static void grpc_json_reader_set_true(
grpc_json_reader *reader) {
grpc_json_new_and_link(reader, GRPC_JSON_TRUE);
static void json_reader_set_true(void* userdata) {
json_create_and_link(userdata, GRPC_JSON_TRUE);
}
static void grpc_json_reader_set_false(
grpc_json_reader *reader) {
grpc_json_new_and_link(reader, GRPC_JSON_FALSE);
static void json_reader_set_false(void* userdata) {
json_create_and_link(userdata, GRPC_JSON_FALSE);
}
static void grpc_json_reader_set_null(
grpc_json_reader *reader) {
grpc_json_new_and_link(reader, GRPC_JSON_NULL);
static void json_reader_set_null(void* userdata) {
json_create_and_link(userdata, GRPC_JSON_NULL);
}
static grpc_json_reader_vtable reader_vtable = {
json_reader_string_clear,
json_reader_string_add_char,
json_reader_string_add_utf32,
json_reader_read_char,
json_reader_container_begins,
json_reader_container_ends,
json_reader_set_key,
json_reader_set_string,
json_reader_set_number,
json_reader_set_true,
json_reader_set_false,
json_reader_set_null
};
/* And finally, let's define our public API. */
grpc_json* grpc_json_parse_string_with_len(char* input, size_t size) {
grpc_json_reader reader;
grpc_json_reader_opaque state;
json_reader_userdata state;
grpc_json *json = NULL;
grpc_json_reader_ret status;
grpc_json_reader_status status;
if (!input) return NULL;
@ -304,26 +314,13 @@ grpc_json* grpc_json_parse_string_with_len(char* input, size_t size) {
state.string = state.key = NULL;
state.string_ptr = state.input = input;
state.remaining_input = size;
reader.userdata = &state;
reader.string_clear = grpc_json_reader_string_clear;
reader.string_add_char = grpc_json_reader_string_add_char;
reader.string_add_utf32 = grpc_json_reader_string_add_utf32;
reader.read_char = grpc_json_reader_read_char;
reader.container_begins = grpc_json_reader_container_begins;
reader.container_ends = grpc_json_reader_container_ends;
reader.set_key = grpc_json_reader_set_key;
reader.set_string = grpc_json_reader_set_string;
reader.set_number = grpc_json_reader_set_number;
reader.set_true = grpc_json_reader_set_true;
reader.set_false = grpc_json_reader_set_false;
reader.set_null = grpc_json_reader_set_null;
grpc_json_reader_init(&reader);
grpc_json_reader_init(&reader, &reader_vtable, &state);
status = grpc_json_reader_run(&reader);
json = state.top;
if ((status != GRPC_JSON_DONE) && json) {
grpc_json_delete(json);
grpc_json_destroy(json);
json = NULL;
}
@ -336,8 +333,8 @@ grpc_json* grpc_json_parse_string(char* input) {
return grpc_json_parse_string_with_len(input, UNBOUND_JSON_STRING_LENGTH);
}
static void grpc_json_dump_recursive(grpc_json_writer* writer,
grpc_json* json, int in_object) {
static void json_dump_recursive(grpc_json_writer* writer,
grpc_json* json, int in_object) {
while (json) {
if (in_object) grpc_json_writer_object_key(writer, json->key);
@ -346,8 +343,8 @@ static void grpc_json_dump_recursive(grpc_json_writer* writer,
case GRPC_JSON_ARRAY:
grpc_json_writer_container_begins(writer, json->type);
if (json->child)
grpc_json_dump_recursive(writer, json->child,
json->type == GRPC_JSON_OBJECT);
json_dump_recursive(writer, json->child,
json->type == GRPC_JSON_OBJECT);
grpc_json_writer_container_ends(writer, json->type);
break;
case GRPC_JSON_STRING:
@ -372,20 +369,23 @@ static void grpc_json_dump_recursive(grpc_json_writer* writer,
}
}
static grpc_json_writer_vtable writer_vtable = {
json_writer_output_char,
json_writer_output_string,
json_writer_output_string_with_len
};
char* grpc_json_dump_to_string(grpc_json* json, int indent) {
grpc_json_writer writer;
grpc_json_writer_opaque state;
json_writer_userdata state;
state.output = NULL;
state.free_space = state.string_len = state.allocated = 0;
writer.userdata = &state;
writer.output_char = grpc_json_writer_output_char;
writer.output_string = grpc_json_writer_output_string;
writer.output_string_with_len = grpc_json_writer_output_string_with_len;
grpc_json_writer_init(&writer, indent);
grpc_json_writer_init(&writer, indent, &writer_vtable, &state);
grpc_json_dump_recursive(&writer, json, 0);
json_dump_recursive(&writer, json, 0);
grpc_json_writer_output_char(&writer, 0);
json_writer_output_char(&state, 0);
return state.output;
}

@ -31,30 +31,34 @@
*
*/
#include <string.h>
#include <grpc/support/port_platform.h>
#include "src/core/json/json_writer.h"
static void grpc_json_writer_output_char(grpc_json_writer* writer, char c) {
writer->output_char(writer, c);
static void json_writer_output_char(grpc_json_writer* writer, char c) {
writer->vtable->output_char(writer->userdata, c);
}
static void grpc_json_writer_output_string(grpc_json_writer* writer, const char* str) {
writer->output_string(writer, str);
static void json_writer_output_string(grpc_json_writer* writer, const char* str) {
writer->vtable->output_string(writer->userdata, str);
}
static void grpc_json_writer_output_string_with_len(grpc_json_writer* writer, const char* str, size_t len) {
writer->output_string_with_len(writer, str, len);
static void json_writer_output_string_with_len(grpc_json_writer* writer, const char* str, size_t len) {
writer->vtable->output_string_with_len(writer->userdata, str, len);
}
/* Call this function to initialize the writer structure. */
void grpc_json_writer_init(grpc_json_writer* writer, int indent) {
writer->depth = 0;
void grpc_json_writer_init(grpc_json_writer* writer, int indent,
grpc_json_writer_vtable* vtable, void* userdata) {
memset(writer, 0, sizeof(grpc_json_writer));
writer->container_empty = 1;
writer->got_key = 0;
writer->indent = indent;
writer->vtable = vtable;
writer->userdata = userdata;
}
static void grpc_json_writer_output_indent(
static void json_writer_output_indent(
grpc_json_writer* writer) {
static const char spacesstr[] =
" "
@ -64,77 +68,78 @@ static void grpc_json_writer_output_indent(
int spaces = writer->depth * writer->indent;
if (writer->indent == 0) return;
if (writer->got_key) {
grpc_json_writer_output_char(writer, ' ');
json_writer_output_char(writer, ' ');
return;
}
while (spaces >= (sizeof(spacesstr) - 1)) {
grpc_json_writer_output_string_with_len(writer, spacesstr,
json_writer_output_string_with_len(writer, spacesstr,
sizeof(spacesstr) - 1);
spaces -= (sizeof(spacesstr) - 1);
}
if (!spaces) return;
if (spaces == 0) return;
grpc_json_writer_output_string_with_len(
json_writer_output_string_with_len(
writer, spacesstr + sizeof(spacesstr) - 1 - spaces, spaces);
}
static void grpc_json_writer_value_end(
grpc_json_writer* writer) {
static void json_writer_value_end(grpc_json_writer* writer) {
if (writer->container_empty) {
writer->container_empty = 0;
if (!writer->indent || !writer->depth) return;
grpc_json_writer_output_char(writer, '\n');
if ((writer->indent == 0) || (writer->depth == 0)) return;
json_writer_output_char(writer, '\n');
} else {
grpc_json_writer_output_char(writer, ',');
if (!writer->indent) return;
grpc_json_writer_output_char(writer, '\n');
json_writer_output_char(writer, ',');
if (writer->indent == 0) return;
json_writer_output_char(writer, '\n');
}
}
static void grpc_json_writer_escape_utf16(grpc_json_writer* writer, gpr_uint16 utf16) {
static void json_writer_escape_utf16(grpc_json_writer* writer, gpr_uint16 utf16) {
static const char hex[] = "0123456789abcdef";
grpc_json_writer_output_string_with_len(writer, "\\u", 2);
grpc_json_writer_output_char(writer, hex[(utf16 >> 12) & 0x0f]);
grpc_json_writer_output_char(writer, hex[(utf16 >> 8) & 0x0f]);
grpc_json_writer_output_char(writer, hex[(utf16 >> 4) & 0x0f]);
grpc_json_writer_output_char(writer, hex[(utf16) & 0x0f]);
json_writer_output_string_with_len(writer, "\\u", 2);
json_writer_output_char(writer, hex[(utf16 >> 12) & 0x0f]);
json_writer_output_char(writer, hex[(utf16 >> 8) & 0x0f]);
json_writer_output_char(writer, hex[(utf16 >> 4) & 0x0f]);
json_writer_output_char(writer, hex[(utf16) & 0x0f]);
}
static void grpc_json_writer_escape_string(
grpc_json_writer* writer, const char* string) {
grpc_json_writer_output_char(writer, '"');
static void json_writer_escape_string(grpc_json_writer* writer,
const char* string) {
json_writer_output_char(writer, '"');
for (;;) {
unsigned char c = (unsigned char)*string++;
if (!c) {
gpr_uint8 c = (gpr_uint8)*string++;
if (c == 0) {
break;
} else if ((c >= 32) && (c <= 127)) {
if ((c == '\\') || (c == '"')) grpc_json_writer_output_char(writer, '\\');
grpc_json_writer_output_char(writer, c);
if ((c == '\\') || (c == '"')) json_writer_output_char(writer, '\\');
json_writer_output_char(writer, c);
} else if (c < 32) {
grpc_json_writer_output_char(writer, '\\');
json_writer_output_char(writer, '\\');
switch (c) {
case '\b':
grpc_json_writer_output_char(writer, 'b');
json_writer_output_char(writer, 'b');
break;
case '\f':
grpc_json_writer_output_char(writer, 'f');
json_writer_output_char(writer, 'f');
break;
case '\n':
grpc_json_writer_output_char(writer, 'n');
json_writer_output_char(writer, 'n');
break;
case '\r':
grpc_json_writer_output_char(writer, 'r');
json_writer_output_char(writer, 'r');
break;
case '\t':
grpc_json_writer_output_char(writer, 't');
json_writer_output_char(writer, 't');
break;
default:
grpc_json_writer_escape_utf16(writer, c);
json_writer_escape_utf16(writer, c);
break;
}
} else {
@ -188,21 +193,21 @@ static void grpc_json_writer_escape_string(
* That range is exactly 20 bits.
*/
utf32 -= 0x10000;
grpc_json_writer_escape_utf16(writer, 0xd800 | (utf32 >> 10));
grpc_json_writer_escape_utf16(writer, 0xdc00 | (utf32 && 0x3ff));
json_writer_escape_utf16(writer, 0xd800 | (utf32 >> 10));
json_writer_escape_utf16(writer, 0xdc00 | (utf32 && 0x3ff));
} else {
grpc_json_writer_escape_utf16(writer, utf32);
json_writer_escape_utf16(writer, utf32);
}
}
}
grpc_json_writer_output_char(writer, '"');
json_writer_output_char(writer, '"');
}
void grpc_json_writer_container_begins(grpc_json_writer* writer, grpc_json_type type) {
if (!writer->got_key) grpc_json_writer_value_end(writer);
grpc_json_writer_output_indent(writer);
grpc_json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '{' : '[');
if (!writer->got_key) json_writer_value_end(writer);
json_writer_output_indent(writer);
json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '{' : '[');
writer->container_empty = 1;
writer->got_key = 0;
writer->depth++;
@ -210,39 +215,39 @@ void grpc_json_writer_container_begins(grpc_json_writer* writer, grpc_json_type
void grpc_json_writer_container_ends(grpc_json_writer* writer, grpc_json_type type) {
if (writer->indent && !writer->container_empty)
grpc_json_writer_output_char(writer, '\n');
json_writer_output_char(writer, '\n');
writer->depth--;
if (!writer->container_empty) grpc_json_writer_output_indent(writer);
grpc_json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '}' : ']');
if (!writer->container_empty) json_writer_output_indent(writer);
json_writer_output_char(writer, type == GRPC_JSON_OBJECT ? '}' : ']');
writer->container_empty = 0;
writer->got_key = 0;
}
void grpc_json_writer_object_key(grpc_json_writer* writer, const char* string) {
grpc_json_writer_value_end(writer);
grpc_json_writer_output_indent(writer);
grpc_json_writer_escape_string(writer, string);
grpc_json_writer_output_char(writer, ':');
json_writer_value_end(writer);
json_writer_output_indent(writer);
json_writer_escape_string(writer, string);
json_writer_output_char(writer, ':');
writer->got_key = 1;
}
void grpc_json_writer_value_raw(grpc_json_writer* writer, const char* string) {
if (!writer->got_key) grpc_json_writer_value_end(writer);
grpc_json_writer_output_indent(writer);
grpc_json_writer_output_string(writer, string);
if (!writer->got_key) json_writer_value_end(writer);
json_writer_output_indent(writer);
json_writer_output_string(writer, string);
writer->got_key = 0;
}
void grpc_json_writer_value_raw_with_len(grpc_json_writer* writer, const char* string, size_t len) {
if (!writer->got_key) grpc_json_writer_value_end(writer);
grpc_json_writer_output_indent(writer);
grpc_json_writer_output_string_with_len(writer, string, len);
if (!writer->got_key) json_writer_value_end(writer);
json_writer_output_indent(writer);
json_writer_output_string_with_len(writer, string, len);
writer->got_key = 0;
}
void grpc_json_writer_value_string(grpc_json_writer* writer, const char* string) {
if (!writer->got_key) grpc_json_writer_value_end(writer);
grpc_json_writer_output_indent(writer);
grpc_json_writer_escape_string(writer, string);
if (!writer->got_key) json_writer_value_end(writer);
json_writer_output_indent(writer);
json_writer_escape_string(writer, string);
writer->got_key = 0;
}

@ -50,19 +50,19 @@
#include "src/core/json/json_common.h"
typedef struct grpc_json_writer {
/* You are responsible for your own opaque userdata. */
void* userdata;
/* The rest are your own callbacks. Define them. */
typedef struct grpc_json_writer_vtable {
/* Adds a character to the output stream. */
void (*output_char)(struct grpc_json_writer*, char);
void (*output_char)(void* userdata, char);
/* Adds a zero-terminated string to the output stream. */
void (*output_string)(struct grpc_json_writer*, const char* str);
void (*output_string)(void* userdata, const char* str);
/* Adds a fixed-length string to the output stream. */
void (*output_string_with_len)(struct grpc_json_writer*, const char* str, size_t len);
void (*output_string_with_len)(void* userdata, const char* str, size_t len);
} grpc_json_writer_vtable;
typedef struct grpc_json_writer {
void* userdata;
grpc_json_writer_vtable* vtable;
int indent;
int depth;
int container_empty;
@ -74,7 +74,8 @@ typedef struct grpc_json_writer {
* use indent=0, then the output will not have any newlines either, thus
* emitting a condensed json output.
*/
void grpc_json_writer_init(grpc_json_writer* writer, int indent);
void grpc_json_writer_init(grpc_json_writer* writer, int indent,
grpc_json_writer_vtable* vtable, void* userdata);
/* Signals the beginning of a container. */
void grpc_json_writer_container_begins(grpc_json_writer* writer, grpc_json_type type);

@ -407,7 +407,7 @@ end:
}
if (null_terminated_body != NULL) gpr_free(null_terminated_body);
if (new_access_token != NULL) gpr_free(new_access_token);
if (json != NULL) grpc_json_delete(json);
if (json != NULL) grpc_json_destroy(json);
return status;
}

@ -140,7 +140,7 @@ grpc_auth_json_key grpc_auth_json_key_create_from_string(
end:
if (bio != NULL) BIO_free(bio);
if (json != NULL) grpc_json_delete(json);
if (json != NULL) grpc_json_destroy(json);
if (!success) grpc_auth_json_key_destruct(&result);
gpr_free(scratchpad);
return result;
@ -172,7 +172,7 @@ void grpc_auth_json_key_destruct(grpc_auth_json_key *json_key) {
static grpc_json *create_child(grpc_json *brother, grpc_json *parent,
const char *key, const char *value,
grpc_json_type type) {
grpc_json *child = grpc_json_new(type);
grpc_json *child = grpc_json_create(type);
if (brother) brother->next = child;
if (!parent->child) parent->child = child;
child->parent = parent;
@ -182,7 +182,7 @@ static grpc_json *create_child(grpc_json *brother, grpc_json *parent,
}
static char *encoded_jwt_header(const char *algorithm) {
grpc_json *json = grpc_json_new(GRPC_JSON_OBJECT);
grpc_json *json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json *child = NULL;
char *json_str = NULL;
char *result = NULL;
@ -193,13 +193,13 @@ static char *encoded_jwt_header(const char *algorithm) {
json_str = grpc_json_dump_to_string(json, 0);
result = grpc_base64_encode(json_str, strlen(json_str), 1, 0);
gpr_free(json_str);
grpc_json_delete(json);
grpc_json_destroy(json);
return result;
}
static char *encoded_jwt_claim(const grpc_auth_json_key *json_key,
const char *scope, gpr_timespec token_lifetime) {
grpc_json *json = grpc_json_new(GRPC_JSON_OBJECT);
grpc_json *json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json *child = NULL;
char *json_str = NULL;
char *result = NULL;
@ -225,7 +225,7 @@ static char *encoded_jwt_claim(const grpc_auth_json_key *json_key,
json_str = grpc_json_dump_to_string(json, 0);
result = grpc_base64_encode(json_str, strlen(json_str), 1, 0);
gpr_free(json_str);
grpc_json_delete(json);
grpc_json_destroy(json);
return result;
}

@ -341,7 +341,7 @@ static void test_jwt_encode_and_sign(void) {
GPR_ASSERT(parsed_header != NULL);
check_jwt_header(parsed_header);
offset = dot - jwt + 1;
grpc_json_delete(parsed_header);
grpc_json_destroy(parsed_header);
gpr_free(scratchpad);
dot = strchr(jwt + offset, '.');
@ -350,7 +350,7 @@ static void test_jwt_encode_and_sign(void) {
GPR_ASSERT(parsed_claim != NULL);
check_jwt_claim(parsed_claim);
offset = dot - jwt + 1;
grpc_json_delete(parsed_claim);
grpc_json_destroy(parsed_claim);
gpr_free(scratchpad);
dot = strchr(jwt + offset, '.');

Loading…
Cancel
Save