57a384c55958100f74a922cae995836aba8ea99b max Mon Jun 24 10:27:43 2013 -0700 working around a sqlinj messages diff --git src/hg/hgc/pubs.c src/hg/hgc/pubs.c index c4fd801..e001483 100644 --- src/hg/hgc/pubs.c +++ src/hg/hgc/pubs.c @@ -1,39 +1,43 @@ /* pubs.c - display details of publiations literature track (pubsxxx tables) */ #include "common.h" #include "jksql.h" #include "hdb.h" #include "hgc.h" #include "hgColors.h" #include "trackDb.h" #include "web.h" #include "hash.h" #include "net.h" #include "obscure.h" #include "common.h" #include "string.h" -//include "hgTrackUi.h" +#include "dystring.h" // cgi var to activate debug output static int pubsDebug = 0; // global var for printArticleInfo to indicate if article has suppl info -// Most publishers have supp data +// Most publishers have supp data. +// If they don't have it, we can skip the fileType column in the table bool pubsHasSupp = TRUE; + // global var for printArticleInfo to indicate if article is elsevier +// If it's elsevier, we print the copyright line bool pubsIsElsevier = FALSE; + // the article source is used to modify other parts of the page static char *articleSource; // we need the external article PMC Id for yif links static char *extId = NULL; // section types in mysql table, for all annotations tables // we note where the hit is located in the document static char *pubsSecNames[] ={ "header", "abstract", "intro", "methods", "results", "discussion", "conclusions", "ack", "refs", "unknown" }; // // whether a checkbox is checked by default, have to correspond to pubsSecNames @@ -261,48 +265,50 @@ } if (names==0) errAbort("You need to specify at least one article section."); char *nameListString = slNameListToString(names, ','); slNameFree(names); return nameListString; } static struct sqlResult *queryMarkerRows(struct sqlConnection *conn, char *markerTable, \ char *articleTable, char *item, int itemLimit, char *sectionList) /* query marker rows from mysql, based on http parameters */ { -char query[4000]; /* Mysql specific setting to make the group_concat function return longer strings */ sqlUpdate(conn, "NOSQLINJ SET SESSION group_concat_max_len = 100000"); -sqlSafef(query, sizeof(query), "SELECT distinct %s.articleId, url, title, authors, citation, " - "pmid, extId, " - "group_concat(snippet, concat(\" (section: \", section, \")\") SEPARATOR ' (...) ') FROM %s " - "JOIN %s USING (articleId) " - "WHERE markerId='%s' AND section in (%s) " - "GROUP by articleId " - "ORDER BY year DESC " - "LIMIT %d", - markerTable, markerTable, articleTable, item, sectionList, itemLimit); +// rather ugly compared to single safef line, but needed to rewrite with dyString for sql inj +struct dyString *query = newDyString(4000); +sqlDyStringPrintf(query,"SELECT distinct "); +sqlDyStringPrintf(query, "%s.articleId,url,title,authors,citation,pmid,extId, ", markerTable); +sqlDyStringPrintf(query, + "group_concat(snippet, concat(\" (section: \", section, \")\") SEPARATOR ' (...) ') FROM %s ", + markerTable); +sqlDyStringPrintf(query, "JOIN %s USING (articleId) ", articleTable); +sqlDyStringPrintf(query, "WHERE markerId='%s' AND section in (", item); +// this part triggered sql injection warning as the section list includes ' and , +sqlDyStringAppend(query, sectionList); +sqlDyStringPrintf(query, ") GROUP BY articleId ORDER BY year DESC LIMIT %d", itemLimit); if (pubsDebug) - printf("%s", query); + printf("%s", query->string); -struct sqlResult *sr = sqlGetResult(conn, query); +struct sqlResult *sr = sqlGetResult(conn, query->string); return sr; } static void printSectionCheckboxes() /* show a little form with checkboxes where user can select sections they want to show */ { // labels to show to user, have to correspond to pubsSecNames char *secLabels[] ={ "Title", "Abstract", "Introduction", "Methods", "Results", "Discussion", "Conclusions", "Acknowledgements", "References", "Undetermined section (e.g. for a brief communication)" }; @@ -331,33 +337,39 @@ } printf("\n", cgiString("o")); printf("\n", cgiString("g")); printf("\n", cgiString("t")); printf("\n", cgiString("i")); printf("\n", cart->sessionId); printf("
"); printf("\n"); printf("

\n"); } static void printLimitWarning(struct sqlConnection *conn, char *markerTable, char *item, int itemLimit, char *sectionList) { -char query[4000]; -sqlSafef(query, sizeof(query), "SELECT COUNT(*) from %s WHERE markerId='%s' AND section in (%s) ", markerTable, item, sectionList); -if (sqlNeedQuickNum(conn, query) > itemLimit) +//char query[4000]; +struct dyString *query = newDyString(4000); +sqlDyStringPrintf(query, "SELECT COUNT(*) from "); +dyStringAppend(query, markerTable); +sqlDyStringPrintf(query, " WHERE markerId='%s' AND section in ", item); +dyStringPrintf(query, " (%s) ", sectionList); // no need to check for illegal characters here + +//sqlSafef(query, sizeof(query), "SELECT COUNT(*) from %s WHERE markerId='%s' AND section in (%s) ", markerTable, item, sectionList); +if (sqlNeedQuickNum(conn, query->string) > itemLimit) { printf("This marker is mentioned more than %d times
\n", itemLimit); printf("The results would take too long to load in your browser and are " "therefore limited to %d articles.

\n", itemLimit); } } static void printMarkerSnippets(struct sqlConnection *conn, char *articleTable, char *markerTable, char *item) { /* do not show more snippets than this limit */ int itemLimit=100; printSectionCheckboxes(); char *sectionList = makeSqlMarkerList();