Fix invalid XML output due to special chars, bug1444.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Kanad Kanhere 2019-05-29 18:41:03 -04:00 committed by Wilson Snyder
parent b83b606267
commit 72eb361131
5 changed files with 83 additions and 30 deletions

View File

@ -20,6 +20,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
**** Fix real parameter assignment, bug1427. [Todd Strader]
**** Fix invalid XML output due to special chars, bug1444. [Kanad Kanhere]
* Verilator 4.014 2019-05-08

View File

@ -59,7 +59,7 @@ class EmitXmlFileVisitor : public AstNVisitor {
// Don't use to quote a filename for #include - #include doesn't \ escape.
// Duplicate in V3File - here so we can print to string
putsNoTracking("\"");
putsNoTracking(V3OutFormatter::quoteNameControls(str));
putsNoTracking(V3OutFormatter::quoteNameControls(str, V3OutFormatter::LA_XML));
putsNoTracking("\"");
}

View File

@ -847,26 +847,49 @@ void V3OutFormatter::putcNoTracking(char chr) {
putcOutput(chr);
}
string V3OutFormatter::quoteNameControls(const string& namein, V3OutFormatter::Language) {
// Encode control chars into C style escapes
string V3OutFormatter::quoteNameControls(const string& namein, V3OutFormatter::Language lang) {
// Encode control chars into output-appropriate escapes
// Reverse is V3Parse::deQuote
string out;
for (string::const_iterator pos=namein.begin(); pos!=namein.end(); ++pos) {
if (pos[0]=='\\' || pos[0]=='"') {
out += string("\\")+pos[0];
} else if (pos[0]=='\n') {
out += "\\n";
} else if (pos[0]=='\r') {
out += "\\r";
} else if (pos[0]=='\t') {
out += "\\t";
} else if (isprint(pos[0])) {
out += pos[0];
} else {
// This will also cover \a etc
// Can't use %03o as messes up when signed
char octal[10]; sprintf(octal, "\\%o%o%o", (pos[0]>>6)&3, (pos[0]>>3)&7, pos[0]&7);
out += octal;
if (lang==LA_XML) {
// Encode chars into XML string
for (string::const_iterator pos=namein.begin(); pos!=namein.end(); ++pos) {
if (pos[0]=='"') {
out += string("&quot;");
} else if (pos[0]=='\'') {
out += string("&apos;");
} else if (pos[0]=='<') {
out += string("&lt;");
} else if (pos[0]=='>') {
out += string("&gt;");
} else if (pos[0]=='&') {
out += string("&amp;");
} else if (isprint(pos[0])) {
out += pos[0];
} else {
char decimal[10]; sprintf(decimal, "&#%u;", (unsigned char)pos[0]);
out += decimal;
}
}
} else {
// Encode control chars into C style escapes
for (string::const_iterator pos=namein.begin(); pos!=namein.end(); ++pos) {
if (pos[0]=='\\' || pos[0]=='"') {
out += string("\\")+pos[0];
} else if (pos[0]=='\n') {
out += "\\n";
} else if (pos[0]=='\r') {
out += "\\r";
} else if (pos[0]=='\t') {
out += "\\t";
} else if (isprint(pos[0])) {
out += pos[0];
} else {
// This will also cover \a etc
// Can't use %03o as messes up when signed
char octal[10]; sprintf(octal, "\\%o%o%o", (pos[0]>>6)&3, (pos[0]>>3)&7, pos[0]&7);
out += octal;
}
}
}
return out;

View File

@ -31,6 +31,24 @@
<varxref fl="f32" name="value" dtype_id="6" dotted="itop"/>
<varref fl="f32" name="dotted" dtype_id="5"/>
</contassign>
<func fl="f34" name="f" dtype_id="1">
<var fl="f34" name="f" dtype_id="1" dir="output" vartype="logic" origName="f"/>
<var fl="f34" name="m" dtype_id="7" dir="input" vartype="string" origName="m"/>
<display fl="f35" displaytype="$display">
<sformatf fl="f35" name="%@" dtype_id="7">
<varref fl="f35" name="m" dtype_id="7"/>
</sformatf>
</display>
</func>
<initial fl="f38">
<begin fl="f38">
<taskref fl="f40" name="f">
<arg fl="f40">
<const fl="f40" name="&quot;&#1;&#2;&#3;&#4;&#5;&#6;&#7;&#8;&#9;&#10;&#11;&#12;&#13;&#14;&#15;&#16;&#17;&#18;&#19;&#20;&#21;&#22;&#23;&#24;&#25;&#26;&#27;&#28;&#29;&#30;&#31; !&quot;#$%&amp;&apos;()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~&#127;&#128;&#129;&#130;&#131;&#132;&#133;&#134;&#135;&#136;&#137;&#138;&#139;&#140;&#141;&#142;&#143;&#144;&#145;&#146;&#147;&#148;&#149;&#150;&#151;&#152;&#153;&#154;&#155;&#156;&#157;&#158;&#159;&#160;&#161;&#162;&#163;&#164;&#165;&#166;&#167;&#168;&#169;&#170;&#171;&#172;&#173;&#174;&#175;&#176;&#177;&#178;&#179;&#180;&#181;&#182;&#183;&#184;&#185;&#186;&#187;&#188;&#189;&#190;&#191;&#192;&#193;&#194;&#195;&#196;&#197;&#198;&#199;&#200;&#201;&#202;&#203;&#204;&#205;&#206;&#207;&#208;&#209;&#210;&#211;&#212;&#213;&#214;&#215;&#216;&#217;&#218;&#219;&#220;&#221;&#222;&#223;&#224;&#225;&#226;&#227;&#228;&#229;&#230;&#231;&#232;&#233;&#234;&#235;&#236;&#237;&#238;&#239;&#240;&#241;&#242;&#243;&#244;&#245;&#246;&#247;&#248;&#249;&#250;&#251;&#252;&#253;&#254;&#255;&quot;" dtype_id="7"/>
</arg>
</taskref>
</begin>
</initial>
</module>
<iface fl="f6" name="ifc" origName="ifc">
<var fl="f7" name="value" dtype_id="6" vartype="integer" origName="value"/>
@ -43,23 +61,24 @@
<basicdtype fl="f7" id="6" name="integer" left="31" right="0"/>
<basicdtype fl="f13" id="1" name="logic"/>
<structdtype fl="f19" id="2" name="m.my_struct">
<memberdtype fl="f20" id="7" name="clk" tag="this is clk" sub_dtype_id="8"/>
<memberdtype fl="f21" id="9" name="k" sub_dtype_id="10"/>
<memberdtype fl="f22" id="11" name="enable" tag="enable" sub_dtype_id="12"/>
<memberdtype fl="f23" id="13" name="data" tag="data" sub_dtype_id="14"/>
<memberdtype fl="f20" id="8" name="clk" tag="this is clk" sub_dtype_id="9"/>
<memberdtype fl="f21" id="10" name="k" sub_dtype_id="11"/>
<memberdtype fl="f22" id="12" name="enable" tag="enable" sub_dtype_id="13"/>
<memberdtype fl="f23" id="14" name="data" tag="data" sub_dtype_id="15"/>
</structdtype>
<basicdtype fl="f20" id="8" name="logic"/>
<basicdtype fl="f21" id="10" name="logic"/>
<basicdtype fl="f22" id="12" name="logic"/>
<basicdtype fl="f23" id="14" name="logic"/>
<basicdtype fl="f20" id="9" name="logic"/>
<basicdtype fl="f21" id="11" name="logic"/>
<basicdtype fl="f22" id="13" name="logic"/>
<basicdtype fl="f23" id="15" name="logic"/>
<ifacerefdtype fl="f28" id="3" modportname=""/>
<unpackarraydtype fl="f30" id="4" sub_dtype_id="2">
<range fl="f30">
<const fl="f30" name="32'h1" dtype_id="5"/>
<const fl="f30" name="32'h0" dtype_id="5"/>
<const fl="f30" name="32&apos;h1" dtype_id="5"/>
<const fl="f30" name="32&apos;h0" dtype_id="5"/>
</range>
</unpackarraydtype>
<refdtype fl="f30" id="15" name="my_struct" sub_dtype_id="2"/>
<refdtype fl="f30" id="16" name="my_struct" sub_dtype_id="2"/>
<basicdtype fl="f34" id="7" name="string"/>
</typetable>
</netlist>
</verilator_xml>

View File

@ -31,4 +31,13 @@ module m
wire [31:0] dotted = itop.value;
function f(input string m);
$display("%s", m);
endfunction
initial begin
// Contains all 256 characters except 0 (null character)
f("\x01\x02\x03\x04\x05\x06\a\x08\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff");
end
endmodule