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/lib/basicBed.c src/lib/basicBed.c
index cefe8e06e3c..3ce68aab074 100644
--- src/lib/basicBed.c
+++ src/lib/basicBed.c
@@ -1057,31 +1057,31 @@
 struct rgbColor rgb = bedColorToRgb(color);
 fprintf(f, "%d,%d,%d", rgb.r, rgb.g, rgb.b);
 }
 
 unsigned int bedParseRgb(char *itemRgb)
 /*      parse a string: "r,g,b" with optional ",a" into three or four unsigned
  *      char values returned as 32 bit number, or -1 for failure.  Byte order
  *      has alpha in the highest-order byte, then r, then g, then b in the
  *      lowest-order byte. This is a "bed" concept of an unsigned color,
  *      which may not match the way the graphics libraries handle color bytes. */
 {
 char dupe[64];
 int wordCount;
 char *row[4];
 
-strncpy(dupe, itemRgb, sizeof(dupe));
+safecpy(dupe, sizeof(dupe), itemRgb);
 wordCount = chopString(dupe, ",", row, ArraySize(row));
 
 if ((wordCount == 3) && (isdigit(row[0][0]) &&
     isdigit(row[1][0]) && isdigit(row[2][0])))
         return ( ((atoi(row[0]) & 0xff) << 16) |
                 ((atoi(row[1]) & 0xff) << 8) |
                 (atoi(row[2]) & 0xff) );
 
 if ((wordCount == 4) && (isdigit(row[0][0]) &&
     isdigit(row[1][0]) && isdigit(row[2][0]) && isdigit(row[3][0])))
         return ( ((atoi(row[0]) & 0xff) << 16) |
                 ((atoi(row[1]) & 0xff) << 8) |
                 (atoi(row[2]) & 0xff) |
                 ((atoi(row[3]) & 0xff) << 24) );