c2a6ef817930149ad6f55818fa0196d99c47e02b braney Fri Sep 11 10:40:11 2026 -0700 cheapcgi: skip a CGI pair with no =value instead of aborting, refs #38335 Both query string parsers looked for the '=' across the whole rest of the string rather than inside the current pair. A pair with no '=' in it therefore ran into the pair after it and took its value. "g-catV2&db=hg38" was stored as one variable named "g-catV2&db", so db was lost with no warning, and that corrupt name was copied on into the cart. The same pair at the end of the string had no '=' left to find and aborted the whole request, which is what the "Mangled CGI input string g-catV2" entries in the hgw1 logs were. Both parsers now find the end of the pair first, keeping the existing separator precedence ('&', then ';' for DAS), and skip a pair with no '='. A mixed "a=1;b=2&c=3" still parses the way it did. Adds lib/tests/cgiParseTest, which runs 18 query strings through both parsers. It covers the empty pair of #38185 as well. Co-Authored-By: Claude Opus 5 (1M context) diff --git src/lib/tests/makefile src/lib/tests/makefile index cfa34defdc0..2863fea0cf7 100644 --- src/lib/tests/makefile +++ src/lib/tests/makefile @@ -1,28 +1,28 @@ kentSrc = ../.. include ../../inc/common.mk MYLIBDIR = ../../lib/${MACHTYPE} MYLIBS = ${MYLIBDIR}/jkweb.a BIN_DIR = bin/${MACHTYPE} pipelineTester = ${BIN_DIR}/pipelineTester test: errCatchTest htmlPageTest htmlExpandUrlTest htmlSanitizeTest pipelineTests dyStringTest \ mimeTests base64Tests quotedPTests safeTest hashTest fetchUrlTest gff3Test \ tabixTest vcfTest hacTreeTest mmHashTest testSumDoubles jsonQueryTest \ - dnaCodonTest pathSimplifyTest faSpeedReadTest + dnaCodonTest pathSimplifyTest faSpeedReadTest cgiParseTest 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} pathSimplifyTest: pathSimplifyTest.o ${MYLIBS} mkdirs @${MKDIR} $(dir $@) ${CC} ${COPT} -o ${BIN_DIR}/pathSimplifyTest pathSimplifyTest.o ${MYLIBS} ${L} ${STRIP} ${BIN_DIR}/pathSimplifyTest${EXE} @@ -31,30 +31,37 @@ faSpeedReadTest: faSpeedReadTest.o ${MYLIBS} mkdirs @${MKDIR} $(dir $@) ${CC} ${COPT} -o ${BIN_DIR}/faSpeedReadTest faSpeedReadTest.o ${MYLIBS} ${L} ${STRIP} ${BIN_DIR}/faSpeedReadTest${EXE} ${BIN_DIR}/faSpeedReadTest > output/faSpeedReadTest diff expected/faSpeedReadTest output/faSpeedReadTest 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 +cgiParseTest: cgiParseTest.o ${MYLIBS} mkdirs + @${MKDIR} $(dir $@) + ${CC} ${COPT} -o ${BIN_DIR}/cgiParseTest cgiParseTest.o ${MYLIBS} ${L} + ${STRIP} ${BIN_DIR}/cgiParseTest${EXE} + ${BIN_DIR}/cgiParseTest > output/cgiParseTest + diff expected/cgiParseTest output/cgiParseTest + 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