File Changes for braney
switch to commits view, user indexv503_preview to v503_preview2 (2026-08-17 to 2026-08-24) v503
Show details
- .gitignore
- lines changed 1, context: html, text, full: html, text
af126b8f0cf9ddc553a78869a3c820a4bd4fdc59 Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125
Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.
Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.
This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.
Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.
- .gitmodules
- lines changed 4, context: html, text, full: html, text
af126b8f0cf9ddc553a78869a3c820a4bd4fdc59 Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125
Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.
Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.
This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.
Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.
- src/hg/cartReset/cartReset.c
- lines changed 2, context: html, text, full: html, text
ee89e6768015d512b5ca8db8a62e8a129dfd5c7f Sun Aug 23 15:56:57 2026 -0700
hgSession, cartReset: send the content policy header on their own pages
Both CGIs write their own http header block, so neither reaches addHttpHeaders
in cart.c, the hook that carries the policy header. hgSession lets each output
path write its own Content-Type, and cartReset gets its header from
htmShellWithHead.
Add the call ahead of each html Content-Type: the two main page functions in
hgSession.c, three more in backup.c, and the one in cartReset. The json paths
and the tar download are left alone, since they print no html.
With the hg.conf option off this changes nothing. With it on, both pages now
carry the header, and its nonce matches the one in the meta tag and on the
inline script tags.
- src/hg/cgilib/api.c
- lines changed 3, context: html, text, full: html, text
a4befd9382fadf413884d2215012535d5d667063 Mon Aug 17 13:46:45 2026 -0700
hgApi, hgTracks: tighten callback parameter validation, refs #38126 #38057
Add isValidJsonpCallback() and apply it to the callback-name paths in
apiOut() and the hgTracks jsonp output, so only C-symbol dotted names are
echoed back.
- src/hg/cgilib/pcrResult.c
- lines changed 6, context: html, text, full: html, text
554396e44745165ee4baf5214aa771f2b17b3be6 Mon Aug 17 16:04:26 2026 -0700
hgPcr, cart: screen the PCR result file names read back out of the cart, refs #37623
The hgPcrResult_<db> cart variable holds two file names and an optional target
name in one value. The cart.c arrays compare a whole value against
isServerUserFilePath(), so none of them fit that shape. Add a fourth array for
it and check the first two words. hgPcrResult_targetStyle shares the prefix and
is a display setting, so it is excluded by name.
Check both names where they are used as well, in pcrResultParseCart() and in
hgPcr's append path, the way dupTrack.c already does.
Two other things in writePcrResultTrack(). pcrFiles[2] was read without ever
being set whenever the value held only two words, which is the usual case. And
the saved-session test was a plain prefix compare that missed sessionDataDirOld;
it now asks whether the file is in the trash instead.
hg/utils/cartFileVarCatalog knows about the new array and has a row for
hgPcrResult_<db> saying why its scan cannot see this one.
- src/hg/hgHubConnect/hgHubConnect.c
- lines changed 12, context: html, text, full: html, text
139e158c2b2817ea64048290f046105d25f97198 Tue Aug 18 11:15:51 2026 -0700
hgHubConnect: encode hub label and contact fields consistently, refs #38123
- lines changed 10, context: html, text, full: html, text
b388a136dae20cfd65849c2412c3d011ce9b5f12 Tue Aug 18 11:21:42 2026 -0700
hgHubConnect: encode assembly names in the genome list, refs #38123
- lines changed 10, context: html, text, full: html, text
a43625b78a309952c8017aee3c3e92adca5739e8 Tue Aug 18 12:03:17 2026 -0700
hgHubConnect: encode the hub url in the genome list, refs #38123
- lines changed 1, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/hgLogin/hgLogin.c
- lines changed 75, context: html, text, full: html, text
67f89eb6f4f5e8ca51c551cdf0918a2cc33ad864 Fri Aug 21 09:01:22 2026 -0700
hgLogin: tighten validation and encoding of the return URL
Validate the return URL in one place, in getReturnToURL: accept only http, https
or a relative URL, and refuse characters that a properly encoded URL never
contains. The login.approvedReturn host check is unchanged and stays optional, so
a mirror that never set it behaves as before.
Encode the value where it is written out: html encoding in the href attributes,
javaScriptLiteralEncode in the location assignment.
Also fix the argument order in the two mail-failure messages, which was rotated
by one, so the values land where the format string means them to, and encode the
user name put into the mail-success redirect.
refs #38011
- src/hg/hgPcr/hgPcr.c
- lines changed 28, context: html, text, full: html, text
554396e44745165ee4baf5214aa771f2b17b3be6 Mon Aug 17 16:04:26 2026 -0700
hgPcr, cart: screen the PCR result file names read back out of the cart, refs #37623
The hgPcrResult_<db> cart variable holds two file names and an optional target
name in one value. The cart.c arrays compare a whole value against
isServerUserFilePath(), so none of them fit that shape. Add a fourth array for
it and check the first two words. hgPcrResult_targetStyle shares the prefix and
is a display setting, so it is excluded by name.
Check both names where they are used as well, in pcrResultParseCart() and in
hgPcr's append path, the way dupTrack.c already does.
Two other things in writePcrResultTrack(). pcrFiles[2] was read without ever
being set whenever the value held only two words, which is the usual case. And
the saved-session test was a plain prefix compare that missed sessionDataDirOld;
it now asks whether the file is in the trash instead.
hg/utils/cartFileVarCatalog knows about the new array and has a row for
hgPcrResult_<db> saying why its scan cannot see this one.
- src/hg/hgPhyloPlace/hgPhyloPlace.c
- lines changed 6, context: html, text, full: html, text
7181c0af889a0eee451b91ff0b23d67f35e0e772 Tue Aug 18 08:39:08 2026 -0700
cheapcgi, customTrack, hgSession, hgPhyloPlace: track in-memory uploads in a registry
Uploaded file contents are handed to the reading code as a text address and
size. Collect that bookkeeping in cheapcgi, which now records each block it
makes and hands back a name for it, and have the custom track, session and
phyloPlace upload paths look the block up by that name.
Also removes the duplicated address/size parsing those callers each had, and
makes lineFileDecompressMem ignore a too-small buffer.
refs #38108
- src/hg/hgSearch/hgSearch.c
- lines changed 3, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/hg/hgSession/backup.c
- lines changed 3, context: html, text, full: html, text
ee89e6768015d512b5ca8db8a62e8a129dfd5c7f Sun Aug 23 15:56:57 2026 -0700
hgSession, cartReset: send the content policy header on their own pages
Both CGIs write their own http header block, so neither reaches addHttpHeaders
in cart.c, the hook that carries the policy header. hgSession lets each output
path write its own Content-Type, and cartReset gets its header from
htmShellWithHead.
Add the call ahead of each html Content-Type: the two main page functions in
hgSession.c, three more in backup.c, and the one in cartReset. The json paths
and the tar download are left alone, since they print no html.
With the hg.conf option off this changes nothing. With it on, both pages now
carry the header, and its nonce matches the one in the meta tag and on the
inline script tags.
- src/hg/hgSession/hgSession.c
- lines changed 15, context: html, text, full: html, text
7181c0af889a0eee451b91ff0b23d67f35e0e772 Tue Aug 18 08:39:08 2026 -0700
cheapcgi, customTrack, hgSession, hgPhyloPlace: track in-memory uploads in a registry
Uploaded file contents are handed to the reading code as a text address and
size. Collect that bookkeeping in cheapcgi, which now records each block it
makes and hands back a name for it, and have the custom track, session and
phyloPlace upload paths look the block up by that name.
Also removes the duplicated address/size parsing those callers each had, and
makes lineFileDecompressMem ignore a too-small buffer.
refs #38108
- lines changed 2, context: html, text, full: html, text
ee89e6768015d512b5ca8db8a62e8a129dfd5c7f Sun Aug 23 15:56:57 2026 -0700
hgSession, cartReset: send the content policy header on their own pages
Both CGIs write their own http header block, so neither reaches addHttpHeaders
in cart.c, the hook that carries the policy header. hgSession lets each output
path write its own Content-Type, and cartReset gets its header from
htmShellWithHead.
Add the call ahead of each html Content-Type: the two main page functions in
hgSession.c, three more in backup.c, and the one in cartReset. The json paths
and the tar download are left alone, since they print no html.
With the hg.conf option off this changes nothing. With it on, both pages now
carry the header, and its nonce matches the one in the meta tag and on the
inline script tags.
- src/hg/hgTables/bigBed.c
- lines changed 8, context: html, text, full: html, text
52cee2eff9e953d4584a415b8a9b84bd2326d3cd Tue Aug 18 11:14:37 2026 -0700
hgTables: encode track menu and schema text consistently, refs #38123
- src/hg/hgTables/hgTables.c
- lines changed 12, context: html, text, full: html, text
52cee2eff9e953d4584a415b8a9b84bd2326d3cd Tue Aug 18 11:14:37 2026 -0700
hgTables: encode track menu and schema text consistently, refs #38123
- lines changed 12, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/hgTables/hgTables.h
- lines changed 3, context: html, text, full: html, text
52cee2eff9e953d4584a415b8a9b84bd2326d3cd Tue Aug 18 11:14:37 2026 -0700
hgTables: encode track menu and schema text consistently, refs #38123
- lines changed 3, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/hgTables/mainPage.c
- lines changed 4, context: html, text, full: html, text
52cee2eff9e953d4584a415b8a9b84bd2326d3cd Tue Aug 18 11:14:37 2026 -0700
hgTables: encode track menu and schema text consistently, refs #38123
- src/hg/hgTables/schema.c
- lines changed 2, context: html, text, full: html, text
52cee2eff9e953d4584a415b8a9b84bd2326d3cd Tue Aug 18 11:14:37 2026 -0700
hgTables: encode track menu and schema text consistently, refs #38123
- src/hg/hgTrackUi/hgTrackUi.c
- lines changed 1, context: html, text, full: html, text
074ea922bc80e0c46b93fb22b91426770022e4e2 Tue Aug 18 10:59:40 2026 -0700
lib, cheapcgi: encode some JSON tags and HTML attributes consistently, refs #38123
- lines changed 11, context: html, text, full: html, text
304e190d0af4be54569ac20edc26999673c44f8b Tue Aug 18 11:05:19 2026 -0700
hgTrackUi, hui: encode trackDb-derived label text consistently, refs #38123
- src/hg/hgTracks/config.c
- lines changed 1, context: html, text, full: html, text
5ee674363623678393bb186b1f5fdfd981ee743f Mon Aug 17 10:35:26 2026 -0700
hgTracks: default multiRegionButtonTop TRUE in config.c too, refs #37977
Two places read multiRegionButtonTop through MULTI_REGION_CFG_BUTTON_TOP: the
top-bar Multi-region button in hgTracks.c and the "Show all" checkbox in the
multi-region dialog in config.c. Kate put the checkbox under this flag on
purpose in 8ae222adb54. Then e1f7896a08f turned the flag on by default in
2022 and changed only the hgTracks.c read, so on a machine that does not set
the flag the button moved to the top bar while the checkbox stayed hidden.
It has been hidden for four years, although the cart variable it sets is read
unconditionally at hgTracks.c:11115, so the feature works for anyone who can
reach the variable another way.
The hg.conf catalog row carried this as an open defect, so its note is
rewritten and its recorded default now matches the tree.
- lines changed 6, context: html, text, full: html, text
20ca104b9897669e127e4ec8675321b12f780cff Tue Aug 18 11:19:44 2026 -0700
lib, hgTracks: encode JSON object keys and configure/search text, refs #38123
- lines changed 1, context: html, text, full: html, text
b88e4615c7ce7ea3f0d05c84365509670493840c Tue Aug 18 14:49:17 2026 -0700
lib, hgc, hgTracks: small output-encoding cleanups, refs #38123
- src/hg/hgTracks/gtexTracks.c
- lines changed 2, context: html, text, full: html, text
535457b618d5a08927870d96f16fa900cc4a91ab Wed Aug 19 18:08:44 2026 -0700
gtexTracks: match the guard on the description abbreviation to the bytes it writes, no redmine
- src/hg/hgTracks/hgTracks.c
- lines changed 6, context: html, text, full: html, text
a4befd9382fadf413884d2215012535d5d667063 Mon Aug 17 13:46:45 2026 -0700
hgApi, hgTracks: tighten callback parameter validation, refs #38126 #38057
Add isValidJsonpCallback() and apply it to the callback-name paths in
apiOut() and the hgTracks jsonp output, so only C-symbol dotted names are
echoed back.
- lines changed 23, context: html, text, full: html, text
764e1dff7737828ea9d3395804db520628e91a69 Tue Aug 18 10:59:46 2026 -0700
hgTracks: encode assembly and group header text consistently, refs #38123
- lines changed 3, context: html, text, full: html, text
934a51aa2ebc7e11bfba57804642cd03e4e1e60a Tue Aug 18 11:45:11 2026 -0700
trackHub: tighten group name validation, refs #38123
- src/hg/hgTracks/searchTracks.c
- lines changed 4, context: html, text, full: html, text
20ca104b9897669e127e4ec8675321b12f780cff Tue Aug 18 11:19:44 2026 -0700
lib, hgTracks: encode JSON object keys and configure/search text, refs #38123
- src/hg/hgTracks/vcfTrack.c
- lines changed 3, context: html, text, full: html, text
a5b8db176c6bd1cca6e542bf57080cfc7c9b29e8 Wed Aug 19 18:08:20 2026 -0700
vcfTrack: only abbreviate an allele that is longer than the per-allele display budget, refs #38154
- src/hg/hgc/bamClick.c
- lines changed 5, context: html, text, full: html, text
af8f5fbc7beacd00970cc8d3d37109f6e979f431 Mon Aug 17 10:35:18 2026 -0700
hgc: read the BAM pairEndsByName setting under the name the UI writes, refs #37979
The BAM track UI writes the checkbox as <track>.pairEndsByName, with a dot,
and hgTracks reads it back with cartUsualBooleanClosestToHome. The details
page built the name with an underscore instead, so it never saw the user's
choice and always fell back to the trackDb setting: a reader who turned
pairing off still got the joined-pair view when they clicked a read.
Nothing in the tree writes the underscore spelling, and no saved session on
hgwdev holds it, so there is no old name to keep working. 214 sessions hold
the dot spelling.
Verified with a two-read paired BAM in a hub: with the box checked the
details page shows the pair, and with it unchecked it now shows the single
read.
- lines changed 5, context: html, text, full: html, text
e6b0dc7877ae4b24f56682885e03263fd2da3582 Tue Aug 18 11:37:04 2026 -0700
lib, hgc: encode barChart, BAM and VCF detail text consistently, refs #38123
- src/hg/hgc/barChartClick.c
- lines changed 6, context: html, text, full: html, text
e6b0dc7877ae4b24f56682885e03263fd2da3582 Tue Aug 18 11:37:04 2026 -0700
lib, hgc: encode barChart, BAM and VCF detail text consistently, refs #38123
- lines changed 1, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/hgc/bigBedClick.c
- lines changed 3, context: html, text, full: html, text
f2d3014a3cc95116346eab4675817cf0c65f6d62 Tue Aug 18 11:12:35 2026 -0700
hgc: encode item detail text consistently, refs #38123
- lines changed 1, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/hgc/hgc.c
- lines changed 9, context: html, text, full: html, text
25c1787f5c2fc9bf27c5da4e5d5a706e3c89e667 Tue Aug 18 14:53:47 2026 -0700
hgc: read chain query sequence from the two bit file whenever the track names one, refs #38146
be4f99627b0 gated the otherTwoBitUrl branch of htcChainAli on the query database
not existing. That is the wrong test. hs1 keeps its sequence in a hub, so the
MySQL database hs1 does exist but holds only trackDb and hgFindSpec tables.
sqlDatabaseExists said yes, control fell through to loadGenomePart, and findNib
aborted with "Table 'hs1.chromInfo' doesn't exist" when the source of a quickLift
was hs1.
Take the otherTwoBitUrl branch whenever the track supplies the file, and keep the
"Org.chrom" label when hOrganism knows the organism, so the hg38 chainSelf track
still reads Human.chrN.
Verified against cgi-bin-braney with genome-test as the baseline: hs1 to hg38
quickLift now renders and its query bases match /gbdb/hs1/hs1.2bit; hg19 to hg38
quickLift, hg38 chainSelf and hg38 chainMm39 all produce byte-identical output.
- lines changed 34, context: html, text, full: html, text
f2d3014a3cc95116346eab4675817cf0c65f6d62 Tue Aug 18 11:12:35 2026 -0700
hgc: encode item detail text consistently, refs #38123
- lines changed 13, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- lines changed 17, context: html, text, full: html, text
9a83298f18860ef6d05232bf7e10f2df3c1c2b1d Sat Aug 22 10:26:22 2026 -0700
hgc: route inline javascript through the standard helpers
Three places in hgc wrote script markup by hand instead of using the
helpers the rest of the tree uses.
printIframe now emits its script block the way hgIntegrator does. The
wiki track create-item form builds its function with jsInlineF, so the
function lands in the same block as the handler that calls it.
showSomePartialDnaAlignment sets the body frame's start position through
the frame URL, which is how the sibling index links already address that
frame, and matches showSomeAlignment just above it.
No change to what any of the three pages contain.
- lines changed 1, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/hg/hgc/hgc.h
- lines changed 3, context: html, text, full: html, text
f2d3014a3cc95116346eab4675817cf0c65f6d62 Tue Aug 18 11:12:35 2026 -0700
hgc: encode item detail text consistently, refs #38123
- lines changed 3, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/hgc/vcfClick.c
- lines changed 35, context: html, text, full: html, text
e6b0dc7877ae4b24f56682885e03263fd2da3582 Tue Aug 18 11:37:04 2026 -0700
lib, hgc: encode barChart, BAM and VCF detail text consistently, refs #38123
- lines changed 1, context: html, text, full: html, text
b88e4615c7ce7ea3f0d05c84365509670493840c Tue Aug 18 14:49:17 2026 -0700
lib, hgc, hgTracks: small output-encoding cleanups, refs #38123
- lines changed 1, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/hgc/wikiTrack.c
- lines changed 6, context: html, text, full: html, text
9a83298f18860ef6d05232bf7e10f2df3c1c2b1d Sat Aug 22 10:26:22 2026 -0700
hgc: route inline javascript through the standard helpers
Three places in hgc wrote script markup by hand instead of using the
helpers the rest of the tree uses.
printIframe now emits its script block the way hgIntegrator does. The
wiki track create-item form builds its function with jsInlineF, so the
function lands in the same block as the handler that calls it.
showSomePartialDnaAlignment sets the body frame's start position through
the frame URL, which is how the sibling index links already address that
frame, and matches showSomeAlignment just above it.
No change to what any of the three pages contain.
- src/hg/hubApi/apiUtils.c
- lines changed 2, context: html, text, full: html, text
ae1b9adc9d85808683118f771703aeb8970306bf Sat Aug 22 10:19:03 2026 -0700
hubApi: add X-Content-Type-Options: nosniff to responses, refs #38163
Set the nosniff header ahead of the Content-Type on every hubApi output
path (JSON, text, and html), so responses declare their type explicitly.
- src/hg/hubApi/blat.c
- lines changed 2, context: html, text, full: html, text
ae1b9adc9d85808683118f771703aeb8970306bf Sat Aug 22 10:19:03 2026 -0700
hubApi: add X-Content-Type-Options: nosniff to responses, refs #38163
Set the nosniff header ahead of the Content-Type on every hubApi output
path (JSON, text, and html), so responses declare their type explicitly.
- src/hg/hubApi/hubApi.c
- lines changed 2, context: html, text, full: html, text
ae1b9adc9d85808683118f771703aeb8970306bf Sat Aug 22 10:19:03 2026 -0700
hubApi: add X-Content-Type-Options: nosniff to responses, refs #38163
Set the nosniff header ahead of the Content-Type on every hubApi output
path (JSON, text, and html), so responses declare their type explicitly.
- lines changed 3, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- lines changed 4, context: html, text, full: html, text
5a8e52dea2362f0f5417a19e95dca4f2ef0903d4 Sun Aug 23 15:20:33 2026 -0700
Merge branch 'cspNonce'
# Conflicts:
# src/hg/hubApi/hubApi.c
- src/hg/inc/hCommon.h
- lines changed 5, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/hg/inc/hubConnect.h
- lines changed 5, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/lib/barChartUi.c
- lines changed 14, context: html, text, full: html, text
e6b0dc7877ae4b24f56682885e03263fd2da3582 Tue Aug 18 11:37:04 2026 -0700
lib, hgc: encode barChart, BAM and VCF detail text consistently, refs #38123
- src/hg/lib/botDelay.c
- lines changed 1, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/hg/lib/cart.c
- lines changed 47, context: html, text, full: html, text
554396e44745165ee4baf5214aa771f2b17b3be6 Mon Aug 17 16:04:26 2026 -0700
hgPcr, cart: screen the PCR result file names read back out of the cart, refs #37623
The hgPcrResult_<db> cart variable holds two file names and an optional target
name in one value. The cart.c arrays compare a whole value against
isServerUserFilePath(), so none of them fit that shape. Add a fourth array for
it and check the first two words. hgPcrResult_targetStyle shares the prefix and
is a display setting, so it is excluded by name.
Check both names where they are used as well, in pcrResultParseCart() and in
hgPcr's append path, the way dupTrack.c already does.
Two other things in writePcrResultTrack(). pcrFiles[2] was read without ever
being set whenever the value held only two words, which is the usual case. And
the saved-session test was a plain prefix compare that missed sessionDataDirOld;
it now asks whether the file is in the trash instead.
hg/utils/cartFileVarCatalog knows about the new array and has a row for
hgPcrResult_<db> saying why its scan cannot see this one.
- lines changed 4, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/hg/lib/customFactory.c
- lines changed 49, context: html, text, full: html, text
7181c0af889a0eee451b91ff0b23d67f35e0e772 Tue Aug 18 08:39:08 2026 -0700
cheapcgi, customTrack, hgSession, hgPhyloPlace: track in-memory uploads in a registry
Uploaded file contents are handed to the reading code as a text address and
size. Collect that bookkeeping in cheapcgi, which now records each block it
makes and hands back a name for it, and have the custom track, session and
phyloPlace upload paths look the block up by that name.
Also removes the duplicated address/size parsing those callers each had, and
makes lineFileDecompressMem ignore a too-small buffer.
refs #38108
- src/hg/lib/customTrack.c
- lines changed 64, context: html, text, full: html, text
7181c0af889a0eee451b91ff0b23d67f35e0e772 Tue Aug 18 08:39:08 2026 -0700
cheapcgi, customTrack, hgSession, hgPhyloPlace: track in-memory uploads in a registry
Uploaded file contents are handed to the reading code as a text address and
size. Collect that bookkeeping in cheapcgi, which now records each block it
makes and hands back a name for it, and have the custom track, session and
phyloPlace upload paths look the block up by that name.
Also removes the duplicated address/size parsing those callers each had, and
makes lineFileDecompressMem ignore a too-small buffer.
refs #38108
- src/hg/lib/hCommon.c
- lines changed 19, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/hg/lib/hdb.c
- lines changed 1, context: html, text, full: html, text
997a9384be1a820ea0c35e2b551308bd6b5fb771 Tue Aug 18 09:08:34 2026 -0700
hdb: drop limit 1 from the hDbForTaxon fallback query so all candidate dbs are checked
The fallback query returned a single row, so the loop in
firstExistingDbFromQuery had nothing to walk. If that one dbDb row had no
real SQL database and no curated hub, hDbForTaxon returned NULL. Without
the limit the loop sees every active row for the taxon in orderKey order and
returns the first one that exists. refs #17886
- src/hg/lib/hubConnect.c
- lines changed 14, context: html, text, full: html, text
aca9143822a9c12b16b33d479a5abb6495b6b4f0 Wed Aug 19 06:59:39 2026 -0700
lib, hgc, hgTables, hgHubConnect: share hubEncode, refs #38123
hgc.c and hgTables.c each had their own copy of hubEncode(). The two
bodies were identical, so move the function to hubConnect.c next to
isHubTrack() and let both CGIs call the one definition.
Also use cgiEncode() rather than htmlEncode() for the db= value in the
hgHubConnect assembly list. That value goes in a query string, so
cgiEncode() is the right function there. Genome names are already
limited to a safe character set, so this changes no output today.
- src/hg/lib/hui.c
- lines changed 1, context: html, text, full: html, text
074ea922bc80e0c46b93fb22b91426770022e4e2 Tue Aug 18 10:59:40 2026 -0700
lib, cheapcgi: encode some JSON tags and HTML attributes consistently, refs #38123
- lines changed 28, context: html, text, full: html, text
304e190d0af4be54569ac20edc26999673c44f8b Tue Aug 18 11:05:19 2026 -0700
hgTrackUi, hui: encode trackDb-derived label text consistently, refs #38123
- lines changed 3, context: html, text, full: html, text
1c7ec830118f006d5fde9d8cdb36596edcf6e055 Tue Aug 18 12:03:17 2026 -0700
cheapcgi, hui: encode a bigBed-derived form control name, refs #38123
- src/hg/lib/jsHelper.c
- lines changed 3, context: html, text, full: html, text
20ca104b9897669e127e4ec8675321b12f780cff Tue Aug 18 11:19:44 2026 -0700
lib, hgTracks: encode JSON object keys and configure/search text, refs #38123
- lines changed 3, context: html, text, full: html, text
b88e4615c7ce7ea3f0d05c84365509670493840c Tue Aug 18 14:49:17 2026 -0700
lib, hgc, hgTracks: small output-encoding cleanups, refs #38123
- src/hg/lib/pgSnp.c
- lines changed 8, context: html, text, full: html, text
01fbc2b46b7fe918aa6628cca8ca8ee7ede0e598 Wed Aug 19 17:54:38 2026 -0700
pgSnp: replace a fixed-size local array in alleleCountsFromVcfRecord with an allocation sized from the record, refs #38154
- src/hg/lib/trackHub.c
- lines changed 7, context: html, text, full: html, text
c4eb98684d52ed28bd00632854ca5c8385b1bb63 Tue Aug 18 11:24:43 2026 -0700
trackHub: tighten genome name validation, refs #38123
- lines changed 20, context: html, text, full: html, text
934a51aa2ebc7e11bfba57804642cd03e4e1e60a Tue Aug 18 11:45:11 2026 -0700
trackHub: tighten group name validation, refs #38123
- src/hg/utils/cartFileVarCatalog/cartFileVarCatalog.py
- lines changed 42, context: html, text, full: html, text
554396e44745165ee4baf5214aa771f2b17b3be6 Mon Aug 17 16:04:26 2026 -0700
hgPcr, cart: screen the PCR result file names read back out of the cart, refs #37623
The hgPcrResult_<db> cart variable holds two file names and an optional target
name in one value. The cart.c arrays compare a whole value against
isServerUserFilePath(), so none of them fit that shape. Add a fourth array for
it and check the first two words. hgPcrResult_targetStyle shares the prefix and
is a display setting, so it is excluded by name.
Check both names where they are used as well, in pcrResultParseCart() and in
hgPcr's append path, the way dupTrack.c already does.
Two other things in writePcrResultTrack(). pcrFiles[2] was read without ever
being set whenever the value held only two words, which is the usual case. And
the saved-session test was a plain prefix compare that missed sessionDataDirOld;
it now asks whether the file is in the trash instead.
hg/utils/cartFileVarCatalog knows about the new array and has a row for
hgPcrResult_<db> saying why its scan cannot see this one.
- src/hg/utils/cartFileVarCatalog/harvestCartFileVars.py
- lines changed 19, context: html, text, full: html, text
554396e44745165ee4baf5214aa771f2b17b3be6 Mon Aug 17 16:04:26 2026 -0700
hgPcr, cart: screen the PCR result file names read back out of the cart, refs #37623
The hgPcrResult_<db> cart variable holds two file names and an optional target
name in one value. The cart.c arrays compare a whole value against
isServerUserFilePath(), so none of them fit that shape. Add a fourth array for
it and check the first two words. hgPcrResult_targetStyle shares the prefix and
is a display setting, so it is excluded by name.
Check both names where they are used as well, in pcrResultParseCart() and in
hgPcr's append path, the way dupTrack.c already does.
Two other things in writePcrResultTrack(). pcrFiles[2] was read without ever
being set whenever the value held only two words, which is the usual case. And
the saved-session test was a plain prefix compare that missed sessionDataDirOld;
it now asks whether the file is in the trash instead.
hg/utils/cartFileVarCatalog knows about the new array and has a row for
hgPcrResult_<db> saying why its scan cannot see this one.
- src/hg/utils/cartTrackVarCatalog/cartVarsNotCataloged.txt
- lines changed 1, context: html, text, full: html, text
9be408c932a09fa56fb6b12b9d1e44eed3b0c5b8 Mon Aug 17 09:58:33 2026 -0700
cartTrackVarCatalog: baseline delAll, which is an element id not a cart variable, refs #37838
hgTracks.c builds "%s_delAll" with safef to name the Delete all button in
the BLAT Results group, then passes that string to jsOnEventByIdF. The
harvester cannot tell a group-prefixed element id from a track-prefixed cart
variable, so the name came out of the scan and failed the nightly reconcile.
It is an HTML id, so it belongs in the baseline. Teaching the scan to skip
strings that only reach jsOnEventById is on the #37979 list.
- src/hg/utils/hgConfCatalog/hgConfCatalog.py
- lines changed 30, context: html, text, full: html, text
352a5277845b6d8b40b008af386c18c35d83e6d7 Mon Aug 17 09:58:26 2026 -0700
hgConfCatalog: repair 30 file:line citations that drifted, refs #37925
The two commits pushed today moved code under the catalog. hgBlat.c gained
about 97 lines, hgTracks.c 17, hgc.c 36 and config.c 9, so every cited read
below those points was off. Written by hgConfCatalog.py --fix-citations,
which only moves a citation when it finds the same read elsewhere in the
same file.
- lines changed 10, context: html, text, full: html, text
5ee674363623678393bb186b1f5fdfd981ee743f Mon Aug 17 10:35:26 2026 -0700
hgTracks: default multiRegionButtonTop TRUE in config.c too, refs #37977
Two places read multiRegionButtonTop through MULTI_REGION_CFG_BUTTON_TOP: the
top-bar Multi-region button in hgTracks.c and the "Show all" checkbox in the
multi-region dialog in config.c. Kate put the checkbox under this flag on
purpose in 8ae222adb54. Then e1f7896a08f turned the flag on by default in
2022 and changed only the hgTracks.c read, so on a machine that does not set
the flag the button moved to the top bar while the checkbox stayed hidden.
It has been hidden for four years, although the cart variable it sets is read
unconditionally at hgTracks.c:11115, so the feature works for anyone who can
reach the variable another way.
The hg.conf catalog row carried this as an open defect, so its note is
rewritten and its recorded default now matches the tree.
- src/inc/cheapcgi.h
- lines changed 7, context: html, text, full: html, text
a4befd9382fadf413884d2215012535d5d667063 Mon Aug 17 13:46:45 2026 -0700
hgApi, hgTracks: tighten callback parameter validation, refs #38126 #38057
Add isValidJsonpCallback() and apply it to the callback-name paths in
apiOut() and the hgTracks jsonp output, so only C-symbol dotted names are
echoed back.
- lines changed 12, context: html, text, full: html, text
7181c0af889a0eee451b91ff0b23d67f35e0e772 Tue Aug 18 08:39:08 2026 -0700
cheapcgi, customTrack, hgSession, hgPhyloPlace: track in-memory uploads in a registry
Uploaded file contents are handed to the reading code as a text address and
size. Collect that bookkeeping in cheapcgi, which now records each block it
makes and hands back a name for it, and have the custom track, session and
phyloPlace upload paths look the block up by that name.
Also removes the duplicated address/size parsing those callers each had, and
makes lineFileDecompressMem ignore a too-small buffer.
refs #38108
- lines changed 9, context: html, text, full: html, text
dbb0850c7935dec65d3394ef1ddcdc10dafac5cf Tue Aug 18 10:03:38 2026 -0700
cheapcgi: parse %hh escapes directly instead of with sscanf, refs #37262
cgiDecode and cgiDecodeFull read each %hh escape with sscanf(in, "%2x", &code).
glibc builds a stream over the whole remaining string on every sscanf call, so
each call scans to the terminating null. That makes the cost of a decode
quadratic in the length of one variable's value.
The cost is real on data we already have. A saved session in hgcentraltest
holds a single 699 KB hgFind.matches value with 58,930 escapes; decoding it
takes 0.29 s of CPU, and cart.c loadHash does it on every load of that session.
The database cart has no size cap, so this is not bounded by the 1 MB limit on
request input that went in for #37452. At that 1 MB limit a single request
still costs over 2 s.
Reading the two hex digits directly is a few hundred times faster (430x on the
699 KB value) and never walks past them. Behavior is unchanged for well-formed
input: verified byte-identical over the top 200 carts of namedSessionDb,
sessionDb and userDb (2.4 million values, 14.7 MB), over an exhaustive sweep of
every "%" plus two arbitrary bytes, and over cgiEncode/cgiDecode round trips of
all 256 byte values.
Decoding now differs only where a "%" is not followed by two hex digits, which
nothing legitimate produces - none of the 659,624 escapes in those carts are
malformed. The old code was worse there anyway: sscanf skips leading
whitespace, so "% 0Z" decoded to a null byte in the middle of the value and
silently truncated it. Malformed escapes now yield '?' like other bad input.
Also removes the FAST_CGI_DECODE ifdef added earlier on this ticket. It never
touched cgiDecode, so it does not describe anything now that the real cost is
fixed. Its per-variable caps are superseded by the total input cap from
#37452, which aborts with a message rather than dropping a variable silently,
and cgiParseNext's variant silently skipped oversized variables for the
ENCODE/CIRM tag tools that are its only callers.
- src/inc/common.mk
- lines changed 16, context: html, text, full: html, text
af126b8f0cf9ddc553a78869a3c820a4bd4fdc59 Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125
Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.
Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.
This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.
Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.
- src/inc/htmshell.h
- lines changed 4, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/inc/vcf.h
- lines changed 5, context: html, text, full: html, text
6c676a0e9ed642676008731762141e0c16822787 Sat Aug 22 09:31:14 2026 -0700
vcf: tighten validation of the genotype allele index, refs #38155
New parseAlleleIx returns missing data for a GT allele index that the record
has no allele for, and for a value that will not fit the field. It checks the
value as an int, before it reaches the field. vcfParseGenotypes and
vcfParseGenotypesGtOnly both go through it, and a check after the per-genotype
loop covers the PL and SGT fallbacks, which choose an index without consulting
the allele count.
hapIxA and hapIxB become signed char. Plain char is unsigned on some
architectures, and the negative missing-data value did not stay negative there.
Size and field offsets are unchanged, and x86 code generation is identical.
Adds a lib/tests case for malformed and boundary genotype indexes.
- src/lib/cheapcgi.c
- lines changed 31, context: html, text, full: html, text
a4befd9382fadf413884d2215012535d5d667063 Mon Aug 17 13:46:45 2026 -0700
hgApi, hgTracks: tighten callback parameter validation, refs #38126 #38057
Add isValidJsonpCallback() and apply it to the callback-name paths in
apiOut() and the hgTracks jsonp output, so only C-symbol dotted names are
echoed back.
- lines changed 56, context: html, text, full: html, text
7181c0af889a0eee451b91ff0b23d67f35e0e772 Tue Aug 18 08:39:08 2026 -0700
cheapcgi, customTrack, hgSession, hgPhyloPlace: track in-memory uploads in a registry
Uploaded file contents are handed to the reading code as a text address and
size. Collect that bookkeeping in cheapcgi, which now records each block it
makes and hands back a name for it, and have the custom track, session and
phyloPlace upload paths look the block up by that name.
Also removes the duplicated address/size parsing those callers each had, and
makes lineFileDecompressMem ignore a too-small buffer.
refs #38108
- lines changed 111, context: html, text, full: html, text
dbb0850c7935dec65d3394ef1ddcdc10dafac5cf Tue Aug 18 10:03:38 2026 -0700
cheapcgi: parse %hh escapes directly instead of with sscanf, refs #37262
cgiDecode and cgiDecodeFull read each %hh escape with sscanf(in, "%2x", &code).
glibc builds a stream over the whole remaining string on every sscanf call, so
each call scans to the terminating null. That makes the cost of a decode
quadratic in the length of one variable's value.
The cost is real on data we already have. A saved session in hgcentraltest
holds a single 699 KB hgFind.matches value with 58,930 escapes; decoding it
takes 0.29 s of CPU, and cart.c loadHash does it on every load of that session.
The database cart has no size cap, so this is not bounded by the 1 MB limit on
request input that went in for #37452. At that 1 MB limit a single request
still costs over 2 s.
Reading the two hex digits directly is a few hundred times faster (430x on the
699 KB value) and never walks past them. Behavior is unchanged for well-formed
input: verified byte-identical over the top 200 carts of namedSessionDb,
sessionDb and userDb (2.4 million values, 14.7 MB), over an exhaustive sweep of
every "%" plus two arbitrary bytes, and over cgiEncode/cgiDecode round trips of
all 256 byte values.
Decoding now differs only where a "%" is not followed by two hex digits, which
nothing legitimate produces - none of the 659,624 escapes in those carts are
malformed. The old code was worse there anyway: sscanf skips leading
whitespace, so "% 0Z" decoded to a null byte in the middle of the value and
silently truncated it. Malformed escapes now yield '?' like other bad input.
Also removes the FAST_CGI_DECODE ifdef added earlier on this ticket. It never
touched cgiDecode, so it does not describe anything now that the real cost is
fixed. Its per-variable caps are superseded by the total input cap from
#37452, which aborts with a message rather than dropping a variable silently,
and cgiParseNext's variant silently skipped oversized variables for the
ENCODE/CIRM tag tools that are its only callers.
- lines changed 7, context: html, text, full: html, text
074ea922bc80e0c46b93fb22b91426770022e4e2 Tue Aug 18 10:59:40 2026 -0700
lib, cheapcgi: encode some JSON tags and HTML attributes consistently, refs #38123
- lines changed 3, context: html, text, full: html, text
1c7ec830118f006d5fde9d8cdb36596edcf6e055 Tue Aug 18 12:03:17 2026 -0700
cheapcgi, hui: encode a bigBed-derived form control name, refs #38123
- src/lib/htmshell.c
- lines changed 14, context: html, text, full: html, text
e6ddf60465deb96e43be6738c5ca6a7a6168cac8 Sat Aug 22 15:08:59 2026 -0700
hg/lib: add an option to send the content policy as an http response header
New cspWriteResponseHeader() in hg/lib/hCommon.c, gated on hg.conf's
cspResponseHeader, which defaults off everywhere. The policy string itself is
still built by the existing code in lib/htmshell.c, which now also knows how to
format it as a response header. Both carry the same nonce, since getNonce() is
one per process, so a page may safely have the header and the meta tag.
Most pages pick it up from addHttpHeaders() in cart.c, the existing hook for
extra response headers, which every cart based CGI already passes through. Six
places build their own http header block and so call it directly: the two "too
many requests" pages, the captcha and its error page, the hubApi help redirect,
and the hgSearch redirect to hgTracks.
Inline scripts on three of those pages now carry the nonce, and the policy
allows the Cloudflare script the bot check loads, so the option works when it
is turned on. The Cloudflare entry is the only part of this that takes effect
with the option off.
- src/lib/jsonParse.c
- lines changed 5, context: html, text, full: html, text
20ca104b9897669e127e4ec8675321b12f780cff Tue Aug 18 11:19:44 2026 -0700
lib, hgTracks: encode JSON object keys and configure/search text, refs #38123
- src/lib/jsonWrite.c
- lines changed 7, context: html, text, full: html, text
074ea922bc80e0c46b93fb22b91426770022e4e2 Tue Aug 18 10:59:40 2026 -0700
lib, cheapcgi: encode some JSON tags and HTML attributes consistently, refs #38123
- src/lib/linefile.c
- lines changed 2, context: html, text, full: html, text
7181c0af889a0eee451b91ff0b23d67f35e0e772 Tue Aug 18 08:39:08 2026 -0700
cheapcgi, customTrack, hgSession, hgPhyloPlace: track in-memory uploads in a registry
Uploaded file contents are handed to the reading code as a text address and
size. Collect that bookkeeping in cheapcgi, which now records each block it
makes and hands back a name for it, and have the custom track, session and
phyloPlace upload paths look the block up by that name.
Also removes the duplicated address/size parsing those callers each had, and
makes lineFileDecompressMem ignore a too-small buffer.
refs #38108
- src/lib/tests/expected/vcfParseBadGenotypeIx.out
- lines changed 33, context: html, text, full: html, text
6c676a0e9ed642676008731762141e0c16822787 Sat Aug 22 09:31:14 2026 -0700
vcf: tighten validation of the genotype allele index, refs #38155
New parseAlleleIx returns missing data for a GT allele index that the record
has no allele for, and for a value that will not fit the field. It checks the
value as an int, before it reaches the field. vcfParseGenotypes and
vcfParseGenotypesGtOnly both go through it, and a check after the per-genotype
loop covers the PL and SGT fallbacks, which choose an index without consulting
the allele count.
hapIxA and hapIxB become signed char. Plain char is unsigned on some
architectures, and the negative missing-data value did not stay negative there.
Size and field offsets are unchanged, and x86 code generation is identical.
Adds a lib/tests case for malformed and boundary genotype indexes.
- src/lib/tests/expected/vcfParseManyAlleles.out
- lines changed 11, context: html, text, full: html, text
de609b7489963f32ad474619cb3dff0283ef7e76 Sun Aug 23 15:13:46 2026 -0700
vcf: bound the genotype allele index by the field it is stored in, refs #38155
parseAlleleIx checked the index against alleleCount only. A record can hold up
to VCF_MAX_INFO alleles, so an index of 128 or more could pass that check and
then narrow on the way into the signed char field. The narrowed value was
sometimes another real allele of the record: with 260 ALT alleles, index 260
came out as 4. The parser then reported a genotype the VCF never named.
The check now also rejects an index above SCHAR_MAX, so an index too large for
the field reads as missing data. SCHAR_MAX and not CHAR_MAX, because CHAR_MAX
is 255 on the unsigned char platforms that the field is declared signed for.
Every other assignment to hapIxA and hapIxB in this file is a literal in the
range -1 to 2, so parseAlleleIx was the only path that could carry an
out-of-range value.
New test vcfParseManyAlleles, with a record of 260 ALT alleles. Without the
fix, GT 128/1 reads as -128/1, 130/130 as -126/-126, and 260/260 as 4/4.
- src/lib/tests/input/badGenotypeIx.vcf.gz
- lines changed 0, context: html, text, full: html, text
6c676a0e9ed642676008731762141e0c16822787 Sat Aug 22 09:31:14 2026 -0700
vcf: tighten validation of the genotype allele index, refs #38155
New parseAlleleIx returns missing data for a GT allele index that the record
has no allele for, and for a value that will not fit the field. It checks the
value as an int, before it reaches the field. vcfParseGenotypes and
vcfParseGenotypesGtOnly both go through it, and a check after the per-genotype
loop covers the PL and SGT fallbacks, which choose an index without consulting
the allele count.
hapIxA and hapIxB become signed char. Plain char is unsigned on some
architectures, and the negative missing-data value did not stay negative there.
Size and field offsets are unchanged, and x86 code generation is identical.
Adds a lib/tests case for malformed and boundary genotype indexes.
- src/lib/tests/input/badGenotypeIx.vcf.gz.tbi
- lines changed 0, context: html, text, full: html, text
6c676a0e9ed642676008731762141e0c16822787 Sat Aug 22 09:31:14 2026 -0700
vcf: tighten validation of the genotype allele index, refs #38155
New parseAlleleIx returns missing data for a GT allele index that the record
has no allele for, and for a value that will not fit the field. It checks the
value as an int, before it reaches the field. vcfParseGenotypes and
vcfParseGenotypesGtOnly both go through it, and a check after the per-genotype
loop covers the PL and SGT fallbacks, which choose an index without consulting
the allele count.
hapIxA and hapIxB become signed char. Plain char is unsigned on some
architectures, and the negative missing-data value did not stay negative there.
Size and field offsets are unchanged, and x86 code generation is identical.
Adds a lib/tests case for malformed and boundary genotype indexes.
- src/lib/tests/input/manyAlleles.vcf.gz
- lines changed 0, context: html, text, full: html, text
de609b7489963f32ad474619cb3dff0283ef7e76 Sun Aug 23 15:13:46 2026 -0700
vcf: bound the genotype allele index by the field it is stored in, refs #38155
parseAlleleIx checked the index against alleleCount only. A record can hold up
to VCF_MAX_INFO alleles, so an index of 128 or more could pass that check and
then narrow on the way into the signed char field. The narrowed value was
sometimes another real allele of the record: with 260 ALT alleles, index 260
came out as 4. The parser then reported a genotype the VCF never named.
The check now also rejects an index above SCHAR_MAX, so an index too large for
the field reads as missing data. SCHAR_MAX and not CHAR_MAX, because CHAR_MAX
is 255 on the unsigned char platforms that the field is declared signed for.
Every other assignment to hapIxA and hapIxB in this file is a literal in the
range -1 to 2, so parseAlleleIx was the only path that could carry an
out-of-range value.
New test vcfParseManyAlleles, with a record of 260 ALT alleles. Without the
fix, GT 128/1 reads as -128/1, 130/130 as -126/-126, and 260/260 as 4/4.
- src/lib/tests/input/manyAlleles.vcf.gz.tbi
- lines changed 0, context: html, text, full: html, text
de609b7489963f32ad474619cb3dff0283ef7e76 Sun Aug 23 15:13:46 2026 -0700
vcf: bound the genotype allele index by the field it is stored in, refs #38155
parseAlleleIx checked the index against alleleCount only. A record can hold up
to VCF_MAX_INFO alleles, so an index of 128 or more could pass that check and
then narrow on the way into the signed char field. The narrowed value was
sometimes another real allele of the record: with 260 ALT alleles, index 260
came out as 4. The parser then reported a genotype the VCF never named.
The check now also rejects an index above SCHAR_MAX, so an index too large for
the field reads as missing data. SCHAR_MAX and not CHAR_MAX, because CHAR_MAX
is 255 on the unsigned char platforms that the field is declared signed for.
Every other assignment to hapIxA and hapIxB in this file is a literal in the
range -1 to 2, so parseAlleleIx was the only path that could carry an
out-of-range value.
New test vcfParseManyAlleles, with a record of 260 ALT alleles. Without the
fix, GT 128/1 reads as -128/1, 130/130 as -126/-126, and 260/260 as 4/4.
- src/lib/tests/makefile
- lines changed 8, context: html, text, full: html, text
6c676a0e9ed642676008731762141e0c16822787 Sat Aug 22 09:31:14 2026 -0700
vcf: tighten validation of the genotype allele index, refs #38155
New parseAlleleIx returns missing data for a GT allele index that the record
has no allele for, and for a value that will not fit the field. It checks the
value as an int, before it reaches the field. vcfParseGenotypes and
vcfParseGenotypesGtOnly both go through it, and a check after the per-genotype
loop covers the PL and SGT fallbacks, which choose an index without consulting
the allele count.
hapIxA and hapIxB become signed char. Plain char is unsigned on some
architectures, and the negative missing-data value did not stay negative there.
Size and field offsets are unchanged, and x86 code generation is identical.
Adds a lib/tests case for malformed and boundary genotype indexes.
- lines changed 9, context: html, text, full: html, text
de609b7489963f32ad474619cb3dff0283ef7e76 Sun Aug 23 15:13:46 2026 -0700
vcf: bound the genotype allele index by the field it is stored in, refs #38155
parseAlleleIx checked the index against alleleCount only. A record can hold up
to VCF_MAX_INFO alleles, so an index of 128 or more could pass that check and
then narrow on the way into the signed char field. The narrowed value was
sometimes another real allele of the record: with 260 ALT alleles, index 260
came out as 4. The parser then reported a genotype the VCF never named.
The check now also rejects an index above SCHAR_MAX, so an index too large for
the field reads as missing data. SCHAR_MAX and not CHAR_MAX, because CHAR_MAX
is 255 on the unsigned char platforms that the field is declared signed for.
Every other assignment to hapIxA and hapIxB in this file is a literal in the
range -1 to 2, so parseAlleleIx was the only path that could carry an
out-of-range value.
New test vcfParseManyAlleles, with a record of 260 ALT alleles. Without the
fix, GT 128/1 reads as -128/1, 130/130 as -126/-126, and 260/260 as 4/4.
- src/lib/tests/vcfParseTest.c
- lines changed 39, context: html, text, full: html, text
6c676a0e9ed642676008731762141e0c16822787 Sat Aug 22 09:31:14 2026 -0700
vcf: tighten validation of the genotype allele index, refs #38155
New parseAlleleIx returns missing data for a GT allele index that the record
has no allele for, and for a value that will not fit the field. It checks the
value as an int, before it reaches the field. vcfParseGenotypes and
vcfParseGenotypesGtOnly both go through it, and a check after the per-genotype
loop covers the PL and SGT fallbacks, which choose an index without consulting
the allele count.
hapIxA and hapIxB become signed char. Plain char is unsigned on some
architectures, and the negative missing-data value did not stay negative there.
Size and field offsets are unchanged, and x86 code generation is identical.
Adds a lib/tests case for malformed and boundary genotype indexes.
- src/lib/vcf.c
- lines changed 30, context: html, text, full: html, text
6c676a0e9ed642676008731762141e0c16822787 Sat Aug 22 09:31:14 2026 -0700
vcf: tighten validation of the genotype allele index, refs #38155
New parseAlleleIx returns missing data for a GT allele index that the record
has no allele for, and for a value that will not fit the field. It checks the
value as an int, before it reaches the field. vcfParseGenotypes and
vcfParseGenotypesGtOnly both go through it, and a check after the per-genotype
loop covers the PL and SGT fallbacks, which choose an index without consulting
the allele count.
hapIxA and hapIxB become signed char. Plain char is unsigned on some
architectures, and the negative missing-data value did not stay negative there.
Size and field offsets are unchanged, and x86 code generation is identical.
Adds a lib/tests case for malformed and boundary genotype indexes.
- lines changed 5, context: html, text, full: html, text
de609b7489963f32ad474619cb3dff0283ef7e76 Sun Aug 23 15:13:46 2026 -0700
vcf: bound the genotype allele index by the field it is stored in, refs #38155
parseAlleleIx checked the index against alleleCount only. A record can hold up
to VCF_MAX_INFO alleles, so an index of 128 or more could pass that check and
then narrow on the way into the signed char field. The narrowed value was
sometimes another real allele of the record: with 260 ALT alleles, index 260
came out as 4. The parser then reported a genotype the VCF never named.
The check now also rejects an index above SCHAR_MAX, so an index too large for
the field reads as missing data. SCHAR_MAX and not CHAR_MAX, because CHAR_MAX
is 255 on the unsigned char platforms that the field is declared signed for.
Every other assignment to hapIxA and hapIxB in this file is a literal in the
range -1 to 2, so parseAlleleIx was the only path that could carry an
out-of-range value.
New test vcfParseManyAlleles, with a record of 260 ALT alleles. Without the
fix, GT 128/1 reads as -128/1, 130/130 as -126/-126, and 260/260 as 4/4.
- src/makefile
- lines changed 9, context: html, text, full: html, text
af126b8f0cf9ddc553a78869a3c820a4bd4fdc59 Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125
Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.
Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.
This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.
Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.
- src/submodules/README.md
- lines changed 47, context: html, text, full: html, text
af126b8f0cf9ddc553a78869a3c820a4bd4fdc59 Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125
Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.
Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.
This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.
Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.
- src/submodules/submoduleSetup
- lines changed 29, context: html, text, full: html, text
af126b8f0cf9ddc553a78869a3c820a4bd4fdc59 Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125
Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.
Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.
This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.
Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.
- src/submodules/zlib-ng
- lines changed 1, context: html, text, full: html, text
af126b8f0cf9ddc553a78869a3c820a4bd4fdc59 Mon Aug 17 13:36:13 2026 -0700
build: link the browser against zlib-ng instead of the system zlib, refs #38125
Adds zlib-ng as a second git submodule, alongside htslib, and points ZLIB at it.
It is built with --zlib-compat, so the header and the symbol names are the
ordinary zlib ones and no calling code has to change.
Measured over the eight Recommended Track Set pages, hgTracks uses 29 percent
less processor time and 26 percent less wall clock, and the image it produces is
pixel identical. Writing the PNG is about three times faster and reading a
bigBed data block about twice as fast, which is why the gain is larger than the
image work alone would give.
This also makes the platforms agree. x86_64 was linking a static /lib64/libz.a
only because that file happened to be present, the arm64 Docker build fell
through to a shared -lz, and Darwin was taking MacPorts zlib. All three now use
the submodule.
Verified on x86_64 Linux, aarch64 Linux and Apple silicon: zlib-ng builds, its
own test suite passes, the makefiles pick it up, and bigBedToBed output is byte
identical to before the change.
- src/utils/makefile
- lines changed 1, context: html, text, full: html, text
4ae50fa5255be82566187f8cdbf5591152d3cf34 Sat Aug 22 14:49:40 2026 -0700
ts: add the ticket-sandbox scripts, refs #37867
ts parks a Redmine ticket as its own frozen browser instance on hgwdev:
a full copy of cgi-bin-$USER and htdocs-$USER served by a private
loopback httpd, with the databases, /gbdb, and trash left shared.
Generalized from the personal version: per-user sandbox paths, TS_ROOT
for the instance directory, and existence checks in create.
- src/utils/ts/README
- lines changed 66, context: html, text, full: html, text
4ae50fa5255be82566187f8cdbf5591152d3cf34 Sat Aug 22 14:49:40 2026 -0700
ts: add the ticket-sandbox scripts, refs #37867
ts parks a Redmine ticket as its own frozen browser instance on hgwdev:
a full copy of cgi-bin-$USER and htdocs-$USER served by a private
loopback httpd, with the databases, /gbdb, and trash left shared.
Generalized from the personal version: per-user sandbox paths, TS_ROOT
for the instance directory, and existence checks in create.
- lines changed 1, context: html, text, full: html, text
798c382a4e6e6f2e9ecaf6c47300f8cc2a6e0074 Mon Aug 24 08:54:58 2026 -0700
ts: add a conf subcommand to rewrite httpd.conf without re-freezing, refs #37867
The CORS scoping fix in 4d9755a1 changed the httpd.conf template, but a
parked instance keeps the conf it was created with. All three parked
instances therefore still set Access-Control-Allow-Origin at server
scope, including on cgi-bin. That is the hole 4d9755a1 closed in the
template only.
The one way to pick up a template change was "ts sync", and cmd_sync
calls freeze before writeConf. For a park whose whole point is the
frozen code, re-freezing to the current live sandbox throws away the
thing being kept. There was no way to update only the config.
"ts conf NNNNN" rewrites httpd.conf from the current template, leaves
the frozen cgi-bin and htdocs alone, and restarts the httpd if it was
running. Ran it on all three parked instances: cgi-bin now sends no
Access-Control header, htdocs and trash send both.
- src/utils/ts/ts
- lines changed 328, context: html, text, full: html, text
4ae50fa5255be82566187f8cdbf5591152d3cf34 Sat Aug 22 14:49:40 2026 -0700
ts: add the ticket-sandbox scripts, refs #37867
ts parks a Redmine ticket as its own frozen browser instance on hgwdev:
a full copy of cgi-bin-$USER and htdocs-$USER served by a private
loopback httpd, with the databases, /gbdb, and trash left shared.
Generalized from the personal version: per-user sandbox paths, TS_ROOT
for the instance directory, and existence checks in create.
- lines changed 11, context: html, text, full: html, text
4d9755a177d6b6660e589ec9f322e3b932fdb391 Sun Aug 23 15:13:54 2026 -0700
ts: scope the CORS header to the data directories, refs #37867
The per-ticket httpd.conf set Access-Control-Allow-Origin to * at server scope,
which covered CGI responses too. The live /usr/local/apache/conf/httpd.conf
sets that header on htdocs and on the trash directories only, never server-wide
and never on cgi-bin. A parked instance has no password, so a wildcard on the
CGI output let any page in the developer's browser read it through the open ssh
tunnel.
The header now sits in the htdocs and trash Directory blocks, with the
Access-Control-Allow-Headers: Range line that accompanies it in the live config,
so range requests on trash files behave the same as in production.
Also replace a tab or newline in the free-text note with a space before it is
written to ports.tsv. The registry is one tab-separated line per ticket, so
those characters appended a malformed row instead of reading back as the note.
Instances parked before this change need ts sync to pick up the new config.
- lines changed 22, context: html, text, full: html, text
798c382a4e6e6f2e9ecaf6c47300f8cc2a6e0074 Mon Aug 24 08:54:58 2026 -0700
ts: add a conf subcommand to rewrite httpd.conf without re-freezing, refs #37867
The CORS scoping fix in 4d9755a1 changed the httpd.conf template, but a
parked instance keeps the conf it was created with. All three parked
instances therefore still set Access-Control-Allow-Origin at server
scope, including on cgi-bin. That is the hole 4d9755a1 closed in the
template only.
The one way to pick up a template change was "ts sync", and cmd_sync
calls freeze before writeConf. For a park whose whole point is the
frozen code, re-freezing to the current live sandbox throws away the
thing being kept. There was no way to update only the config.
"ts conf NNNNN" rewrites httpd.conf from the current template, leaves
the frozen cgi-bin and htdocs alone, and restarts the httpd if it was
running. Ran it on all three parked instances: cgi-bin now sends no
Access-Control header, htdocs and trash send both.
- src/utils/ts/ts.mac
- lines changed 68, context: html, text, full: html, text
4ae50fa5255be82566187f8cdbf5591152d3cf34 Sat Aug 22 14:49:40 2026 -0700
ts: add the ticket-sandbox scripts, refs #37867
ts parks a Redmine ticket as its own frozen browser instance on hgwdev:
a full copy of cgi-bin-$USER and htdocs-$USER served by a private
loopback httpd, with the databases, /gbdb, and trash left shared.
Generalized from the personal version: per-user sandbox paths, TS_ROOT
for the instance directory, and existence checks in create.
- lines changed 2, context: html, text, full: html, text
798c382a4e6e6f2e9ecaf6c47300f8cc2a6e0074 Mon Aug 24 08:54:58 2026 -0700
ts: add a conf subcommand to rewrite httpd.conf without re-freezing, refs #37867
The CORS scoping fix in 4d9755a1 changed the httpd.conf template, but a
parked instance keeps the conf it was created with. All three parked
instances therefore still set Access-Control-Allow-Origin at server
scope, including on cgi-bin. That is the hole 4d9755a1 closed in the
template only.
The one way to pick up a template change was "ts sync", and cmd_sync
calls freeze before writeConf. For a park whose whole point is the
frozen code, re-freezing to the current live sandbox throws away the
thing being kept. There was no way to update only the config.
"ts conf NNNNN" rewrites httpd.conf from the current template, leaves
the frozen cgi-bin and htdocs alone, and restarts the httpd if it was
running. Ran it on all three parked instances: cgi-bin now sends no
Access-Control header, htdocs and trash send both.
switch to commits view, user index