On Sat, Mar 31, 2018 at 11:01:15AM +0200, Peter Krempa wrote: > Rather than depending on yajl bits for creating the JSON structure > replace it by few virBuffer bits. This will make the JSON formatter > libary agnostic. I don't think this is a good idea as it means we have to reinvent the wheel to ensure that we are correctly formatting & escaping JSON. This patch gets escaping wrong which illustrates the point :-( It has also discarded the utf8 validation that the old code did. > +static void > +virJSONValueToStringAddString(virBufferPtr buf, > + virJSONValuePtr string) > +{ > + const char *t; > + > + virBufferAddLit(buf, "\""); > + > + for (t = string->data.string; *t; t++) { > + switch (*t) { > + case '"': > + virBufferAddLit(buf, "\\\""); > + break; > + case '\\': > + virBufferAddLit(buf, "\\\\"); > + break; > + case '\n': > + virBufferAddLit(buf, "\\n"); > + break; > + case '\t': > + virBufferAddLit(buf, "\\t"); > + break; Missing \r, \f, \b. Also missing hex escaping of non printable characters. > + default: > + virBufferAdd(buf, t, 1); > + break; > + } > + } > + > + virBufferAddLit(buf, "\""); > +} > + > + > +#define VIR_JSON_PRETTY_NEWLINE \ > + if (pretty) \ > + virBufferAddLit(buf, "\n") > > static int > virJSONValueToStringOne(virJSONValuePtr object, > - yajl_gen g) > + virBufferPtr buf, > + bool pretty) > { > size_t i; > > - VIR_DEBUG("object=%p type=%d gen=%p", object, object->type, g); > - > - switch (object->type) { > + switch ((virJSONType) object->type) { > case VIR_JSON_TYPE_OBJECT: > - if (yajl_gen_map_open(g) != yajl_gen_status_ok) > - return -1; > + virBufferAddLit(buf, "{"); > + VIR_JSON_PRETTY_NEWLINE; > + virBufferAdjustIndent(buf, 2); > + > for (i = 0; i < object->data.object.npairs; i++) { > - if (yajl_gen_string(g, > - (unsigned char *)object->data.object.pairs[i].key, > - strlen(object->data.object.pairs[i].key)) > - != yajl_gen_status_ok) > - return -1; > - if (virJSONValueToStringOne(object->data.object.pairs[i].value, g) < 0) > + virBufferStrcat(buf, "\"", object->data.object.pairs[i].key, "\":", NULL); Missing escaping of key. > + > + if (pretty) > + virBufferAddLit(buf, " "); > + > + if (virJSONValueToStringOne(object->data.object.pairs[i].value, > + buf, pretty) < 0) > return -1; > + > + if (i != object->data.object.npairs - 1) { > + virBufferAddLit(buf, ","); > + VIR_JSON_PRETTY_NEWLINE; > + } > } > - if (yajl_gen_map_close(g) != yajl_gen_status_ok) > - return -1; > + > + virBufferAdjustIndent(buf, -2); > + VIR_JSON_PRETTY_NEWLINE; > + virBufferAddLit(buf, "}"); > break; > + > case VIR_JSON_TYPE_ARRAY: > - if (yajl_gen_array_open(g) != yajl_gen_status_ok) > - return -1; > + virBufferAddLit(buf, "["); > + VIR_JSON_PRETTY_NEWLINE; > + virBufferAdjustIndent(buf, 2); > + > for (i = 0; i < object->data.array.nvalues; i++) { > - if (virJSONValueToStringOne(object->data.array.values[i], g) < 0) > + if (virJSONValueToStringOne(object->data.array.values[i], buf, pretty) < 0) > return -1; > + > + if (i != object->data.array.nvalues - 1) { > + virBufferAddLit(buf, ","); > + VIR_JSON_PRETTY_NEWLINE; > + } > } > - if (yajl_gen_array_close(g) != yajl_gen_status_ok) > - return -1; > + > + virBufferAdjustIndent(buf, -2); > + VIR_JSON_PRETTY_NEWLINE; > + virBufferAddLit(buf, "]"); > break; > > case VIR_JSON_TYPE_STRING: > - if (yajl_gen_string(g, (unsigned char *)object->data.string, > - strlen(object->data.string)) != yajl_gen_status_ok) > - return -1; > + virJSONValueToStringAddString(buf, object); > break; > > case VIR_JSON_TYPE_NUMBER: > - if (yajl_gen_number(g, object->data.number, > - strlen(object->data.number)) != yajl_gen_status_ok) > - return -1; > + virBufferAdd(buf, object->data.number, -1); > break; > > case VIR_JSON_TYPE_BOOLEAN: > - if (yajl_gen_bool(g, object->data.boolean) != yajl_gen_status_ok) > - return -1; > + if (object->data.boolean) > + virBufferAddLit(buf, "true"); > + else > + virBufferAddLit(buf, "false"); > break; > > case VIR_JSON_TYPE_NULL: > - if (yajl_gen_null(g) != yajl_gen_status_ok) > - return -1; > + virBufferAddLit(buf, "null"); > break; > > default: > + virReportEnumRangeError(virJSONType, object->type); > return -1; > } > > return 0; > } Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list