080a160c7b9595d516c9c70e83689a09b60839d0 galt Mon Jun 3 12:16:53 2013 -0700 fix SQL Injection diff --git src/hg/lib/hgFind.c src/hg/lib/hgFind.c index 8af4b17..eb79c9e 100644 --- src/hg/lib/hgFind.c +++ src/hg/lib/hgFind.c @@ -362,32 +362,32 @@ } return writeIx; } static struct slName *doGrepQuery(char *indexFile, char *table, char *key, char *extraOptions) /* grep -i key indexFile, return a list of ids (first word of each line). */ { struct pipeline *pl = NULL; struct slName *idList = NULL; struct lineFile *lf = NULL; char *id, *rest, *line; char *keyWords[HGFIND_MAX_KEYWORDS]; char **cmds[HGFIND_MAX_KEYWORDS+1]; -/* No need to escape special chars here, it's already been done: */ -char *escapedKey = cloneString(key); +/* escape special chars here */ +char *escapedKey = sqlEscapeString(key); /* presumably this is the right way escape it? -Galt*/ int keyCount; touppers(escapedKey); keyCount = chopLine(escapedKey, keyWords); keyCount = removeTooCommon(table, keyWords, keyCount); if (keyCount > 0) { if (extraOptions == NULL) extraOptions = ""; makeCmds(cmds, keyWords, keyCount, extraOptions); pl = pipelineOpen(cmds, pipelineRead | pipelineNoAbort, indexFile, NULL); lf = pipelineLineFile(pl); verbose(3, "\n***Running this fgrep command with pipeline from %s:\n*** %s\n\n", indexFile, pipelineDesc(pl)); @@ -415,61 +415,61 @@ } static char *MrnaIDforGeneName(char *db, char *geneName) /* return mRNA ID for a gene name */ { struct sqlConnection *conn; struct sqlResult *sr = NULL; char query[256]; char **row; char *result = NULL; conn = hAllocConn(db); if (sqlTableExists(conn, "refLink")) { - safef(query, sizeof(query), "SELECT mrnaAcc FROM refLink WHERE name='%s'", + sqlSafef(query, sizeof(query), "SELECT mrnaAcc FROM refLink WHERE name='%s'", geneName); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { result = cloneString(row[0]); } else { result = NULL; } sqlFreeResult(&sr); } hFreeConn(&conn); return result; } char *MrnaIDforProtein(char *db, char *proteinID) /* return mRNA ID for a protein */ { struct sqlConnection *conn; struct sqlResult *sr = NULL; struct dyString *query; char **row; char * result; conn = hAllocConn(db); query = newDyString(256); -dyStringPrintf(query, "SELECT mrnaID FROM spMrna WHERE spID='%s'", proteinID); +sqlDyStringPrintf(query, "SELECT mrnaID FROM spMrna WHERE spID='%s'", proteinID); sr = sqlGetResult(conn, query->string); if ((row = sqlNextRow(sr)) != NULL) { result = cloneString(row[0]); } else { result = NULL; } freeDyString(&query); sqlFreeResult(&sr); hFreeConn(&conn); return result; } @@ -482,42 +482,40 @@ struct sqlResult *sr = NULL; struct dyString *query; char **row; boolean ok = FALSE; struct hgPosTable *table = NULL; struct hgPos *pos = NULL; int rowOffset; char *localName; localName = spec; if (!hTableExists(db, tableName)) return FALSE; rowOffset = hOffsetPastBin(db, NULL, tableName); conn = hAllocConn(db); query = newDyString(256); -dyStringPrintf(query, +sqlDyStringPrintf(query, "SELECT chrom, txStart, txEnd, name FROM %s WHERE name='%s'", tableName, localName); sr = sqlGetResult(conn, query->string); while ((row = sqlNextRow(sr)) != NULL) { if (ok == FALSE) { ok = TRUE; AllocVar(table); - dyStringClear(query); - dyStringPrintf(query, "%s Gene Predictions", tableName); if (hTableExists(db, "kgProtMap2")) table->description = cloneString("UCSC Genes"); else table->description = cloneString("Known Genes"); table->name = cloneString("knownGene"); slAddHead(&hgp->tableList, table); } AllocVar(pos); pos->chrom = hgOfficialChromName(db, row[0]); pos->chromStart = atoi(row[1]); pos->chromEnd = atoi(row[2]); pos->name = cloneString(geneSymbol); /* pos->browserName = cloneString(geneSymbol); highlight change */ pos->browserName = cloneString(row[3]); slAddHead(&table->posList, pos); @@ -595,64 +593,60 @@ tsr = slElementFromIx(tsrList, maxToReturn-1); tsr->next = NULL; } /* Make hash of all search results - one for each known gene ID. */ for (tsr = tsrList; tsr != NULL; tsr = tsr->next) { lmAllocVar(hash->lm, tp); tp->tsr = tsr; slAddHead(&tpList, tp); hashAdd(hash, tsr->itemId, tp); } /* Stream through knownGenes table and make up a pos * for each mapping of each gene matching search. */ -dyStringAppend(dy, +sqlDyStringAppend(dy, "select name,chrom,txStart,txEnd from knownGene where name in ("); for (tsr = tsrList; tsr != NULL; tsr = tsr->next) { - dyStringAppendC(dy, '"'); - dyStringAppend(dy, tsr->itemId); - dyStringAppendC(dy, '"'); + sqlDyStringPrintf(dy, "'%s'", tsr->itemId); if (tsr->next != NULL) dyStringAppendC(dy, ','); } dyStringAppend(dy, ")"); sr = sqlGetResult(conn, dy->string); while ((row = sqlNextRow(sr)) != NULL) { tp = hashFindVal(hash, row[0]); if (tp == NULL) internalErr(); AllocVar(pos); pos->chrom = cloneString(row[1]); pos->chromStart = sqlUnsigned(row[2]); pos->chromEnd = sqlUnsigned(row[3]); slAddHead(&tp->posList, pos); } sqlFreeResult(&sr); /* Stream through kgXref table adding description and geneSymbol */ dyStringClear(dy); -dyStringAppend(dy, +sqlDyStringAppend(dy, "select kgID,geneSymbol,description from kgXref where kgID in ("); for (tsr = tsrList; tsr != NULL; tsr = tsr->next) { - dyStringAppendC(dy, '"'); - dyStringAppend(dy, tsr->itemId); - dyStringAppendC(dy, '"'); + sqlDyStringPrintf(dy, "'%s'", tsr->itemId); if (tsr->next != NULL) dyStringAppendC(dy, ','); } dyStringAppend(dy, ")"); sr = sqlGetResult(conn, dy->string); while ((row = sqlNextRow(sr)) != NULL) { tp = hashFindVal(hash, row[0]); if (tp == NULL) internalErr(); for (pos = tp->posList; pos != NULL; pos = pos->next) { char nameBuf[256]; safef(nameBuf, sizeof(nameBuf), "%s (%s)", row[1], row[0]); pos->name = cloneString(nameBuf); @@ -715,31 +709,31 @@ struct sqlResult *sr = NULL; struct dyString *query; char **row; boolean ok = FALSE; struct hgPosTable *table = NULL; struct hgPos *pos = NULL; int rowOffset; char *localName; localName = spec; if (!hTableExists(db, tableName)) return FALSE; rowOffset = hOffsetPastBin(db, NULL, tableName); conn = hAllocConn(db); query = newDyString(256); -dyStringPrintf(query, "SELECT chrom, txStart, txEnd, name, description FROM %s, kgXref " +sqlDyStringPrintf(query, "SELECT chrom, txStart, txEnd, name, description FROM %s, kgXref " "WHERE description LIKE '%%%s%%' and kgId=name", tableName, localName); sr = sqlGetResult(conn, query->string); while ((row = sqlNextRow(sr)) != NULL) { if (ok == FALSE) { ok = TRUE; table = addKnownGeneTable(db, hgp); } AllocVar(pos); pos->chrom = hgOfficialChromName(db, row[0]); pos->chromStart = atoi(row[1]); pos->chromEnd = atoi(row[2]); pos->name = cloneString(row[3]); @@ -762,31 +756,31 @@ struct sqlResult *sr = NULL; struct dyString *query; char **row; boolean ok = FALSE; struct hgPosTable *table = NULL; struct hgPos *pos = NULL; int rowOffset; char *localName; localName = spec; if (!hTableExists(db, tableName)) return FALSE; rowOffset = hOffsetPastBin(db, NULL, tableName); conn = hAllocConn(db); query = newDyString(256); -dyStringPrintf(query, "SELECT chrom, txStart, txEnd, name FROM %s " +sqlDyStringPrintf(query, "SELECT chrom, txStart, txEnd, name FROM %s " "WHERE name LIKE '%s%%'", tableName, localName); sr = sqlGetResult(conn, query->string); while ((row = sqlNextRow(sr)) != NULL) { if (ok == FALSE) { ok = TRUE; table = addKnownGeneTable(db, hgp); slAddHead(&hgp->tableList, table); } AllocVar(pos); pos->chrom = hgOfficialChromName(db, row[0]); pos->chromStart = atoi(row[1]); @@ -907,31 +901,31 @@ num = atoi(chrom); if (num < 1 || num > 22) return NULL; safef(buf, sizeof(buf), "chr%d", num); return hgOfficialChromName(db, buf); } static struct cytoBand *loadAllBands(char *db) /* Load up all bands from database. */ { struct cytoBand *list = NULL, *el; struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr = NULL; char **row; -sr = sqlGetResult(conn, "select * from cytoBand"); +sr = sqlGetResult(conn, "NOSQLINJ select * from cytoBand"); while ((row = sqlNextRow(sr)) != NULL) { el = cytoBandLoad(row); slAddHead(&list, el); } sqlFreeResult(&sr); slReverse(&list); hFreeConn(&conn); return list; } static struct cytoBand *bandList = NULL; void hgFindChromBand(char *db, char *chromosome, char *band, int *retStart, int *retEnd) /* Return start/end of band in chromosome. */ @@ -1090,56 +1084,56 @@ boolean findChromContigPos(char *db, char *name, char **retChromName, int *retWinStart, int *retWinEnd) /* Find position in genome of contig. Look in all chroms. * Don't alter return variables unless found. */ /* NOTE: could probably speed this up by using the chromInfo hashtable */ { struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr = NULL; char **row; char query[256]; boolean foundIt = FALSE; /* In case this is a scaffold-based assembly, check for unsplit table first: */ if (sqlTableExists(conn, "gold")) { - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select chrom,chromStart,chromEnd from gold where frag = '%s'", name); sr = sqlMustGetResult(conn, query); row = sqlNextRow(sr); if (row != NULL) { *retChromName = cloneString(row[0]); *retWinStart = atoi(row[1]); *retWinEnd = atoi(row[2]); foundIt = TRUE; } sqlFreeResult(&sr); } else { struct slName *allChroms = hAllChromNames(db); struct slName *chromPtr; for (chromPtr=allChroms; chromPtr != NULL; chromPtr=chromPtr->next) { char tableName[256]; safef(tableName, sizeof(tableName), "%s_gold", chromPtr->name); if (! sqlTableExists(conn, tableName)) continue; - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select chromStart,chromEnd from %s where frag = '%s'", tableName, name); sr = sqlMustGetResult(conn, query); row = sqlNextRow(sr); if (row != NULL) { *retChromName = cloneString(chromPtr->name); *retWinStart = atoi(row[0]); *retWinEnd = atoi(row[1]); foundIt = TRUE; } sqlFreeResult(&sr); if (foundIt) break; } @@ -1164,31 +1158,31 @@ } #endif static boolean mrnaInfo(char *acc, struct sqlConnection *conn, char **mrnaType) /* Sets *mrnaType to mrna/est type for the accession */ /* Ignores returned values if parameters are NULL */ /* Return TRUE if search succeeded, else FALSE */ /* NOTE: caller must free mrnaType */ { char query[256]; struct sqlResult *sr; char **row; int ret; -safef(query, sizeof(query), +sqlSafef(query, sizeof(query), "select type from gbCdnaInfo where acc = '%s'", acc); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { if (mrnaType != NULL) *mrnaType = cloneString(row[0]); ret = TRUE; } else ret = FALSE; sqlFreeResult(&sr); return ret; } boolean isRefSeqAcc(char *acc) @@ -1265,31 +1259,31 @@ char *vis = cart ? cartOptionalString(cart, trackName) : NULL; if (vis && sameString(vis, "full")) return "full"; else return hTrackOpenVis(db, trackName); } static struct psl *getPslFromTable(struct sqlConnection *conn, char *db, char *table, char *acc) /* If table exists, return PSL for each row with qName = acc. */ { struct psl *pslList = NULL; if (sqlTableExists(conn, table)) { int rowOffset = hOffsetPastBin(db, NULL, table); char query[256]; - safef(query, sizeof(query), "select * from %s where qName = '%s'", table, acc); + sqlSafef(query, sizeof(query), "select * from %s where qName = '%s'", table, acc); struct sqlResult *sr = sqlGetResult(conn, query); char **row; while ((row = sqlNextRow(sr)) != NULL) { struct psl *psl = pslLoad(row+rowOffset); slAddHead(&pslList, psl); } slReverse(&pslList); sqlFreeResult(&sr); } return pslList; } static void addPslResultToHgp(struct hgPositions *hgp, char *db, char *tableName, char *shortLabel, char *acc, struct psl *pslList) @@ -1426,48 +1420,50 @@ if (grepIndexRoot != NULL && hfsSetting != NULL) { char buf[1024]; safef(buf, sizeof(buf), "%s/%s/%s.%s", grepIndexRoot, db, table, suffix); if (fileExists(buf)) return cloneString(buf); } return NULL; } static struct slName *genbankGrepQuery(char *indexFile, char *table, char *key) /* grep -i key indexFile, return a list of ids (first word of each line). */ { +//verbose(1,"genbankGrepQuery table=[%s] key=[%s]\n", table, key); // DEBUG REMOVE char *extraOptions = ""; if (sameString(table, "author")) extraOptions = "-w"; return doGrepQuery(indexFile, table, key, extraOptions); } static struct slName *genbankSqlFuzzyQuery(struct sqlConnection *conn, char *table, char *key) /* Perform a fuzzy sql search for %key% in table.name; return list of * corresponding table.id's. */ { +//verbose(1,"genbankSqlFuzzyQuery table=[%s] key=[%s]\n", table, key); // DEBUG REMOVE struct slName *idList = NULL, *idEl = NULL; if (!isTooCommon(table, key)) { struct sqlResult *sr; char **row; char query[256]; - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select id,name from %s where name like '%%%s%%'", table, key); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { touppers(row[1]); if (keyIsPrefix(key, row[1])) { idEl = newSlName(row[0]); slAddHead(&idList, idEl); } } sqlFreeResult(&sr); } return idList; } @@ -1476,58 +1472,60 @@ char *tables[], int tableCount) /* Return TRUE if all tables have a readable genbank index file. */ { int i; for (i=0; i < tableCount; i++) if (! getGenbankGrepIndex(db, hfs, tables[i], "idName")) return FALSE; return TRUE;; } static void findHitsToTables(char *db, struct hgFindSpec *hfs, char *key, char *tables[], int tableCount, struct hash **retHash, struct slName **retList) /* Return all unique accessions that match any table. */ { +//verbose(1,"findHitsToTables db=[%s] key=[%s]\n", db, key); // DEBUG REMOVE struct slName *list = NULL, *el; struct hash *hash = newHash(0); struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr; char **row; char query[256]; char *field; int i; for (i = 0; inext) { /* don't check srcDb to exclude refseq for compat with older tables */ - safef(query, sizeof(query), + //verbose(1,"findHitsToTables field=[%s] idEl->name=[%s]\n", field, idEl->name); // DEBUG REMOVE + sqlSafef(query, sizeof(query), "select acc, organism from gbCdnaInfo where %s = %s " " and type = 'mRNA'", field, idEl->name); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { char *acc = row[0]; /* will use this later to distinguish xeno mrna */ int organismID = sqlUnsigned(row[1]); if (!isRefSeqAcc(acc) && !hashLookup(hash, acc)) { el = newSlName(acc); slAddHead(&list, el); hashAddInt(hash, acc, organismID); } @@ -1564,31 +1562,31 @@ *retHash = hash; *retList = list; } static void mrnaKeysHtmlOnePos(struct hgPosTable *table, struct hgPos *pos, FILE *f) { fprintf(f, "%s", pos->description); } static boolean mrnaAligns(struct sqlConnection *conn, char *table, char *acc) /* Return TRUE if accession is in the designated alignment table (for speed, * this assumes that we've already checked that the table exists) */ { char query[256]; -safef(query, sizeof(query), +sqlSafef(query, sizeof(query), "select count(*) from %s where qName = '%s'", table, acc); return (sqlQuickNum(conn, query) > 0); } static int addMrnaPositionTable(char *db, struct hgPositions *hgp, struct slName **pAccList, struct hash *accOrgHash, struct cart *cart, struct sqlConnection *conn, char *hgAppName, boolean aligns, boolean isXeno) /* Generate table of positions that match criteria. * Add to hgp if any found. Return number found */ { struct hgPosTable *table = NULL; struct hgPos *pos = NULL; struct slName *el = NULL; @@ -1607,31 +1605,31 @@ boolean mrnaTableExists = hTableExists(hgp->database, mrnaTable); AllocVar(table); /* Examine all accessions to see if they fit criteria for * this table. Add all matching to the position list, and * remove from the accession list */ for (el = *pAccList; el != NULL; el = el->next) { freez(&elToFree); acc = el->name; /* check if item matches xeno criterion */ if (hTableExists(db, "gbStatus")) { - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select (orgCat = 'native' && srcDb != 'RefSeq') from gbStatus where acc = '%s'", acc); /* redmine #3301 */ if (isXeno == sqlQuickNum(conn, query)) continue; } else { int itemOrganismID = hashIntVal(accOrgHash, acc); if (isXeno == (itemOrganismID == organismID)) continue; } /* check if item matches alignment criterion */ if (aligns != (mrnaTableExists && mrnaAligns(conn, mrnaTable, acc))) continue; @@ -1649,46 +1647,46 @@ } else { /* display mRNA details page -- need to add dummy CGI variables*/ dyStringPrintf(dy, "", hgp->extraCgi); dyStringPrintf(dy, "%s", acc); /* print description for item, or lacking that, the product name */ safef(description, sizeof(description), "%s", "n/a"); - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select description.name from gbCdnaInfo,description" " where gbCdnaInfo.acc = '%s' and gbCdnaInfo.description = description.id", acc); sqlQuickQuery(conn, query, description, sizeof(description)); if (sameString(description, "n/a")) { /* look for product name */ - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select productName.name from gbCdnaInfo,productName" " where gbCdnaInfo.acc = '%s' and gbCdnaInfo.productName = productName.id", acc); sqlQuickQuery(conn, query, product, sizeof(product)); if (!sameString(product, "n/a")) { /* get organism name */ - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select organism.name from gbCdnaInfo,organism" " where gbCdnaInfo.acc = '%s' and gbCdnaInfo.organism = organism.id", acc); *organism = 0; sqlQuickQuery(conn, query, organism, sizeof(organism)); safef(description, sizeof(description), "%s%s%s", *organism ? organism : "", *organism ? ", " : "", product); } } if (!sameString(description, "n/a")) /* print description if it has been loaded */ dyStringPrintf(dy, " - %s", description); dyStringPrintf(dy, "\n"); pos->description = cloneString(dy->string); @@ -1855,31 +1853,31 @@ slAddHead(&hgp->tableList, table); table->description = cloneString("Known Genes"); table->name = cloneString("knownGene"); for (kl = kaList; kl != NULL; kl = kl->next) { /* Don't return duplicate mrna accessions */ if (hashFindVal(hash, kl->kgID)) { hashAdd(hash, kl->kgID, kl); continue; } hashAdd(hash, kl->kgID, kl); dyStringClear(ds); - dyStringPrintf(ds, "select * from knownGene where name = '%s'", + sqlDyStringPrintf(ds, "select * from knownGene where name = '%s'", kl->kgID); sr = sqlGetResult(conn, ds->string); while ((row = sqlNextRow(sr)) != NULL) { gp = genePredLoad(row); AllocVar(pos); slAddHead(&table->posList, pos); pos->name = cloneString(kl->alias); #if UNUSED pos->browserName = cloneString(kl->alias); // highlight change #endif pos->browserName = cloneString(kl->kgID); safef(cond_str, sizeof(cond_str), "kgID = '%s'", kl->kgID); answer = sqlGetField(db, "kgXref", "description", cond_str); @@ -1943,31 +1941,31 @@ slAddHead(&hgp->tableList, table); table->description = cloneString("Known Genes"); table->name = cloneString("knownGene"); for (kl = kpaList; kl != NULL; kl = kl->next) { /* Don't return duplicate mrna accessions */ if (hashFindVal(hash, kl->kgID)) { hashAdd(hash, kl->kgID, kl); continue; } hashAdd(hash, kl->kgID, kl); dyStringClear(ds); - dyStringPrintf(ds, "select * from knownGene where name = '%s'", + sqlDyStringPrintf(ds, "select * from knownGene where name = '%s'", kl->kgID); sr = sqlGetResult(conn, ds->string); while ((row = sqlNextRow(sr)) != NULL) { gp = genePredLoad(row); AllocVar(pos); slAddHead(&table->posList, pos); pos->name = cloneString(kl->alias); /* pos->browserName = cloneString(kl->alias); highlight change */ pos->browserName = cloneString(kl->kgID); safef(cond_str, sizeof(cond_str), "kgID = '%s'", kl->kgID); answer = sqlGetField(db, "kgXref", "description", cond_str); if (answer != NULL) { @@ -2010,115 +2008,116 @@ } sqlFreeResult(&sr); } static void addRefLinkAccs(struct sqlConnection *conn, struct slName *accList, struct refLink **pList) /* Query database and add returned refLinks to head of list. */ { struct slName *accEl = NULL; struct sqlResult *sr = NULL; char **row = NULL; char query[256]; for (accEl = accList; accEl != NULL; accEl = accEl->next) { - safef(query, sizeof(query), "select * from refLink where mrnaAcc = '%s'", + sqlSafef(query, sizeof(query), "select * from refLink where mrnaAcc = '%s'", accEl->name); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { struct refLink *rl = refLinkLoad(row); slAddHead(pList, rl); } sqlFreeResult(&sr); } } static boolean findRefGenes(char *db, struct hgFindSpec *hfs, char *spec, struct hgPositions *hgp) /* Look up refSeq genes in table. */ { +//verbose(1,"findRefGenes db=[%s] spec=[%s]\n", db, spec); // DEBUG REMOVE struct sqlConnection *conn = hAllocConn(db); struct dyString *ds = newDyString(256); struct refLink *rlList = NULL, *rl; boolean gotRefLink = hTableExists(db, "refLink"); boolean found = FALSE; char *specNoVersion = cloneString(spec); (void) chopPrefix(specNoVersion); - +//verbose(1,"findRefGenes specNoVersion=[%s]\n", specNoVersion); // DEBUG REMOVE if (gotRefLink) { if (startsWith("NM_", specNoVersion) || startsWith("NR_", specNoVersion) || startsWith("XM_", specNoVersion)) { - dyStringPrintf(ds, "select * from refLink where mrnaAcc = '%s'", specNoVersion); + sqlDyStringPrintf(ds, "select * from refLink where mrnaAcc = '%s'", specNoVersion); addRefLinks(conn, ds, &rlList); } else if (startsWith("NP_", specNoVersion) || startsWith("XP_", specNoVersion)) { - dyStringPrintf(ds, "select * from refLink where protAcc = '%s'", specNoVersion); + sqlDyStringPrintf(ds, "select * from refLink where protAcc = '%s'", specNoVersion); addRefLinks(conn, ds, &rlList); } else if (isUnsignedInt(specNoVersion)) { - dyStringPrintf(ds, "select * from refLink where locusLinkId = %s", + sqlDyStringPrintf(ds, "select * from refLink where locusLinkId = %s", specNoVersion); addRefLinks(conn, ds, &rlList); dyStringClear(ds); - dyStringPrintf(ds, "select * from refLink where omimId = %s", specNoVersion); + sqlDyStringPrintf(ds, "select * from refLink where omimId = %s", specNoVersion); addRefLinks(conn, ds, &rlList); } else { char *indexFile = getGenbankGrepIndex(db, hfs, "refLink", "mrnaAccProduct"); - dyStringPrintf(ds, "select * from refLink where name like '%s%%'", + sqlDyStringPrintf(ds, "select * from refLink where name like '%s%%'", specNoVersion); addRefLinks(conn, ds, &rlList); if (indexFile != NULL) { struct slName *accList = doGrepQuery(indexFile, "refLink", specNoVersion, NULL); addRefLinkAccs(conn, accList, &rlList); } else { dyStringClear(ds); - dyStringPrintf(ds, "select * from refLink where product like '%%%s%%'", + sqlDyStringPrintf(ds, "select * from refLink where product like '%%%s%%'", specNoVersion); addRefLinks(conn, ds, &rlList); } } } if (rlList != NULL) { struct hgPosTable *table = NULL; struct hash *hash = newHash(8); for (rl = rlList; rl != NULL; rl = rl->next) { char where[64]; struct genePredReader *gpr; struct genePred *gp; /* Don't return duplicate mrna accessions */ if (hashFindVal(hash, rl->mrnaAcc)) { hashAdd(hash, rl->mrnaAcc, rl); continue; } hashAdd(hash, rl->mrnaAcc, rl); - safef(where, sizeof where, "name = '%s'", rl->mrnaAcc); + sqlSafefFrag(where, sizeof where, "name = '%s'", rl->mrnaAcc); gpr = genePredReaderQuery(conn, hfs->searchTable, where); while ((gp = genePredReaderNext(gpr)) != NULL) { struct hgPos *pos = NULL; AllocVar(pos); if (table == NULL) { char desc[256]; AllocVar(table); table->name = cloneString(hfs->searchTable); if (startsWith("xeno", hfs->searchTable)) safef(desc, sizeof(desc), "Non-%s RefSeq Genes", hOrganism(db)); else safef(desc, sizeof(desc), "RefSeq Genes"); table->description = cloneString(desc); @@ -2166,58 +2165,58 @@ /* Look up TIGR and Genbank genes from keyword */ { struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr = NULL; struct dyString *ds = newDyString(256); char **row; struct hgPosTable *table = NULL; struct hgPos *pos; struct bed *bed; struct tigrCmrGene *tigrList = NULL, *tigr; /* struct minGeneInfo *gbList = NULL, *gb; */ boolean gotTIGRkeys = sqlTableExists(conn, "tigrCmrORFsInfo"); if (gotTIGRkeys) { - dyStringPrintf(ds, "select * from tigrCmrORFsInfo where tigrCommon like '%%%s%%'", spec); + sqlDyStringPrintf(ds, "select * from tigrCmrORFsInfo where tigrCommon like '%%%s%%'", spec); addTigrCmrGenes(conn, ds, &tigrList); dyStringClear(ds); - dyStringPrintf(ds, "select * from tigrCmrORFsInfo where tigrMainRole like '%%%s%%'", spec); + sqlDyStringPrintf(ds, "select * from tigrCmrORFsInfo where tigrMainRole like '%%%s%%'", spec); addTigrCmrGenes(conn, ds, &tigrList); dyStringClear(ds); - dyStringPrintf(ds, "select * from tigrCmrORFsInfo where tigrSubRole like '%%%s%%'", spec); + sqlDyStringPrintf(ds, "select * from tigrCmrORFsInfo where tigrSubRole like '%%%s%%'", spec); addTigrCmrGenes(conn, ds, &tigrList); dyStringClear(ds); } if (tigrList != NULL) { struct hash *hash = newHash(8); AllocVar(table); slAddHead(&hgp->tableList, table); table->description = cloneString("TIGR CMR Genes"); table->name = cloneString("tigrORFsCmr"); for (tigr = tigrList; tigr != NULL; tigr = tigr->next) { /* Don't return duplicate TIGR CMR accessions */ if (hashFindVal(hash, tigr->name)) { hashAdd(hash, tigr->name, tigr); continue; } hashAdd(hash, tigr->name, tigr); dyStringClear(ds); - dyStringPrintf(ds, "select * from tigrCmrORFs where name = '%s'", tigr->name); + sqlDyStringPrintf(ds, "select * from tigrCmrORFs where name = '%s'", tigr->name); sr = sqlGetResult(conn, ds->string); while ((row = sqlNextRow(sr)) != NULL) { bed = bedLoadN(row+1,6); AllocVar(pos); slAddHead(&table->posList, pos); pos->name = cloneString(tigr->name); pos->browserName = cloneString(tigr->name); dyStringClear(ds); dyStringPrintf(ds, "%s; %s; %s", tigr->tigrCommon, tigr->tigrMainRole, tigr->tigrSubRole); pos->description = cloneString(ds->string); pos->chrom = hgOfficialChromName(db, bed->chrom); pos->chromStart = bed->chromStart; pos->chromEnd = bed->chromEnd; bedFree(&bed); @@ -2240,31 +2239,31 @@ struct sqlConnection *conn; struct sqlResult *sr = NULL; struct dyString *query; char **row; boolean ok = FALSE; struct hgPos *pos = NULL; int rowOffset; char *localName; localName = pattern; if (!hTableExists(db, tableName)) return FALSE; rowOffset = hOffsetPastBin(db, NULL, tableName); conn = hAllocConn(db); query = newDyString(256); -dyStringPrintf(query, +sqlDyStringPrintf(query, "SELECT chrom, txStart, txEnd, name FROM %s WHERE name LIKE '%s'", tableName, pattern); sr = sqlGetResult(conn, query->string); while ((row = sqlNextRow(sr)) != NULL) { if (ok == FALSE) { ok = TRUE; if (table == NULL) { AllocVar(table); dyStringClear(query); dyStringPrintf(query, "%s Gene Predictions", tableName); table->description = cloneString(query->string); table->name = cloneString(tableName); @@ -2318,69 +2317,69 @@ } static boolean findYeastGenes(char *db, char *pattern, struct hgPositions *hgp) /* Scan yeast-specific tables. */ { struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr; char **row, query[256]; struct hgPosTable *table = NULL; boolean found = FALSE; if (hTableExists(db, "sgdGene")) { struct hash *uniqHash = newHash(0); boolean gotNames = FALSE, gotDescriptions = FALSE; - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select name from sgdGene where name = '%s'", pattern); addUniqYeastGene(db, uniqHash, conn, query, hgp, "sgdGene", &table); if (hTableExists(db, "sgdToName")) { gotNames = TRUE; - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select name from sgdToName where value like '%s%%'", pattern); addUniqYeastGene(db, uniqHash, conn, query, hgp, "sgdGene", &table); } if (hTableExists(db, "sgdDescription")) { gotDescriptions = TRUE; - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select name from sgdDescription where description like '%%%s%%'", pattern); addUniqYeastGene(db, uniqHash, conn, query, hgp, "sgdGene", &table); } hashFree(&uniqHash); /* Add descriptions to table. */ if (table != NULL) { struct hgPos *pos; for (pos = table->posList; pos != NULL; pos = pos->next) { struct dyString *dy = newDyString(1024); if (gotNames) { - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select value from sgdToName where name = '%s'", pos->name); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) dyStringPrintf(dy, "(%s) ", row[0]); sqlFreeResult(&sr); } if (gotDescriptions) { - safef(query, sizeof(query), + sqlSafef(query, sizeof(query), "select description from sgdDescription where name = '%s'", pos->name); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) dyStringPrintf(dy, "%s", row[0]); sqlFreeResult(&sr); } if (dy->stringSize > 0) pos->description = cloneString(dy->string); dyStringFree(&dy); } found = TRUE; } } hFreeConn(&conn); @@ -2582,34 +2581,36 @@ char *table) { if (relativeFlag) hUserAbort("Sorry, range spec (\":%d-%d\") is not supported for %s.", relStart+1, relEnd, table); } #endif static boolean searchSpecial(char *db, struct hgFindSpec *hfs, char *term, struct hgPositions *hgp, boolean relativeFlag, int relStart, int relEnd, boolean *retFound) /* Handle searchTypes for which we have special code. Return true if * we have special code. Set retFind according to whether we find term. */ { +//verbose(1,"searchSpecial db=[%s] term=[%s]\n", db, term); // DEBUG REMOVE boolean isSpecial = TRUE; boolean found = FALSE; char *upcTerm = cloneString(term); touppers(upcTerm); +//verbose(1,"searchSpecial hfs->searchType=[%s]\n", hfs->searchType); // DEBUG REMOVE if (sameString(hfs->searchType, "knownGene")) { if (gotFullText(db)) found = findKnownGeneFullText(db, term, hgp); else /* NOTE, in a few months (say by April 1 2006) get rid of else -JK */ { if (!found && hTableExists(db, "kgAlias")) found = findKgGenesByAlias(db, term, hgp); if (!found && hTableExists(db, "kgProtAlias")) found = findKgGenesByProtAlias(db, term, hgp); if (!found) found = findKnownGene(db, term, hgp, hfs->searchTable); } } else if (sameString(hfs->searchType, "refGene")) @@ -2647,46 +2648,61 @@ } else if (sameString(hfs->searchType, "mrnaKeyword")) { found = findMrnaKeys(db, hfs, upcTerm, hgp); } else if (sameString(hfs->searchType, "sgdGene")) { found = findYeastGenes(db, term, hgp); } else { isSpecial = FALSE; } *retFound = found; freeMem(upcTerm); +//verbose(1,"searchSpecial done isSpecial=%d\n", isSpecial); // DEBUG REMOVE return(isSpecial); } static struct slPair *getXrefTerms(char *db, struct hgFindSpec *hfs, char *term) /* Search xrefTable for xrefQuery with term. Return all matching names. */ { +//verbose(1,"getXrefTerms db=[%s] term=[%s]\n", db, term); // DEBUG REMOVE struct slPair *xrefList = NULL, *xrefPtr = NULL; struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr = NULL; char **row; -char buf[512]; boolean isFuzzy = sameWord(hfs->searchMethod, "fuzzy"); -safef(buf, sizeof(buf), hfs->xrefQuery, hfs->xrefTable, term); -sr = sqlGetResult(conn, buf); +// TODO wonder if we could re-work this better to get to upstream sql creation and +// then be able to avoid this complexity:? +// hfs->refTable sometimes contains a comma-separated table list +// but we do not have control over the original sql since it is in trackDb.ra + +// example from human/hg19/trackDb.ra +// xrefTable kgXref, ucscRetroInfo5 +// xrefQuery select ucscRetroInfo5.name, spDisplayID from %s where spDisplayID like '%s%%' and kgName = kgID + +struct dyString *dy = dyStringNew(256); +dyStringAppend(dy, "NOSQLINJ "); +// in particular, if we could get to the upstream and change the first %s to %-s for the param corresponding to xrefTable, +// that would be nice. +dyStringPrintf(dy, hfs->xrefQuery, sqlCkIl(hfs->xrefTable), sqlEscapeString(term)); // keep this sqlEscape +sr = sqlGetResult(conn, dy->string); +dyStringFree(&dy); while ((row = sqlNextRow(sr)) != NULL) { if (!isFuzzy || keyIsPrefixIgnoreCase(term, row[1])) { xrefPtr = slPairNew(cloneString(row[1]), cloneString(row[0])); slAddHead(&xrefList, xrefPtr); } } sqlFreeResult(&sr); hFreeConn(&conn); slReverse(&xrefList); if (xrefList == NULL && hgFindSpecSetting(hfs, "searchBoth") != NULL) xrefList = slPairNew(cloneString(""), cloneString(term)); return(xrefList); } @@ -2711,30 +2727,31 @@ { int sz; va_list args; va_start(args, format); sz = vatruncatef(buf, size, format, args); va_end(args); } static boolean doQuery(char *db, struct hgFindSpec *hfs, char *xrefTerm, char *term, struct hgPositions *hgp, boolean relativeFlag, int relStart, int relEnd, boolean multiTerm) /* Perform a query as specified in hfs, assuming table existence has been * checked and xref'ing has been taken care of. */ { +//verbose(1,"doQuery term=[%s]\n", term); // DEBUG REMOVE struct slName *tableList = hSplitTableNames(db, hfs->searchTable); struct slName *tPtr = NULL; struct hgPosTable *table = NULL; struct hgPos *pos = NULL; struct sqlConnection *conn = hAllocConn(db); struct sqlResult *sr = NULL; char **row = NULL; char *termPrefix = hgFindSpecSetting(hfs, "termPrefix"); char *paddingStr = hgFindSpecSetting(hfs, "padding"); int padding = isEmpty(paddingStr) ? 0 : atoi(paddingStr); boolean found = FALSE; char *description = NULL; char buf[2048]; if (isNotEmpty(termPrefix) && startsWith(termPrefix, term)) @@ -2743,32 +2760,34 @@ return(FALSE); if (isNotEmpty(hfs->searchDescription)) truncatef(buf, sizeof(buf), "%s", hfs->searchDescription); else safef(buf, sizeof(buf), "%s", hfs->searchTable); description = cloneString(buf); if (hgp->tableList != NULL && sameString(hgp->tableList->name, hfs->searchTable) && sameString(hgp->tableList->description, description)) table = hgp->tableList; for (tPtr = tableList; tPtr != NULL; tPtr = tPtr->next) { - safef(buf, sizeof(buf), hfs->query, tPtr->name, term); - sr = sqlGetResult(conn, buf); + // we do not have control over the original sql since it comes from trackDb.ra or elsewhere? + char query[2048]; + sqlSafef(query, sizeof(query), hfs->query, tPtr->name, term); + sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { if(table == NULL) { AllocVar(table); table->description = description; table->name = cloneString(hfs->searchTable); slAddHead(&hgp->tableList, table); } found = TRUE; AllocVar(pos); pos->chrom = cloneString(row[0]); pos->chromStart = atoi(row[1]); pos->chromEnd = atoi(row[2]); if (isNotEmpty(xrefTerm)) @@ -2805,58 +2824,65 @@ } if (table != NULL) slReverse(&table->posList); sqlFreeResult(&sr); hFreeConn(&conn); slFreeList(&tableList); return(found); } boolean hgFindUsingSpec(char *db, struct hgFindSpec *hfs, char *term, struct hgPositions *hgp, boolean relativeFlag, int relStart, int relEnd, boolean multiTerm) /* Perform the search described by hfs on term. If successful, put results * in hgp and return TRUE. (If not, don't modify hgp.) */ { +//verbose(1,"hgFindUsingSpec db=[%s] term=[%s]\n", db, term); // DEBUG REMOVE struct slPair *xrefList = NULL, *xrefPtr = NULL; boolean found = FALSE; if (hfs == NULL || term == NULL || hgp == NULL) errAbort("NULL passed to hgFindUsingSpec.\n"); if (strlen(term)<2 && ! (sameString(hfs->searchName, "knownGene") || sameString(hfs->searchName, "flyBaseGeneSymbolOneLetter"))) return FALSE; if (isNotEmpty(hfs->termRegex) && ! regexMatchNoCase(term, hfs->termRegex)) return(FALSE); if (! hTableOrSplitExists(db, hfs->searchTable)) return(FALSE); if (isNotEmpty(hfs->searchType) && searchSpecial(db, hfs, term, hgp, relativeFlag, relStart, relEnd, &found)) return(found); +//verbose(1,"hgFindUsingSpec hfs->xrefTable=[%s]\n", hfs->xrefTable); // DEBUG REMOVE if (isNotEmpty(hfs->xrefTable)) { struct sqlConnection *conn = hAllocConn(db); - boolean exists = sqlTableExists(conn, hfs->xrefTable); + // NOTE hfs->xrefTable can sometimes contain a comma-separated table list, + // rather than just a single table. + char *tables = replaceChars(hfs->xrefTable, ",", " "); + boolean exists = sqlTablesExist(conn, tables); hFreeConn(&conn); + freeMem(tables); if (! exists) return(FALSE); + xrefList = getXrefTerms(db, hfs, term); } else xrefList = slPairNew(cloneString(""), cloneString(term)); for (xrefPtr = xrefList; xrefPtr != NULL; xrefPtr = xrefPtr->next) { found |= doQuery(db, hfs, xrefPtr->name, (char *)xrefPtr->val, hgp, relativeFlag, relStart, relEnd, multiTerm); } slPairFreeValsAndList(&xrefList); return(found); } @@ -2936,31 +2962,31 @@ hgPosTableFreeList(&(hgp->tableList->next)); hgPosFreeList(&(hgp->tableList->posList->next)); } } static boolean searchKnownCanonical(char *db, char *term, struct hgPositions *hgp) /* Look for term in kgXref.geneSymbol, and if found, put knownCanonical coords and * knownGene.name in hgp. */ { boolean foundIt = FALSE; struct sqlConnection *conn = hAllocConn(db); if (sqlTableExists(conn, "knownGene") && sqlTableExists(conn, "knownCanonical") && sqlTableExists(conn, "kgXref")) { char query[512]; - safef(query, sizeof(query), "select chrom,chromStart,chromEnd,kgID from knownCanonical,kgXref " + sqlSafef(query, sizeof(query), "select chrom,chromStart,chromEnd,kgID from knownCanonical,kgXref " "where kgXref.geneSymbol = '%s' and kgXref.kgId = knownCanonical.transcript;", term); struct sqlResult *sr = sqlGetResult(conn, query); char **row; if ((row = sqlNextRow(sr)) != NULL) { singlePos(hgp, "UCSC Genes", term, "knownGene", row[3], row[3], cloneString(row[0]), atoi(row[1]), atoi(row[2])); foundIt = TRUE; } sqlFreeResult(&sr); } hFreeConn(&conn); return foundIt; } @@ -3069,63 +3095,65 @@ } else relEnd = atoi(stripCommas(term+substrs[3].rm_so)); if (canonicalSpec || gbrowserSpec || lengthSpec) relStart--; if (lengthSpec) relEnd += relStart; if (relStart > relEnd) { int tmp = relStart; relStart = relEnd; relEnd = tmp; } relativeFlag = TRUE; } -term = sqlEscapeString(term); +//term = sqlEscapeString(term); // term is pre-escaped ! // DEBUG REMOVE +term = cloneString(term); // DEBUG KEEP? -if (hgOfficialChromName(db, term) != NULL) +if (hgOfficialChromName(db, term) != NULL) // this mangles the term { char *chrom; int start, end; hgParseChromRange(db, term, &chrom, &start, &end); if (relativeFlag) { int chromSize = end; end = start + relEnd; start = start + relStart; if (end > chromSize) end = chromSize; if (start < 0) start = 0; } singlePos(hgp, "Chromosome Range", NULL, "chromInfo", originalTerm, "", chrom, start, end); } else { struct hgFindSpec *shortList = NULL, *longList = NULL; struct hgFindSpec *hfs; boolean done = FALSE; // Disable singleBaseSpec for any term that is not hgOfficialChromName // because that mangles legitimate IDs that are [A-Z]:[0-9]+. if (singleBaseSpec) { singleBaseSpec = relativeFlag = FALSE; - term = sqlEscapeString(originalTerm); + //term = sqlEscapeString(originalTerm); // DEBUG REMOVE + term = cloneString(originalTerm); // DEBUG KEEP relStart = relEnd = 0; } if (!trackHubDatabase(db)) hgFindSpecGetAllSpecs(db, &shortList, &longList); for (hfs = shortList; hfs != NULL; hfs = hfs->next) { if (hgFindUsingSpec(db, hfs, term, hgp, relativeFlag, relStart, relEnd, multiTerm)) { done = TRUE; if (! hgFindSpecSetting(hfs, "semiShortCircuit")) break; } }