595531f894a27e59e18b32436f6cb932fa4374a0 lrnassar Tue Sep 8 13:03:44 2026 -0700 BLAT form character counter: per-type limits passed through from the C constants. refs #38293 The counter showed the 75,000 DNA limit for every query type; protein and translated queries are capped at 10,000, so an oversized protein paste looked fine until the server rejected it. The per-sequence limits are now named constants in hgBlat.c, emitted into hgBlatFormData and read by the counter, which keys on the Query type dropdown and recounts when it changes - so the numbers cannot drift apart again. BLAT's guess counts against the DNA limit. diff --git src/hg/hgBlat/hgBlat.c src/hg/hgBlat/hgBlat.c index 6188f8fe540..b0e25eb588a 100644 --- src/hg/hgBlat/hgBlat.c +++ src/hg/hgBlat/hgBlat.c @@ -52,30 +52,36 @@ struct hash *oldVars = NULL; struct perfTimer *hgBlatTiming = NULL; /* Non-NULL when &measureTiming is set; times the request * and is emitted as hgBlatData.timing for the JS dialog. */ boolean orgChange = FALSE; boolean dbChange = FALSE; boolean allGenomes = FALSE; boolean allResults = FALSE; boolean autoRearr = FALSE; static long enteredMainTime = 0; boolean autoBigPsl = FALSE; // DEFAULT VALUE change to TRUE in future /* for earlyBotCheck() function at the beginning of main() */ #define delayFraction 0.5 /* standard penalty is 1.0 for most CGIs */ + +/* Per-sequence query size limits, enforced below and shown by the new form's character counter + * (emitted into hgBlatFormData so the C and JS numbers cannot drift apart). The total limit for + * a multi-sequence submission is 2.5x the per-sequence limit. */ +#define maxSingleSizeDna 75000 +#define maxSingleSizeTx 10000 /* protein and translated queries */ /* this one is 0.5 */ static boolean issueBotWarning = FALSE; struct gfResult /* Detailed gfServer results, this is a span of several nearby tiles, minimum 2 for dna. */ { struct gfResult *next; /* have to multiply translated coordinates by 3 */ int qStart; /* Query Start Coordinate */ int qEnd; /* Query End Coordinate */ char *chrom; /* Target Chrom Name */ int tStart; /* Target Start Coordinate */ int tEnd; /* Target End Coordinate */ int numHits; /* number of tile hits, minimum 2 for dna */ char tStrand; /* + or - Target Strand used with prot, rnax, dnax */ @@ -2244,31 +2250,31 @@ if (seqList != NULL && seqList->name[0] == 0) { freeMem(seqList->name); seqList->name = cloneString("YourSeq"); } trimUniq(seqList); /* If feeling lucky only do the first one. */ if(feelingLucky && seqList != NULL) { seqList->next = NULL; } /* Figure out size allowed. */ -maxSingleSize = (isTx ? 10000 : 75000); +maxSingleSize = (isTx ? maxSingleSizeTx : maxSingleSizeDna); maxTotalSize = maxSingleSize * 2.5; #ifdef LOWELAB maxSeqCount = 200; #else maxSeqCount = 25; #endif char *optionMaxSeqCount = cfgOptionDefault("hgBlat.maxSequenceCount", NULL); if (isNotEmpty(optionMaxSeqCount)) maxSeqCount = sqlSigned(optionMaxSeqCount); /* Create temporary file to store sequence. */ trashDirFile(&faTn, "hgSs", "hgSs", ".fa"); faWriteAll(faTn.forCgi, seqList); @@ -2802,30 +2808,33 @@ jsonWriteBoolean(jw, "autoRearr", autoRearr); jsonWriteBoolean(jw, "allGenomes", allGenomes); /* "Keep results" only means something on a machine configured to clear earlier BLAT result tracks. * With blatOldTracks at its "keep" default, or at "hide", there is nothing to opt out of, so the * checkbox is not shown at all. hgc.c (buildBigPsl) is what acts on blatKeepResults. */ jsonWriteBoolean(jw, "showKeepResults", sameString(cfgOptionDefault("blatOldTracks", "keep"), "delete")); jsonWriteBoolean(jw, "keepResults", cartUsualBoolean(cart, "blatKeepResults", FALSE)); /* "Keep only last search" checkbox (RM #38086): the inverse framing - results accumulate by * default (the current public behavior) and checking the box opts into removing earlier BLAT * result tracks on each new search. Gated by its own hg.conf setting, independent of * blatOldTracks above; hgc.c (buildBigPsl) is what acts on blatOnlyLatest. */ jsonWriteBoolean(jw, "showOnlyLatest", sameString(cfgOptionDefault("blatOnlyLatestCheckbox", "off"), "on")); jsonWriteBoolean(jw, "onlyLatest", cartUsualBoolean(cart, "blatOnlyLatest", FALSE)); +/* The enforced per-sequence limits, so the character counter shows the right cap per query type. */ +jsonWriteNumber(jw, "maxSingleDna", maxSingleSizeDna); +jsonWriteNumber(jw, "maxSingleTx", maxSingleSizeTx); /* The example is fetched on demand rather than inlined: it is a real 2.5 kb sequence, which would * otherwise be embedded in every page load of the form just to serve the few users who click * "Load example". The sequence is a window over two PTP4A3 exons that is also carried by an alt * haplotype and a fix patch of chr8, so the results table shows the alt/fix rows and their * explanatory icons rather than a single boring hit. */ jsonWriteString(jw, "exampleUrl", "../goldenPath/help/blatExample.fa"); jsonWriteString(jw, "exampleLabel", "Load example"); jsonWriteString(jw, "exampleTitle", "Fill the box with an example query: " "2.5 kb of the human PTP4A3 gene."); /* Same "similar tools" links the classic page offered, so the sidebar isn't a set of dead links. * These carry $DB$ rather than a baked-in db: picking a genome no longer reloads the page, so * blatFormSetDb() re-expands them against the newly chosen assembly. * * Deliberately NOT gated on hgPcrOk() the way the classic form was. That test can only be made for * the assembly the page happened to load with, so on a page where the genome can be changed without