4037b582757f86eed1c5559eca9ccc7af85c1496 braney Fri Aug 21 10:00:49 2026 -0700 lib: add htmlSanitize, an allowlist filter for HTML written elsewhere, refs #38126 htmlSanitize() takes a piece of HTML and returns a copy holding only the elements, attributes and style properties on its lists. An element on the keep list survives with its allowed attributes. A short list of elements that carry nothing for a reader, script and style and form among them, is dropped along with its contents. Every other element loses its tag and keeps its text, so a whole document that somebody saved and pasted in comes out as the article it was meant to be. The lists come from a survey of all 5390 description pages reachable from the public hub list, so they are sized to what hubs actually write. The style attribute is filtered a property at a time, and href and src are checked for a scheme we do not print, after decoding entities and padding. An iframe is kept only when it plays a video from one of a few hosts, and then with a sandbox attribute. htmlSanitizeReport() returns the same copy plus a list of one-line messages naming what came out, for hubCheck to show a hub author. The tokenizer is hand written and forgiving. It never aborts and always returns something, because the HTML it will be handed is often broken. lib/htmlPage.c cannot be reused for this: its parser aborts on bad input. diff --git src/lib/tests/makefile src/lib/tests/makefile index 4edefea0e3e..1e47ac21198 100644 --- src/lib/tests/makefile +++ src/lib/tests/makefile @@ -1,46 +1,53 @@ kentSrc = ../.. include ../../inc/common.mk MYLIBDIR = ../../lib/${MACHTYPE} MYLIBS = ${MYLIBDIR}/jkweb.a BIN_DIR = bin/${MACHTYPE} pipelineTester = ${BIN_DIR}/pipelineTester -test: errCatchTest htmlPageTest htmlExpandUrlTest pipelineTests dyStringTest \ +test: errCatchTest htmlPageTest htmlExpandUrlTest htmlSanitizeTest pipelineTests dyStringTest \ mimeTests base64Tests quotedPTests safeTest hashTest fetchUrlTest gff3Test \ tabixTest vcfTest hacTreeTest mmHashTest testSumDoubles jsonQueryTest \ dnaCodonTest rm -r output fetchUrlTest testSumDoubles @echo tested all mkdirs: ${MKDIR} output ${BIN_DIR} testSumDoubles: testSumDoubles.o ${MYLIBS} @${MKDIR} $(dir $@) ${CC} ${COPT} -o ./testSumDoubles testSumDoubles.o ${MYLIBS} ${L} dnaCodonTest: dnaCodonTest.o ${MYLIBS} mkdirs @${MKDIR} $(dir $@) ${CC} ${COPT} -o ${BIN_DIR}/dnaCodonTest dnaCodonTest.o ${MYLIBS} ${L} ${STRIP} ${BIN_DIR}/dnaCodonTest${EXE} ${BIN_DIR}/dnaCodonTest > output/dnaCodonTest diff expected/dnaCodonTest output/dnaCodonTest +htmlSanitizeTest: htmlSanitizeTest.o ${MYLIBS} mkdirs + @${MKDIR} $(dir $@) + ${CC} ${COPT} -o ${BIN_DIR}/htmlSanitizeTest htmlSanitizeTest.o ${MYLIBS} ${L} + ${STRIP} ${BIN_DIR}/htmlSanitizeTest${EXE} + ${BIN_DIR}/htmlSanitizeTest > output/htmlSanitizeTest + diff expected/htmlSanitizeTest output/htmlSanitizeTest + errCatchTest: errCatchTest.o ${MYLIBS} mkdirs @${MKDIR} $(dir $@) ${CC} ${COPT} -o ${BIN_DIR}/errCatchTest errCatchTest.o ${MYLIBS} ${L} ${STRIP} ${BIN_DIR}/errCatchTest${EXE} ${BIN_DIR}/errCatchTest secret > output/errCatch.good diff expected/errCatch.good output/errCatch.good ${BIN_DIR}/errCatchTest bad > output/errCatch.bad diff expected/errCatch.bad output/errCatch.bad htmlExpandUrlTest: htmlExpandUrlTest.o ${MYLIBS} mkdirs @${MKDIR} $(dir $@) ${CC} ${COPT} -o ${BIN_DIR}/htmlExpandUrlTest htmlExpandUrlTest.o ${MYLIBS} ${L} ${STRIP} ${BIN_DIR}/htmlExpandUrlTest${EXE} ${BIN_DIR}/htmlExpandUrlTest > output/htmlExpandUrlTest 2>&1 diff expected/htmlExpandUrlTest output/htmlExpandUrlTest