b50a995e326f37cb2248e9a04628c15fb1b58215 max Mon Sep 14 05:40:04 2026 -0700 My Sessions no longer hides a user's own "__" sessions, refs #38313 Both My Sessions listings decided a row was a share token by testing the session name for the "__" prefix, so they also hid sessions a user had named that way themselves - eleven of them on the RR, across four accounts, and their owners could no longer rename, describe, reshare or delete them. The prefix is a naming convention we follow, not a namespace we own. The authoritative mark is the "snapshotType <type>" line saveSnapshotSession() already writes into the settings column, so test that instead. Both queries already select settings, so no query changes. snapshotTypeFromSettings() walks the settings lines rather than calling raFromString(): it runs once per listed row, and a hash there costs ~600ns and three allocations for every session that has a description, against ~30ns and none for the walk. Rows with empty settings, the common case, short-circuit in both. diff --git src/hg/hgSession/hgSession.c src/hg/hgSession/hgSession.c index 8c062c68dc5..834b9db5c7c 100644 --- src/hg/hgSession/hgSession.c +++ src/hg/hgSession/hgSession.c @@ -367,32 +367,34 @@ sqlSafef(query, sizeof(query), "SELECT sessionName, shared, firstUse, useCount, contents, settings from %s " "WHERE userName = '%s' ORDER BY sessionName;", namedSessionTable, encUserName); else sqlSafef(query, sizeof(query), "SELECT sessionName, shared, firstUse, useCount, contents from %s " "WHERE userName = '%s' ORDER BY sessionName;", namedSessionTable, encUserName); sr = sqlGetResult(conn, query); int rowIdx = 0; while ((row = sqlNextRow(sr)) != NULL) { char *encSessionName = row[0]; /* A snapshot is a share token, not a session the user made and would recognize (see - * lib/snapshotSession.c). Leave it out of the list, as its "__" prefix promises. */ - if (snapshotIsSnapshotName(encSessionName)) + * lib/snapshotSession.c). Leave it out of the list. Ask the settings column, which + * saveSnapshotSession() stamps with the snapshot type - not the "__" name prefix, which users + * have also used for sessions of their own that they do need to see here (refs #38313). */ + if (gotSettings && snapshotIsSnapshotSettings(row[5])) continue; char *sessionName = cgiDecodeClone(encSessionName); char *link = NULL; int shared = atoi(row[1]); char *firstUse = row[2]; char buf[512]; boolean inGallery = FALSE; boolean hasDescription = FALSE; if (shared >=2) inGallery = TRUE; printf("<TR><TD> </TD><TD>"); char iconId[256]; @@ -2368,33 +2370,35 @@ "SELECT sessionName, shared, firstUse, useCount, contents, settings, lastUse FROM %s " "WHERE userName = '%s' ORDER BY sessionName;", namedSessionTable, encUserName); else sqlSafef(query, sizeof(query), "SELECT sessionName, shared, firstUse, useCount, contents, lastUse FROM %s " "WHERE userName = '%s' ORDER BY sessionName;", namedSessionTable, encUserName); struct sqlResult *sr = sqlGetResult(conn, query); perfTimerStep(hgSessionTiming, "load sessions from MySQL"); char **row; /* Cache one connection per assembly db so the per-session band/locus lookups don't * re-open a connection for every row when many sessions share an assembly. */ struct hash *dbConnCache = hashNew(0); while ((row = sqlNextRow(sr)) != NULL) { char *encSessionName = row[0]; - /* Snapshots are share tokens, not sessions the user made; keep them out of the list, - * as their "__" prefix promises (see lib/snapshotSession.c). */ - if (snapshotIsSnapshotName(encSessionName)) + /* Snapshots are share tokens, not sessions the user made; keep them out of the list. + * The settings column, stamped by saveSnapshotSession(), is what says so - the "__" + * name prefix does not, since users have named their own sessions that way and those + * belong in the list (refs #38313). See lib/snapshotSession.c. */ + if (gotSettings && snapshotIsSnapshotSettings(row[5])) continue; char *sessionName = cgiDecodeClone(encSessionName); int shared = atoi(row[1]); char *firstUse = cloneString(row[2]); struct tm firstUseTm; ZeroVar(&firstUseTm); strptime(firstUse, "%Y-%m-%d %T", &firstUseTm); long epoch = (long)mktime(&firstUseTm); /* created = date only for display; createdFull = date+minute for the hover. */ char *dateOnly = cloneString(firstUse); char *spacePt = strchr(dateOnly, ' '); if (spacePt != NULL) *spacePt = '\0'; char *createdFull = cloneString(firstUse); if (strlen(createdFull) == 19)