diff --git a/src/Interval.cpp b/src/Interval.cpp index 1d83c6cd..5d82566a 100644 --- a/src/Interval.cpp +++ b/src/Interval.cpp @@ -89,7 +89,7 @@ std::string Interval::serialize () const if (! annotation.empty ()) { out << (_tags.empty () ? " #" : "") - << " # \"" << annotation << "\""; + << " # \"" << escape (annotation, '"') << "\""; } return out.str (); @@ -138,7 +138,7 @@ std::string Interval::json () const out << ','; } - out << "\"annotation\":\"" << annotation << "\""; + out << "\"annotation\":\"" << escape (annotation, '"') << "\""; } out << "}"; diff --git a/test/annotate.t b/test/annotate.t index 9d97db07..e08cb6c8 100755 --- a/test/annotate.t +++ b/test/annotate.t @@ -178,6 +178,18 @@ class TestAnnotate(TestCase): self.assertEquals(len(j), 1) self.assertClosedInterval(j[0], expectedAnnotation="foo") + def test_annotate_with_embedded_quotes(self): + """Call 'annotate' with embedded quotes""" + now_utc = datetime.now().utcnow() + one_hour_before_utc = now_utc - timedelta(hours=1) + + self.t("track {:%Y-%m-%dT%H:%M:%S}Z - {:%Y-%m-%dT%H:%M:%S}Z".format(one_hour_before_utc, now_utc)) + self.t("annotate @1 'bar \"foo\" bar'") + + j = self.t.export() + + self.assertEquals(len(j), 1) + self.assertClosedInterval(j[0], expectedAnnotation='bar "foo" bar') if __name__ == "__main__": from simpletap import TAPTestRunner