fb50a1cca3a117bb964c43196671142484b13bf9
braney
  Fri Jun 12 12:10:47 2026 -0700
lib jkOwnLib hg/lib: fix warnings exposed by -O3 build

At -O3 GCC does more inlining and interprocedural range analysis, which
surfaces several warnings that -O -g never triggered.  With -Werror these
break the build, so fix them ahead of switching the default to -O3.

- bamFile.c: move setenv() into the else of its NULL guard so it is not
reachable with a NULL argument (-Wnonnull, seen via inlining of bamFetch).
- basicBed.c, wormdna.c, bedDetail.c, customFactory.c, hdb.c, qaSeq.c:
replace strncpy() with safecpy() where the result must be terminated
(-Wstringop-truncation).
- htmshell.c: use memcpy() for the intentional exact-length, non-terminated
copy (-Wstringop-truncation).
- obscure.c: compute the comma groups in sprintLongWithCommas() with % 1000
so the compiler can see each %03lld argument is bounded (-Wformat-overflow).
- crudeali.c: do the endian type-pun through a union so strict-aliasing
analysis no longer reports the value as uninitialized (-Wuninitialized).
- jksql.c: wrap a possibly-NULL database name in naForNull() before passing
it to %s (-Wformat-overflow).

refs #37761

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

diff --git src/hg/lib/hdb.c src/hg/lib/hdb.c
index 68d953b9431..eb891021d51 100644
--- src/hg/lib/hdb.c
+++ src/hg/lib/hdb.c
@@ -2292,31 +2292,31 @@
     if (hti->strandField[0] != 0)
 	if (sameString("tStarts", hti->startsField))
 	    {
 	    // psl: use XOR of qStrand,tStrand if both are given.
 	    qStrand = row[4][0];
 	    tStrand = row[4][1];
 	    if ((tStrand != '+') && (tStrand != '-'))
 		bedItem->strand[0] = qStrand;
 	    else if ((qStrand == '-' && tStrand == '+') ||
 		     (qStrand == '+' && tStrand == '-'))
 		strncpy(bedItem->strand, "-", 2);
 	    else
 		strncpy(bedItem->strand, "+", 2);
 	    }
 	else
-	    strncpy(bedItem->strand, row[4], 2);
+	    safecpy(bedItem->strand, sizeof(bedItem->strand), row[4]);
     else
 	strcpy(bedItem->strand, ".");
     if (canDoUTR)
 	{
 	bedItem->thickStart = atoi(row[5]);
 	bedItem->thickEnd   = atoi(row[6]);
 	/* thickStart, thickEnd fields are sometimes used for other-organism
 	   coords (e.g. synteny100000, syntenyBuild30).  So if they look
 	   completely wrong, fake them out to start/end.  */
 	if (bedItem->thickStart < bedItem->chromStart)
 	    bedItem->thickStart = bedItem->chromStart;
 	else if (bedItem->thickStart > bedItem->chromEnd)
 	    bedItem->thickStart = bedItem->chromStart;
 	if (bedItem->thickEnd < bedItem->chromStart)
 	    bedItem->thickEnd = bedItem->chromEnd;