4fd52b1b34d170c15d3aacfeaf4fbb26fff224b1
hiram
  Wed Mar 25 12:52:00 2026 -0700
fix bugs for chrom size at 2^31 and manage partial computation windows at beginning or end of drawing window for gcOnFly refs #35958

diff --git src/hg/lib/wigDataStream.c src/hg/lib/wigDataStream.c
index af7a2a235e7..80c7cf9b373 100644
--- src/hg/lib/wigDataStream.c
+++ src/hg/lib/wigDataStream.c
@@ -2307,42 +2307,65 @@
  * retWindows with an allocated array.  Caller must freeMem(*retWindows). */
 {
 struct dnaSeq *seq = hChromSeq(db, chrom, start, end);
 if (seq == NULL)
     {
     *retWindows = NULL;
     return 0;
     }
 
 int seqLen = end - start;
 /* Align to winSize-base chromosome boundary, not the fetch boundary.
  * startOffset is the number of bases into the fetched sequence where
  * the first chromosome-aligned window begins. */
 int startOffset = (winSize - (start % winSize)) % winSize;
 
-/* Upper bound on number of windows */
-int maxWindows = (seqLen - startOffset + winSize - 1) / winSize;
+/* Upper bound on number of windows (+ 1 for possible leading partial) */
+int maxWindows = (seqLen - startOffset + winSize - 1) / winSize + 1;
 struct gcOnTheFlyWindow *windows;
 AllocArray(windows, maxWindows);
 
 int count = 0;
+
+/* Handle leading partial window if fetch starts mid-window */
+if (startOffset > 0)
+    {
+    int gcCount = 0, validBases = 0;
+    int i;
+    for (i = 0; i < startOffset; i++)
+        {
+        char b = seq->dna[i];
+        if (b == 'g' || b == 'c')  { gcCount++;  validBases++; }
+        else if (b != 'n')           validBases++;
+        }
+    if (validBases > 0)
+        {
+        windows[count].chromStart = start;
+        windows[count].gcPct = 100.0 * gcCount / validBases;
+        count++;
+        }
+    }
+
 int pos;
-for (pos = startOffset; pos + winSize <= seqLen; pos += winSize)
+for (pos = startOffset; pos < seqLen; pos += winSize)
     {
+    int windowEnd = pos + winSize;
+    if (windowEnd > seqLen)
+        windowEnd = seqLen;        /* partial window at end of chrom */
     int gcCount = 0, validBases = 0;
     int i;
-    for (i = pos; i < pos + winSize; i++)
+    for (i = pos; i < windowEnd; i++)
         {
         char b = seq->dna[i];
         if (b == 'g' || b == 'c')  { gcCount++;  validBases++; }
         else if (b != 'n')           validBases++;
         }
     if (validBases == 0)
         continue;
     windows[count].chromStart = start + pos;
     windows[count].gcPct = 100.0 * gcCount / validBases;
     count++;
     }
 
 dnaSeqFree(&seq);
 *retWindows = windows;
 return count;