8983998334c36e7dfefe608b9a4effe3a10ae9ab braney Fri Aug 21 10:21:02 2026 -0700 hubCheck: give chopByChar the number of slots, not the size of the array, no redmine splitMessages holds sixteen pointers, and the call passed sizeof(splitMessages), which is the byte count. A track that gathers more than sixteen warning lines therefore wrote past the end of it. Twenty filterByRange settings with no matching filter setting is enough to do it, and hgHubConnect runs hubCheck with -htmlOut on any hub address somebody types in. Pass ArraySize instead. The mistake dates from 702afb4c465 in 2020. diff --git src/hg/utils/hubCheck/hubCheck.c src/hg/utils/hubCheck/hubCheck.c index c083c766477..2ec999e3bd1 100644 --- src/hg/utils/hubCheck/hubCheck.c +++ src/hg/utils/hubCheck/hubCheck.c @@ -593,31 +593,31 @@ char *strippedMessage = NULL; char *splitMessages[16]; // SUBGROUP_MAX=9 but add a few extra just in case char parentOrTrackString[512]; char id[512]; static int count = 0; // forces unique ID's which the jstree object needs int numMessages = 0; int i = 0; // if a subtrack is missing multiple subgroups, then message will contain // at least two newline separated errors, both should be printed separately: if (message) { strippedMessage = cloneString(message); while (lastChar(strippedMessage) == '\n') trimLastChar(strippedMessage); - numMessages = chopByChar(strippedMessage, '\n', splitMessages, sizeof(splitMessages)); + numMessages = chopByChar(strippedMessage, '\n', splitMessages, ArraySize(splitMessages)); } for (; i < numMessages; i++) { if (isNotEmpty(splitMessages[i])) { safef(id, sizeof(id), "%s%d", trackHubSkipHubName(tdb->track), count); safef(parentOrTrackString, sizeof(parentOrTrackString), "%s_%s", trackHubSkipHubName(genome->name), trackHubSkipHubName(tdb->track)); dyStringPrintf(errors, "%s,", makeChildObjectString(id, "TrackDb Error", tdb->shortLabel, tdb->longLabel, "#550073", trackHubSkipHubName(tdb->track), splitMessages[i], parentOrTrackString)); count++; } } }