00001
00116 * ...
00117 * writer->setProps(props);
00118 * @endcode
00119 *
00120 * You could set the playlist's creation time like this:
00121 *
00122 * @code
00123 * XspfDateTime dateTime(2006, 8, 28, 11, 30, 11, 1, 0);
00124 * props.lendDate(&dateTime);
00125 * @endcode
00126 *
00127 * Similar to the steal/get duality introduced earlier you have to choose
00128 * between the "lend" and "give" function family when setting
00129 * information. The whole thing again is only about memory ownership:
00130 * The lend functions do not transfer ownership, the give functions do.
00131 * The give family also offers to copy the memory or to assign
00132 * existing memory. To make this more clear calling
00133 *
00134 * @code
00135 * props.giveTitle(_PT("Some title"), XspfData::TRANSFER);
00136 * @endcode
00137 *
00138 * would be a bad idea since the memory would not be copied but still
00139 * be deleted on destruction. You should use
00140 *
00141 * @code
00142 * props.lendTitle(_PT("Some title"));
00143 * @endcode
00144 *
00145 * in this case.
00146 *
00147 * Back to the writer: When you have created a XspfWriter instance
00148 * you can let it write its content to file:
00149 *
00150 * @code
00151 * writer.writeFile(_PT("TEST.xspf"));
00152 * @endcode
00153 *
00154 * In this case that would make a valid playlist without any tracks.
00155 * So before writing the playlist you should add your tracks:
00156 *
00157 * @code
00158 * XspfTrack track;
00159 * ...
00160 * track.lendCreator(_PT("Breaking Benjamin"));
00161 * ...
00162 * writer.addTrack(track);
00163 * @endcode
00164 *
00165 * When addTrack() is called the track information is appended to an
00166 * internal buffer which is written when writeFile() is called eventually.
00167 * You can add the same track several times and you can call writeFile()
00168 * several times to write the same playlist to several files;
00169 * what you cannot do is add more tracks after writing the playlist
00170 * to a file: You will have to call reset() to start over with an empty track list first.
00171 *
00172 *
00173 * @section SEC_MALICIOUS Handling malicious XML
00174 * Let us assume you are using libxspf to power some kind of web service with XSPF
00175 * reading cabilities. Let us further assume this service can accept XSPF input
00176 * from a user. Due to the nature of XML your service would be vulnerable to
00177 * an <i>XML entity explosion attack</i>. What this means is that a rather small
00178 * malicious XML file can make the running XML processor a huge amount of memory
00179 * or CPU time or both.
00180 *
00181 * A popular example is <i>billion laughs</i>, of which an XSPF version
00182 * could look like this:
00183 *
00184 * @code
00185 * <?xml version="1.0"?>
00186 * <!DOCTYPE billion [
00187 * <!ELEMENT billion (#PCDATA)>
00188 * <!ENTITY laugh0 "ha">
00189 * <!ENTITY laugh1 "&laugh0;&laugh0;">
00190 * <!ENTITY laugh2 "&laugh1;&laugh1;">
00191 * <!ENTITY laugh3 "&laugh2;&laugh2;">
00192 * <!ENTITY laugh4 "&laugh3;&laugh3;">
00193 * ...
00194 * <!ENTITY laugh30 "&laugh29;&laugh29;">
00195 * ]>
00196 * <playlist version="1" xmlns="http://xspf.org/ns/0/">
00197 * <title>&laugh30;</title>
00198 * <trackList />
00199 * </playlist>
00200 * @endcode
00201 *
00202 * With malicious XML detection enabled, libxspf sets certain limits
00203 * to the values of entities. Currently these limits are:
00204 * - Length of entity values
00205 * - Sum of lookups per entity value
00206 * - Lookup depth per entity value
00207 *
00208 * The above <i>billion laughs</i> example has these metrics:
00209 * <table border="0">
00210 * <tr><td class="indexkey">Entity</td><td class="indexkey">Length</td><td class="indexkey">Lookup Sum</td><td class="indexkey">Lookup Depth</td></tr>
00211 * <tr><td class="indexvalue">laugh0</td><td class="indexvalue">2</td><td class="indexvalue">0</td><td class="indexvalue">0</td></tr>
00212 * <tr><td class="indexvalue">laugh1</td><td class="indexvalue">4</td><td class="indexvalue">2</td><td class="indexvalue">1</td></tr>
00213 * <tr><td class="indexvalue">laugh2</td><td class="indexvalue">8</td><td class="indexvalue">6</td><td class="indexvalue">2</td></tr>
00214 * <tr><td class="indexvalue">laugh3</td><td class="indexvalue">16</td><td class="indexvalue">14</td><td class="indexvalue">3</td></tr>
00215 * <tr><td class="indexvalue">laugh4</td><td class="indexvalue">32</td><td class="indexvalue">30</td><td class="indexvalue">4</td></tr>
00216 * <tr><td class="indexvalue">...</td><td class="indexvalue">...</td><td class="indexvalue">...</td><td class="indexvalue">...</td></tr>
00217 * <tr><td class="indexvalue">laugh30</td><td class="indexvalue">2,147,483,648</td><td class="indexvalue">2,147,483,646</td><td class="indexvalue">30</td></tr>
00218 * <tr><td class="indexvalue">laugh<i>n</i></td><td class="indexvalue">2^(<i>n</i>+1)</td><td class="indexvalue">2^(<i>n</i>+1)-2</td><td class="indexvalue"><i>n</i></td></tr>
00219 * </table>
00220 *
00221 * Looking at <i>laugh30</i> all three values are much higher than those of most peaceful XML files.
00222 * Through calling
00223 *
00224 * @code
00225 * reader.enableMaliciousXmlDetection(true);
00226 * @endcode
00227 *
00228 * you can make a XspfReader instance protocol these metrics in order to detect
00229 * malicious XML. Also, all of these metrics can be limited and adjusted individually;
00230 * for instance this is how to limit the lookup depth to a maximum of 2:
00231 *
00232 * @code
00233 * reader.limitLookupDepthPerEntityValue(true);
00234 * reader.setMaxLookupDepthPerEntityValue(2);
00235 * @endcode
00236 *
00237 * @attention
00238 * Malicious XML detection can only work for you if you are clear
00239 * about your software's use cases. Tune the detection parameters to
00240 * what you have to allow and reject everything else.
00241 */