e4945398e5ef0d578b54b6dd6160101492c59fba
chmalee
  Fri Jun 29 12:20:08 2018 -0700
Adding check to make sure barChart extraFields will fit in return array after code review feedback, refs #21657

diff --git src/hg/hgc/barChartClick.c src/hg/hgc/barChartClick.c
index 4648074..546f1ba 100644
--- src/hg/hgc/barChartClick.c
+++ src/hg/hgc/barChartClick.c
@@ -8,30 +8,32 @@
 #include "hdb.h"
 #include "hvGfx.h"
 #include "trashDir.h"
 #include "hCommon.h"
 #include "hui.h"
 #include "asParse.h"
 #include "hgc.h"
 #include "trackHub.h"
 
 #include "barChartBed.h"
 #include "barChartCategory.h"
 #include "barChartData.h"
 #include "barChartSample.h"
 #include "barChartUi.h"
 
+#define EXTRA_FIELDS_SIZE 256
+
 struct barChartItemData
 /* Measured value for a sample and the sample category at a locus.
  * Used for barChart track details (boxplot) */
     {
     struct barChartItemData *next;  /* Next in singly linked list. */
     char *sample;	/* Sample identifier */
     char *category;     /* Sample category (from barChartSample table  or barChartSampleUrl file) */
     double value;	/* Measured value (e.g. expression level) */
     };
 
 static struct hash *getTrackCategories(struct trackDb *tdb)
 /* Get list of categories from trackDb.  This may be a subset of those in matrix. 
  * (though maybe better to prune matrix for performance) */
 {
 char *categs = trackDbSetting(tdb, BAR_CHART_CATEGORY_LABELS);
@@ -62,33 +64,35 @@
     asColumnFind(as, BARCHART_OFFSET_COLUMN) != NULL && 
     asColumnFind(as, BARCHART_LEN_COLUMN) != NULL);
 struct lm *lm = lmInit(0);
 struct bigBedInterval *bb, *bbList =  bigBedIntervalQuery(bbi, chrom, start, end, 0, lm);
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     char *rest = cloneString(bb->rest);
     char startBuf[16], endBuf[16];
     char *row[32];
     bigBedIntervalToRow(bb, chrom, startBuf, endBuf, row, ArraySize(row));
     struct barChartBed *barChart = barChartBedLoadOptionalOffsets(row, hasOffsets);
     if (barChart == NULL)
         continue;
     if (sameString(barChart->name, item))
         {
-        char *restFields[256];
+        char *restFields[EXTRA_FIELDS_SIZE];
         int restCount = chopTabs(rest, restFields);
         int restBedFields = (6 + (hasOffsets ? 2 : 0));
+        if ((restCount - restBedFields) > EXTRA_FIELDS_SIZE)
+            errAbort("More than %d extraFields in barChart file %s\n", EXTRA_FIELDS_SIZE, tdb->table);
         if (restCount > restBedFields)
             {
             int i;
             for (i = 0; i < restCount - restBedFields; i++)
                 extraFieldsRet[i] = restFields[restBedFields + i];
             *extraFieldsCountRet = (restCount - restBedFields);
             }
         return barChart;
         }
     }
 return NULL;
 }
 
 static struct barChartBed *getBarChartFromTable(struct trackDb *tdb, char *table, 
                                                 char *item, char *chrom, int start, int end)
@@ -364,31 +368,31 @@
 struct asColumn *asFindColByIx(struct asObject *as, int ix)
 /* Find AS column by index */
 {
 struct asColumn *asCol;
 int i;
 for (i=0, asCol = as->columnList; asCol != NULL && i<ix; asCol = asCol->next, i++);
 return asCol;
 }
 
 void doBarChartDetails(struct trackDb *tdb, char *item)
 /* Details of barChart item */
 {
 int start = cartInt(cart, "o");
 int end = cartInt(cart, "t");
 struct asObject *as = NULL;
-char *extraFields[256];
+char *extraFields[EXTRA_FIELDS_SIZE];
 int extraFieldCount = 0;
 int numColumns = 0;
 struct barChartBed *chartItem = getBarChart(tdb, item, seqName, start, end, &as, extraFields, &extraFieldCount);
 if (chartItem == NULL)
     errAbort("Can't find item %s in barChart table/file %s\n", item, tdb->table);
 
 genericHeader(tdb, item);
 
 // get name and name2 from trackDb, .as file, or use defaults
 struct asColumn *nameCol = NULL, *name2Col = NULL;
 //struct asColumn *name2Col;
 char *nameLabel = NULL, *name2Label = NULL;
 if (as != NULL)
     {
     numColumns = slCount(as->columnList);
@@ -412,31 +416,31 @@
 float highLevel = barChartMaxValue(chartItem, &categId);
 char *units = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, "units");
 char *metric = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_METRIC, "");
 printf("<b>Total all %s values: </b> %0.2f %s<br>\n", metric, barChartTotalValue(chartItem), units);
 printf("<b>Maximum %s value: </b> %0.2f %s in %s<br>\n", 
                 metric, highLevel, units, barChartUiGetCategoryLabelById(categId, database, tdb));
 printf("<b>Score: </b> %d<br>\n", chartItem->score); 
 printf("<b>Genomic position: "
                 "</b>%s <a href='%s&db=%s&position=%s%%3A%d-%d'>%s:%d-%d</a><br>\n", 
                     database, hgTracksPathAndSettings(), database, 
                     chartItem->chrom, chartItem->chromStart+1, chartItem->chromEnd,
                     chartItem->chrom, chartItem->chromStart+1, chartItem->chromEnd);
 printf("<b>Strand: </b> %s\n", chartItem->strand); 
 
 // print any remaining extra fields
-if (numColumns > 11)
+if (numColumns > 0)
     {
     extraFieldsPrint(tdb, NULL, extraFields, extraFieldCount);
     }
 
 char *matrixUrl = NULL, *sampleUrl = NULL;
 struct barChartItemData *vals = getSampleVals(tdb, chartItem, &matrixUrl, &sampleUrl);
 if (vals != NULL)
     {
     // Print boxplot
     puts("<p>");
     char *df = makeDataFrame(tdb->table, vals);
     char *colorFile = makeColorFile(tdb);
     printBoxplot(df, item, chartItem->name2, units, colorFile);
     printf("<br><a href='%s'>View all data points for %s%s%s%s</a>\n", df, 
                         chartItem->name,