156dbcfc96c9a4a5eba481f8d979700b0ca1024e galt Mon Feb 3 06:28:18 2025 -0800 Fixing security concern in hgEncodeVocab. fixes #287. Note that actual full cleanup by removing the unneeded encode/cv.ra from trackDb files has not been done yet., and making the code tolerate its presence or absence in the trackDb.ra files, at the start of the controlledVocabulary setting. diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 5d1c4bbeae8..8a89d8db1ea 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -174,47 +174,38 @@ // until it's implemented { char *tbOff = trackDbSetting(tdb, "tableBrowser"); if (isNotEmpty(tbOff) && sameString(nextWord(&tbOff), "off")) return FALSE; char *hint = " title='Open data format (table schema) in new window'"; if (label == NULL) label = " View data format"; struct trackDb *topLevel = trackDbTopLevelSelfOrParent(tdb); printf(SCHEMA_LINKED, db, topLevel->grp, topLevel->track, tdb->table, hint, label); return TRUE; } return FALSE; } -char *wgEncodeVocabLink(char *file,char *term,char *value,char *title, char *label,char *suffix) +char *wgEncodeVocabLink(char *term,char *value,char *title, char *label,char *suffix) // returns allocated string of HTML link to controlled vocabulary term { -#define VOCAB_LINK_WITH_FILE "<A HREF='hgEncodeVocab?ra=%s&%s=\"%s\"' title='%s details' " \ - "class='cv' TARGET=ucscVocab>%s</A>" #define VOCAB_LINK "<A HREF='hgEncodeVocab?%s=\"%s\"' title='%s details' class='cv' " \ "TARGET=ucscVocab>%s</A>" struct dyString *dyLink = NULL; char *encTerm = cgiEncode(term); char *encValue = cgiEncode(value); -if (file != NULL) - { - char *encFile = cgiEncode(file); - dyLink = dyStringCreate(VOCAB_LINK_WITH_FILE,encFile,encTerm,encValue,title,label); - freeMem(encFile); - } -else dyLink = dyStringCreate(VOCAB_LINK,encTerm,encValue,title,label); if (suffix != NULL) dyStringAppend(dyLink,suffix); // Don't encode since this may contain HTML freeMem(encTerm); freeMem(encValue); return dyStringCannibalize(&dyLink); } char *pairsAsHtmlTable( struct slPair *pairs, struct trackDb *tdb, boolean showLongLabel,boolean showShortLabel) /* Return a string which is an HTML table of the tags for this track. */ { if (pairs == NULL) return ""; @@ -283,36 +274,36 @@ dyStringAppend(dyTable,"<BR>"); slNameFree(&file); } dyStringAppend(dyTable,"</td></tr>"); } else { // Don't bother with tableName if (cvTermTypes && differentString(mdbVar->var,MDB_VAR_TABLENAME)) { struct hash *cvTerm = hashFindVal(cvTermTypes,mdbVar->var); if (cvTerm != NULL) // even if cvTerm isn't used, { // it proves that it exists and a link is desirable if (!cvTermIsHidden(mdbVar->var)) { char *label = (char *)cvLabel(NULL,mdbVar->var); - char *linkOfType = wgEncodeVocabLink(NULL,CV_TYPE,mdbVar->var,label, + char *linkOfType = wgEncodeVocabLink(CV_TYPE,mdbVar->var,label, label,NULL); if (cvTermIsCvDefined(mdbVar->var)) { label = (char *)cvLabel(mdbVar->var,mdbVar->val); - char *linkOfTerm = wgEncodeVocabLink(NULL,CV_TERM,mdbVar->val,label, + char *linkOfTerm = wgEncodeVocabLink(CV_TERM,mdbVar->val,label, label,NULL); dyStringPrintf(dyTable,"<tr valign='bottom'><td align='right' nowrap>" "<i>%s:</i></td><td nowrap>%s</td></tr>", linkOfType,linkOfTerm); freeMem(linkOfTerm); } else dyStringPrintf(dyTable,"<tr valign='bottom'><td align='right' nowrap>" "<i>%s:</i></td><td nowrap>%s</td></tr>", linkOfType,mdbVar->val); freeMem(linkOfType); continue; } } } @@ -8572,44 +8563,44 @@ char *words[SMALLBUF]; int count; if ((count = chopByWhite(cloneString(vocab), words, SMALLBUF)) <= 1) return cloneString(label); char *suffix = NULL; char *rootLabel = labelRoot(label, &suffix); boolean found = FALSE; int ix; for (ix=1;ix<count && !found;ix++) { if (sameString(vocabType,words[ix])) // controlledVocabulary setting matches tag { // so all labels are linked - char *link = wgEncodeVocabLink(words[0],"term",words[ix],rootLabel,rootLabel,suffix); + char *link = wgEncodeVocabLink("term",words[ix],rootLabel,rootLabel,suffix); return link; } else if (countChars(words[ix],'=') == 1 && childTdb != NULL) // The name of a trackDb setting follows and will be the controlled vocab term { strSwapChar(words[ix],'=',0); if (sameString(vocabType,words[ix])) // tags match, but search for term { char * cvSetting = words[ix] + strlen(words[ix]) + 1; const char * cvTerm = metadataFindValue(childTdb,cvSetting); if (cvTerm != NULL) { - char *link = wgEncodeVocabLink(words[0], + char *link = wgEncodeVocabLink( (sameWord(cvSetting,"antibody") ? "target" : "term"), (char *)cvTerm,(char *)cvTerm,rootLabel,suffix); return link; } } } } freeMem(words[0]); freeMem(rootLabel); return cloneString(label); } #define PM_BUTTON_UC "<IMG height=18 width=18 id='%s' src='../images/%s'>" #define PM_BUTTON_UC_JS "return (matSetMatrixCheckBoxes(%s%s%s%s%s%s) == false);" #define PM_MAKE_BUTTON_UC(s1,s2,s3,s4,s5,s6,name,img) \ @@ -8939,33 +8930,33 @@ mdbVar = members->groupTag; break; } else if (startsWithWordByDelimiter(members->groupTag,'=',words[ix])) { mdbVar = words[ix] + strlen(members->groupTag) + 1; break; } } if (mdbVar == NULL) { freeMem(vocab); return cloneString(members->groupTitle); } -#define VOCAB_MULTILINK_BEG "<A HREF='hgEncodeVocab?ra=%s&%s=\"" +#define VOCAB_MULTILINK_BEG "<A HREF='hgEncodeVocab?%s=\"" #define VOCAB_MULTILINK_END "\"' title='Click for details of each %s' TARGET=ucscVocab>%s</A>" -struct dyString *dyLink = dyStringCreate(VOCAB_MULTILINK_BEG,vocab, +struct dyString *dyLink = dyStringCreate(VOCAB_MULTILINK_BEG, (sameWord(mdbVar,"antibody")?"target":"term")); // Now build the comma delimited string of mdb vals (all have same mdb var) boolean first = TRUE; for (ix=0;ix<members->count;ix++) { if (members->subtrackList[ix] != NULL && members->subtrackList[ix]->val != NULL) { struct trackDb *childTdb = members->subtrackList[ix]->val; (void)metadataForTable(db,childTdb,NULL); // Makes sure this has been populated const char * mdbVal = metadataFindValue(childTdb,mdbVar); // one for each is enough if (mdbVal != NULL) { if (!first) dyStringAppendC(dyLink,',');