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>&nbsp;&nbsp;</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)