Subject: | not quoting strings when data has been sorted numerically before being passed to JSON::Syck::Dump |
Note how strings are treated, even with a string based sort:
hal9000:~ dmuey$ perl -MJSON::Syck -e 'print
JSON::Syck::Dump(\@ARGV)."\n";print JSON::Syck::Dump([sort { $a cmp $b }
@ARGV])."\n";print JSON::Syck::Dump(\@ARGV)."\n";' 2 1 Howdy
["2","1","Howdy"]
["1","2","Howdy"]
["2","1","Howdy"]
hal9000:~ dmuey$
Now compare that to when the data is passed through a numeric sort prior
to JSON-ification:
hal9000:~ dmuey$ perl -MJSON::Syck -e 'print
JSON::Syck::Dump(\@ARGV)."\n";print JSON::Syck::Dump([sort { $a <=> $b }
@ARGV])."\n";print JSON::Syck::Dump(\@ARGV)."\n";' 2 1 Howdy
["2","1","Howdy"]
[Howdy,1,2]
[2,1,Howdy]
hal9000:~ dmuey$
JSON::Syck forever treats it as an integer and does not quote it! That
results in broken JSON ...
rebuilding YAML::Syck 1.07 with the attached patch applied creates a
global that makes it quote everything.
A better solution is to probably get it to quote the value as
appropriate to what it is instead ...
Here is the output when the variable added via the patch is set to true:
hal9000:~ dmuey$ perl -MJSON::Syck -e '$JSON::Syck::PreferString=1;print
JSON::Syck::Dump(\@ARGV)."\n";print JSON::Syck::Dump([sort { $a cmp $b }
@ARGV])."\n";print JSON::Syck::Dump(\@ARGV)."\n";' 2 1 Howdy
["2","1","Howdy"]
["1","2","Howdy"]
["2","1","Howdy"]
hal9000:~ dmuey$ perl -MJSON::Syck -e '$JSON::Syck::PreferString=1;print
JSON::Syck::Dump(\@ARGV)."\n";print JSON::Syck::Dump([sort { $a <=> $b }
@ARGV])."\n";print JSON::Syck::Dump(\@ARGV)."\n";' 2 1 Howdy
["2","1","Howdy"]
["Howdy","1","2"]
["2","1","Howdy"]
hal9000:~ dmuey$
Subject: | YAML-Syck.patch |
diff -ruN YAML-Syck-1.07/perl_common.h YAML-Syck-1.07.fixed/perl_common.h
--- YAML-Syck-1.07/perl_common.h 2008-04-19 14:08:31.000000000 -0500
+++ YAML-Syck-1.07.fixed/perl_common.h 2009-10-05 14:33:00.000000000 -0500
@@ -36,6 +36,7 @@
char* tag;
char dump_code;
bool implicit_binary;
+ bool prefer_string;
};
struct parser_xtra {
diff -ruN YAML-Syck-1.07/perl_syck.h YAML-Syck-1.07.fixed/perl_syck.h
--- YAML-Syck-1.07/perl_syck.h 2008-06-08 12:53:09.000000000 -0500
+++ YAML-Syck-1.07.fixed/perl_syck.h 2009-10-05 14:35:27.000000000 -0500
@@ -740,6 +740,7 @@
SV* sv = (SV*)data;
struct emitter_xtra *bonus = (struct emitter_xtra *)e->bonus;
char* tag = bonus->tag;
+ char prefer_string = bonus->prefer_string;
svtype ty = SvTYPE(sv);
#ifndef YAML_IS_JSON
char dump_code = bonus->dump_code;
@@ -860,7 +861,8 @@
/* emit an undef (typically pointed from a blesed SvRV) */
syck_emit_scalar(e, OBJOF("str"), scalar_plain, 0, 0, 0, NULL_LITERAL, NULL_LITERAL_LENGTH);
}
- else if (SvNIOKp(sv) && (sv_len(sv) != 0)) {
+ else if ( (!prefer_string || (sv_len(sv) == 0) ) && SvNIOKp(sv) && (sv_len(sv) != 0) ) {
+ /* if prefer_string is on only emit */
/* emit a number with a stringified version */
syck_emit_scalar(e, OBJOF("str"), SCALAR_NUMBER, 0, 0, 0, SvPV_nolen(sv), sv_len(sv));
}
@@ -1074,6 +1076,7 @@
SV *headless = GvSV(gv_fetchpv(form("%s::Headless", PACKAGE_NAME), TRUE, SVt_PV));
SV *implicit_unicode = GvSV(gv_fetchpv(form("%s::ImplicitUnicode", PACKAGE_NAME), TRUE, SVt_PV));
SV *implicit_binary = GvSV(gv_fetchpv(form("%s::ImplicitBinary", PACKAGE_NAME), TRUE, SVt_PV));
+ SV *prefer_string = GvSV(gv_fetchpv(form("%s::PreferString", PACKAGE_NAME), TRUE, SVt_PV));
SV *use_code = GvSV(gv_fetchpv(form("%s::UseCode", PACKAGE_NAME), TRUE, SVt_PV));
SV *dump_code = GvSV(gv_fetchpv(form("%s::DumpCode", PACKAGE_NAME), TRUE, SVt_PV));
SV *sortkeys = GvSV(gv_fetchpv(form("%s::SortKeys", PACKAGE_NAME), TRUE, SVt_PV));
@@ -1111,6 +1114,7 @@
*(bonus.tag) = '\0';
bonus.dump_code = SvTRUE(use_code) || SvTRUE(dump_code);
bonus.implicit_binary = SvTRUE(implicit_binary);
+ bonus.prefer_string = SvTRUE(prefer_string);
emitter->bonus = &bonus;
syck_emitter_handler( emitter, PERL_SYCK_EMITTER_HANDLER );