9c7de0bd83bc6e1876dc0b8b7091127629a07bf0 chmalee Thu Mar 5 14:32:25 2026 -0800 Fix array size bounds check for /getData/track endpoint to actually limit to 100 requested tracks diff --git src/hg/hubApi/getData.c src/hg/hubApi/getData.c index 896e3b7949b..77ecca7d9cc 100644 --- src/hg/hubApi/getData.c +++ src/hg/hubApi/getData.c @@ -468,32 +468,34 @@ if (NULL == tdb) apiErrAbort(err400, err400Msg, "failed to find a track hub definition in genome=%s for endpoint '/getData/track' given hubUrl='%s'", genome, hubUrl); struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "hubUrl", hubUrl); jsonWriteString(jw, "genome", genome); struct jsonWrite *columnTypesJw = NULL; if (jsonOutputArrays || debug) { columnTypesJw = jsonWriteNew(); jsonWriteObjectStart(columnTypesJw, "columnTypes"); } // allow optional comma sep list of tracks -char *tracks[100]; -int numTracks = chopByChar(trackArg, ',', tracks, sizeof(tracks)); +char *tracks[MAX_NUM_TRACKS + 1]; +int numTracks = chopByChar(trackArg, ',', tracks, MAX_NUM_TRACKS+1); +if (numTracks > MAX_NUM_TRACKS) + apiErrAbort(err400, err400Msg, "too many tracks requested, limit to 100 tracks or less for endpoint '/getData/track"); int i = 0; for (i = 0; i < numTracks; i++) { char *track = cloneString(tracks[i]); struct trackDb *thisTrack = findTrackDb(track, tdb); if (NULL == thisTrack) apiErrAbort(err400, err400Msg, "failed to find specified track=%s in genome=%s for endpoint '/getData/track' given hubUrl='%s'", track, genome, hubUrl); if (trackHasNoData(thisTrack)) apiErrAbort(err400, err400Msg, "container track '%s' does not contain data, use the children of this container for data access", track); if (! isSupportedType(thisTrack->type)) apiErrAbort(err415, err415Msg, "track type '%s' for track=%s not supported at this time", thisTrack->type, track); char *bigDataUrl = trackDbSetting(thisTrack, "bigDataUrl"); struct bbiFile *bbi = bigFileOpen(thisTrack->type, bigDataUrl); if (NULL == bbi) @@ -607,32 +609,34 @@ /* database existence has already been checked before now, might * have disappeared in the mean time (well, not really . . .) */ struct sqlConnection *conn = hAllocConnMaybe(db); if (NULL == conn) apiErrAbort(err400, err400Msg, "can not find genome 'genome=%s' for endpoint '/getData/track", db); struct jsonWrite *jw = apiStartOutput(); jsonWriteString(jw, "genome", db); // load the tracks struct trackDb *tdbList = NULL; cartTrackDbInitForApi(NULL, db, &tdbList, NULL, TRUE); // allow optional comma sep list of tracks -char *tracks[100]; -int numTracks = chopByChar(trackArg, ',', tracks, sizeof(tracks)); +char *tracks[MAX_NUM_TRACKS+1]; +int numTracks = chopByChar(trackArg, ',', tracks, MAX_NUM_TRACKS+1); +if (numTracks > MAX_NUM_TRACKS) + apiErrAbort(err400, err400Msg, "too many tracks requested, limit to 100 tracks or less for endpoint '/getData/track"); int i = 0; struct hash *trackHash = hashNew(0); // let hub tracks work struct jsonWrite *columnTypesJw = NULL; if (jsonOutputArrays || debug) { columnTypesJw = jsonWriteNew(); jsonWriteObjectStart(columnTypesJw, "columnTypes"); } for (i = 0; i < numTracks; i++) { char *track = cloneString(tracks[i]); char *sqlTable = cloneString(track); if (cartTrackDbIsAccessDenied(db, sqlTable) || (cartTrackDbIsNoGenome(db, sqlTable) && !(chrom && start && end)))