int main(int argc, char** argv) { FILE* fp; if (argc > 1) { if (argv[1][0] == '-' && argv[1][1] == '-') { fp = stdin; } else { fp = fopen(argv[1], "rb"); } } else { print_help(); return 0; } ubjr_context_t* rctx = ubjr_open_file(fp); ubjr_dynamic_t dyn = ubjr_read_dynamic(rctx); ubjw_context_t* wctx = ubjw_open_file(stdout); ubjrw_write_dynamic(wctx, dyn, 1); return 0; }
static inline int64_t priv_ubjw_read_integer(ubjr_context_t* ctx) { ubjr_dynamic_t d = ubjr_read_dynamic(ctx); if (d.type >= UBJ_INT8 && d.type <= UBJ_INT64) return d.integer; return 0;//error }
bool run_test(uint32_t* hash_out) { char* data = benchmark_in_situ_copy(file_data, file_size); if (!data) return false; ubjr_context_t* src = ubjr_open_memory((uint8_t*)data, (uint8_t*)(data + file_size)); ubjr_dynamic_t dynamic = ubjr_read_dynamic(src); hash_value(&dynamic, UBJ_MIXED, 0, hash_out); ubjr_cleanup_dynamic(&dynamic); // ubjr has a bug where it leaks the userdata. it never calls the // close_cb, but even if it did, free() in memclose() is // commented out. this ugly hack frees it manually. free(((void**)src)[4]); ubjr_close_context(src); benchmark_in_situ_free(data); // ubjr_open_memory() sets NULL as the error handling callback. // I don't know how it is meant to handle errors, and it seems to // have lots of bugs (for example priv_ubjw_read_integer() returns // 0 on error, but 0 is also a valid integer.) The return value // of memread() is also never checked so if the data is truncated // it just continues using uninitialized memory, which seems to // easily throw it into an infinite loop or infinite recursion. // // For now we'll have to skip error checking, but this seems like // an unfair advantage for ubj. Data validation is fundamental // to security and it affects performance. return true; }
static inline void priv_ubjr_read_to_ptr(ubjr_context_t* ctx, uint8_t* dst, UBJ_TYPE typ) { int64_t n = 1; char *tstr; switch (typ) { case UBJ_MIXED: { *(ubjr_dynamic_t*)dst = ubjr_read_dynamic(ctx); break; } case UBJ_STRING: case UBJ_HIGH_PRECISION: { n = priv_ubjw_read_integer(ctx); } case UBJ_CHAR: { tstr = malloc(n + 1); priv_ubjr_context_read(ctx, tstr, n); tstr[n] = 0; *(ubjr_string_t*)dst = tstr; break; } case UBJ_INT8: case UBJ_UINT8: { *dst = priv_ubjr_read_1b(ctx); break; } case UBJ_INT16: { *(uint16_t*)dst = priv_ubjr_read_2b(ctx); break; } case UBJ_INT32: case UBJ_FLOAT32: { *(uint32_t*)dst = priv_ubjr_read_4b(ctx); break; } case UBJ_INT64: case UBJ_FLOAT64: { *(uint64_t*)dst = priv_ubjr_read_8b(ctx); break; } case UBJ_ARRAY: { *(ubjr_array_t*)dst = priv_ubjr_read_raw_array(ctx); break; } case UBJ_OBJECT: { *(ubjr_object_t*)dst = priv_ubjr_read_raw_object(ctx); break; } }; }