Skip to content
Browse files

Added proper handling of ]]> occurring in a CDATA section (DXML-12)

  • Loading branch information...
1 parent df7324d commit cf810dc81857623442fcdf422172efd33af5bf44 @senior senior committed Jan 8, 2013
Showing with 33 additions and 3 deletions.
  1. +14 −1 src/main/clojure/clojure/data/xml.clj
  2. +19 −2 src/test/clojure/clojure/data/xml/test_emit.clj
View
15 src/main/clojure/clojure/data/xml.clj
@@ -49,12 +49,25 @@
(.writeStartElement writer "" qname (or nspace ""))
(write-attributes (:attrs event) writer)))
+(defn str-empty? [s]
+ (or (nil? s)
+ (= s "")))
+
+(defn emit-cdata [^String cdata-str writer]
+ (when-not (str-empty? cdata-str)
+ (let [idx (.indexOf cdata-str "]]>")]
+ (if (= idx -1)
+ (.writeCData writer cdata-str )
+ (do
+ (.writeCData writer (subs cdata-str 0 idx))
+ (recur (subs cdata-str (+ idx 3)) writer))))))
@weissjeffm
weissjeffm added a note Jun 19, 2013

This doesn't work.

user> (xml/indent-str (xml/sexp-as-element [:pre [:-cdata "foo]]>bar"]]))
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><pre><![CDATA[foo]]><![CDATA[bar]]></pre>\n"

What's being emitted here is cdata for foobar not foo]]>bar.

What needs to be done is break up the delimiter ]]> so that the first two characters are in one cdata block, and the last character is in the next block.

I'll submit a patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+
(defn emit-event [event ^javax.xml.stream.XMLStreamWriter writer]
(case (:type event)
:start-element (emit-start-tag event writer)
:end-element (.writeEndElement writer)
:chars (.writeCharacters writer (:str event))
- :cdata (.writeCData writer (:str event))
+ :cdata (emit-cdata (:str event) writer)
:comment (.writeComment writer (:str event))))
(defprotocol EventGeneration
View
21 src/test/clojure/clojure/data/xml/test_emit.clj
@@ -78,10 +78,27 @@
(emit (element :foo) *out* :encoding "ISO-8859-1"))))))
(deftest emitting-cdata
+ (testing "basic cdata"
+ (is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<cdata-stuff><![CDATA[<goes><here>]]></cdata-stuff>")
+ (emit-str (element :cdata-stuff {}
+ (cdata "<goes><here>"))))))
+ (testing "cdata with ]]> chars"
+ (is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<cdata-stuff><![CDATA[<goes><here>]]><![CDATA[<and><here>]]></cdata-stuff>")
+ (emit-str (element :cdata-stuff {}
+ (cdata "<goes><here>]]><and><here>"))))))
+ (testing "cdata with ]]> chars and newlines"
+ (is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<cdata-stuff><![CDATA[<goes><here>\n\n\n]]><![CDATA[<and><here>]]></cdata-stuff>")
+ (emit-str (element :cdata-stuff {}
+ (cdata "<goes><here>\n\n\n]]><and><here>")))))))
+
+(deftest emitting-cdata-with-embedded-end
(is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- "<cdata-stuff><![CDATA[<goes><here>]]></cdata-stuff>")
+ "<cdata-stuff><![CDATA[<goes><here>]]><![CDATA[<and><here>]]></cdata-stuff>")
(emit-str (element :cdata-stuff {}
- (cdata "<goes><here>"))))) )
+ (cdata "<goes><here>]]><and><here>"))))) )
(deftest emitting-comment
(is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"

0 comments on commit cf810dc

Please sign in to comment.
Something went wrong with that request. Please try again.