struct sr_java_frame * sr_java_frame_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "frame")) return NULL; struct sr_java_frame *result = sr_java_frame_new(); bool success = JSON_READ_STRING(root, "name", &result->name) && JSON_READ_STRING(root, "file_name", &result->file_name) && JSON_READ_UINT32(root, "file_line", &result->file_line) && JSON_READ_STRING(root, "class_path", &result->class_path) && JSON_READ_BOOL(root, "is_native", &result->is_native) && JSON_READ_BOOL(root, "is_exception", &result->is_exception) && JSON_READ_STRING(root, "message", &result->message); if (!success) { sr_java_frame_free(result); return NULL; } return result; }
struct sr_operating_system * sr_operating_system_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "operating system")) return NULL; struct sr_operating_system *result = sr_operating_system_new(); bool success = JSON_READ_STRING(root, "name", &result->name) && JSON_READ_STRING(root, "version", &result->version) && JSON_READ_STRING(root, "architecture", &result->architecture) && JSON_READ_UINT64(root, "uptime", &result->uptime); /* desktop is optional - failure is not fatal */ JSON_READ_STRING(root, "desktop", &result->desktop); /* variant is optional - failure is not fatal */ JSON_READ_STRING(root, "variant", &result->variant); if (!success) { sr_operating_system_free(result); return NULL; } return result; }
struct sr_python_frame * sr_python_frame_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "frame")) return NULL; struct sr_python_frame *result = sr_python_frame_new(); struct sr_json_value *val; /* Source file name / special file */ if ((val = json_element(root, "file_name"))) { if (!JSON_CHECK_TYPE(val, SR_JSON_STRING, "file_name")) goto fail; result->special_file = false; result->file_name = sr_strdup(val->u.string.ptr); } else if ((val = json_element(root, "special_file"))) { if (!JSON_CHECK_TYPE(val, SR_JSON_STRING, "special_file")) goto fail; result->special_file = true; result->file_name = sr_strdup(val->u.string.ptr); } /* Function name / special function. */ if ((val = json_element(root, "function_name"))) { if (!JSON_CHECK_TYPE(val, SR_JSON_STRING, "function_name")) goto fail; result->special_function = false; result->function_name = sr_strdup(val->u.string.ptr); } else if ((val = json_element(root, "special_function"))) { if (!JSON_CHECK_TYPE(val, SR_JSON_STRING, "special_function")) goto fail; result->special_function = true; result->function_name = sr_strdup(val->u.string.ptr); } bool success = JSON_READ_STRING(root, "line_contents", &result->line_contents) && JSON_READ_UINT32(root, "file_line", &result->file_line); if (!success) goto fail; return result; fail: sr_python_frame_free(result); return NULL; }
struct sr_core_stacktrace * sr_core_stacktrace_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "stacktrace")) return NULL; struct sr_core_stacktrace *result = sr_core_stacktrace_new(); bool success = JSON_READ_UINT16(root, "signal", &result->signal) && JSON_READ_STRING(root, "executable", &result->executable) && JSON_READ_BOOL(root, "only_crash_thread", &result->only_crash_thread); if (!success) goto fail; /* Read threads. */ struct sr_json_value *stacktrace = json_element(root, "stacktrace"); if (stacktrace) { if (!JSON_CHECK_TYPE(stacktrace, SR_JSON_ARRAY, "stacktrace")) goto fail; struct sr_json_value *json_thread; FOR_JSON_ARRAY(stacktrace, json_thread) { struct sr_core_thread *thread = sr_core_thread_from_json(json_thread, error_message); if (!thread) goto fail; struct sr_json_value *crash_thread = json_element(json_thread, "crash_thread"); if (crash_thread) { if (!JSON_CHECK_TYPE(crash_thread, SR_JSON_BOOLEAN, "crash_thread")) { sr_core_thread_free(thread); goto fail; } if (crash_thread->u.boolean) result->crash_thread = thread; } result->threads = sr_core_thread_append(result->threads, thread); } } return result; fail: sr_core_stacktrace_free(result); return NULL; }
struct sr_python_stacktrace * sr_python_stacktrace_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "stacktrace")) return NULL; struct sr_python_stacktrace *result = sr_python_stacktrace_new(); /* Exception name. */ if (!JSON_READ_STRING(root, "exception_name", &result->exception_name)) goto fail; /* Frames. */ struct sr_json_value *stacktrace = json_element(root, "stacktrace"); if (stacktrace) { if (!JSON_CHECK_TYPE(stacktrace, SR_JSON_ARRAY, "stacktrace")) goto fail; struct sr_json_value *frame_json; FOR_JSON_ARRAY(stacktrace, frame_json) { struct sr_python_frame *frame = sr_python_frame_from_json(frame_json, error_message); if (!frame) goto fail; result->frames = sr_python_frame_append(result->frames, frame); } } return result; fail: sr_python_stacktrace_free(result); return NULL; }
struct sr_koops_stacktrace * sr_koops_stacktrace_from_json(struct sr_json_value *root, char **error_message) { if (!JSON_CHECK_TYPE(root, SR_JSON_OBJECT, "stacktrace")) return NULL; struct sr_koops_stacktrace *result = sr_koops_stacktrace_new(); /* Kernel version. */ if (!JSON_READ_STRING(root, "version", &result->version)) goto fail; /* Raw oops text. */ if (!JSON_READ_STRING(root, "raw_oops", &result->raw_oops)) goto fail; /* Kernel taint flags. */ struct sr_json_value *taint_flags = json_element(root, "taint_flags"); if (taint_flags) { if (!JSON_CHECK_TYPE(taint_flags, SR_JSON_ARRAY, "taint_flags")) goto fail; struct sr_json_value *flag_json; FOR_JSON_ARRAY(taint_flags, flag_json) { if (!JSON_CHECK_TYPE(flag_json, SR_JSON_STRING, "taint flag")) goto fail; for (struct sr_taint_flag *f = sr_flags; f->name; f++) { if (0 == strcmp(f->name, flag_json->u.string.ptr)) { *(bool *)((void *)result + f->member_offset) = true; break; } } /* XXX should we do something if nothing is set? */ } } /* Modules. */ struct sr_json_value *modules = json_element(root, "modules"); if (modules) { if (!JSON_CHECK_TYPE(modules, SR_JSON_ARRAY, "modules")) goto fail; unsigned i = 0; size_t allocated = 128; result->modules = sr_malloc_array(allocated, sizeof(char*)); struct sr_json_value *mod_json; FOR_JSON_ARRAY(modules, mod_json) { if (!JSON_CHECK_TYPE(mod_json, SR_JSON_STRING, "module")) goto fail; /* need to keep the last element for NULL terminator */ if (i+1 == allocated) { allocated *= 2; result->modules = sr_realloc(result->modules, allocated); } result->modules[i] = sr_strdup(mod_json->u.string.ptr); i++; } result->modules[i] = NULL; } /* Frames. */ struct sr_json_value *frames = json_element(root, "frames"); if (frames) { if (!JSON_CHECK_TYPE(frames, SR_JSON_ARRAY, "frames")) goto fail; struct sr_json_value *frame_json; FOR_JSON_ARRAY(frames, frame_json) { struct sr_koops_frame *frame = sr_koops_frame_from_json(frame_json, error_message); if (!frame) goto fail; result->frames = sr_koops_frame_append(result->frames, frame); } } return result; fail: sr_koops_stacktrace_free(result); return NULL; }