ScroogeXHTML for Object Pascal 10.0 — Release Candidate 1
ScroogeXHTML is the Object Pascal component that converts RTF (rich text) files, strings, and streams into clean HTML5, XHTML, or plain text. It ships as source, has no UI dependencies beyond the RTL/VCL/LCL, and builds on Delphi 2009+ and Free Pascal / Lazarus.
Version 10.0 is a robustness, security, and performance release. It also retires a large amount of legacy output-format code. Here are the highlights.
Leaner output: HTML5 and XHTML 1.0 Strict only
All deprecated output document types have been removed: HTML 3.2/Flex, HTML 4.01 Transitional/Strict, XHTML 1.0 Transitional, XHTML Basic 1.0, XHTML Mobile Profile 1.0, and XHTML 1.1. TDocumentType is now just dtHTML_50 and dtXHTML_10_Strict, and the SCROOGE_DEPRECATED_DOCUMENT_TYPES conditional define is gone. If you were already producing HTML5 or XHTML 1.0 Strict output, nothing changes for you — you simply get a smaller, more focused codebase.
Hardening against malformed and adversarial RTF
If you convert RTF that you did not create yourself — for example through the web demo, or a server-side conversion endpoint — this is the important release. Version 10.0 fixes a series of ways that a truncated, malformed, or hostile document could hang the parser, exhaust memory, or crash the conversion:
- XSS fix: anchor
idand hyperlinkhrefattribute values are now HTML-escaped in the generated output. - Infinite-loop fix: a document whose
\clw/\clfts/\trw/\trftskeyword was not followed by another control word could hangTSxReader.SkipWord. - RTF group nesting is now bounded (
MAX_RTF_GROUP_DEPTH). A long run of{characters could previously grow the parser’s property stack until memory ran out; nesting past the limit now raisesESxRtfGroupNestingError. - Control-word and parameter length are now bounded (
MAX_RTF_CONTROL_WORD_LEN/MAX_RTF_PARAM_DIGITS). \binbyte count hardened: a missing parameter no longer inherits a stale value, and a negative or out-of-range count can no longer make the parser consume the rest of the document as binary data.- Malformed color tables:
RGBToHexnow clamps out-of-range or negative\red/\green/\bluevalues instead of emitting a malformed hex color. - Malformed picture data: a non-hex character in
\pictdata is now skipped rather than aborting the whole conversion withEConvertError. - Symbol-font range fix: an out-of-bounds table read in
SymbolToUnicodefor the U+F000..U+F040 / U+F0FF+ range is fixed; such code points now pass through unchanged.
Faster conversion of large documents
The reader, writer, and translator hot paths no longer use O(n²) string concatenation — they build output with TStringBuilder. Large documents convert substantially faster as a result.
Better list fidelity
- Ordered-list numbering styles (roman numerals, letters, and so on) from the RTF
\listtablenow render as an<ol type="...">attribute (HTML5) or a CSSlist-style-type(XHTML), instead of always falling back to a bare<ol>. - List-override number-type resolution no longer discards non-bullet override styles.
Embedded pictures are a real DOM node
Embedded pictures now have a genuine DOM node type (TPictureNode / ISimpleDomPictureNode), replacing the previous approach of storing pre-rendered HTML inside a text node.
More precise hyperlink detection
Attribute-based hyperlink auto-detection has been removed. Underlined blue text is no longer treated as a link just because it looks like one — only actual RTF HYPERLINK fields are converted.
Tooling and quality
- Headless test-runner scripts for both compilers:
run-delphi.cmdandrun-fpc.cmd/run-fpc.sh. - Headless DUnit runs (
-text-mode) can no longer hang on a memory-leak dialog with no one present to dismiss it. - Doxygen warnings fixed; more unit tests added.
About this Release Candidate
10.0-RC1 is a release candidate, not the final 10.0 release. We are publishing it now so that you can test it against your own RTF documents and integrations before the final build.
Suggestions are welcome. If you find a regression, a document that converts differently than it did in 9.x, or anything else worth changing before the final release, please get in touch: info@habarisoft.com.
Registered users can download 10.0-RC1 now using the download link on the ScroogeXHTML web site.
Links
- Web site: https://www.scroogexhtml.com/object_pascal.html
- Demo download: https://www.habarisoft.com/scroogexhtml/10.0-RC1/ScroogeXHTMLDemo.zip
- Getting Started (PDF): https://www.habarisoft.com/scroogexhtml/10.0-RC1/docs/ScroogeXHTMLGettingStarted.pdf
- API documentation: https://www.habarisoft.com/scroogexhtml/10.0-RC1/docs/api/index.html
- Full release notes: https://www.habarisoft.com/scroogexhtml/10.0-RC1/docs/api/version.html