output: #fixed code
                                  protected MetricData getRollupByGranularity(
              String tenantId,
              String metricName,
              long from,
              long to,
              Granularity g) {
  
          final Timer.Context ctx = metricsFetchTimer.time();
          final Locator locator = Locator.createLocatorFromPathComponents(tenantId, metricName);
          final MetricData metricData = AstyanaxReader.getInstance().getDatapointsForRange(
                  locator,
                  new Range(g.snapMillis(from), to),
                  g);
  
          boolean isRollable = metricData.getType().equals(MetricData.Type.NUMBER.toString())
                  || metricData.getType().equals(MetricData.Type.HISTOGRAM.toString());
  
          // if Granularity is FULL, we are missing raw data - can't generate that
          if (ROLLUP_REPAIR && isRollable && g != Granularity.FULL && metricData != null) {
              final Timer.Context rollupsCalcCtx = rollupsCalcOnReadTimer.time();
  
              if (metricData.getData().isEmpty()) { // data completely missing for range. complete repair.
                  rollupsRepairEntireRange.mark();
                  List<Points.Point> repairedPoints = repairRollupsOnRead(locator, g, from, to);
                  for (Points.Point repairedPoint : repairedPoints) {
                      metricData.getData().add(repairedPoint);
                  }
  
                  if (repairedPoints.isEmpty()) {
                      rollupsRepairEntireRangeEmpty.mark();
                  }
              } else {
                  long actualStart = minTime(metricData.getData());
                  long actualEnd = maxTime(metricData.getData());
  
                  // If the returned start is greater than 'from', we are missing a portion of data.
                  if (actualStart > from) {
                      rollupsRepairedLeft.mark();
                      List<Points.Point> repairedLeft = repairRollupsOnRead(locator, g, from, actualStart);
                      for (Points.Point repairedPoint : repairedLeft) {
                          metricData.getData().add(repairedPoint);
                      }
  
                      if (repairedLeft.isEmpty()) {
                          rollupsRepairedLeftEmpty.mark();
                      }
                  }
  
                  // If the returned end timestamp is less than 'to', we are missing a portion of data.
                  if (actualEnd + g.milliseconds() <= to) {
                      rollupsRepairedRight.mark();
                      List<Points.Point> repairedRight = repairRollupsOnRead(locator, g, actualEnd + g.milliseconds(), to);
                      for (Points.Point repairedPoint : repairedRight) {
                          metricData.getData().add(repairedPoint);
                      }
  
                      if (repairedRight.isEmpty()) {
                          rollupsRepairedRightEmpty.mark();
                      }
                  }
              }
              rollupsCalcCtx.stop();
          }
          ctx.stop();
  
          if (g == Granularity.FULL) {
              numFullPointsReturned.update(metricData.getData().getPoints().size());
          } else {
              numRollupPointsReturned.update(metricData.getData().getPoints().size());
          }
  
          return metricData;
      }
input: #vulnerable code 
                                  protected MetricData getRollupByGranularity(
              String tenantId,
              String metricName,
              long from,
              long to,
              Granularity g) {
  
          final Timer.Context ctx = metricsFetchTimer.time();
          final Locator locator = Locator.createLocatorFromPathComponents(tenantId, metricName);
          final MetricData metricData = AstyanaxReader.getInstance().getDatapointsForRange(
                  locator,
                  new Range(g.snapMillis(from), to),
                  g);
  
          // if Granularity is FULL, we are missing raw data - can't generate that
          if (ROLLUP_REPAIR && g != Granularity.FULL && metricData != null) {
              final Timer.Context rollupsCalcCtx = rollupsCalcOnReadTimer.time();
  
              if (metricData.getData().isEmpty()) { // data completely missing for range. complete repair.
                  rollupsRepairEntireRange.mark();
                  List<Points.Point> repairedPoints = repairRollupsOnRead(locator, g, from, to);
                  for (Points.Point repairedPoint : repairedPoints) {
                      metricData.getData().add(repairedPoint);
                  }
  
                  if (repairedPoints.isEmpty()) {
                      rollupsRepairEntireRangeEmpty.mark();
                  }
              } else {
                  long actualStart = minTime(metricData.getData());
                  long actualEnd = maxTime(metricData.getData());
  
                  // If the returned start is greater than 'from', we are missing a portion of data.
                  if (actualStart > from) {
                      rollupsRepairedLeft.mark();
                      List<Points.Point> repairedLeft = repairRollupsOnRead(locator, g, from, actualStart);
                      for (Points.Point repairedPoint : repairedLeft) {
                          metricData.getData().add(repairedPoint);
                      }
  
                      if (repairedLeft.isEmpty()) {
                          rollupsRepairedLeftEmpty.mark();
                      }
                  }
  
                  // If the returned end timestamp is less than 'to', we are missing a portion of data.
                  if (actualEnd + g.milliseconds() <= to) {
                      rollupsRepairedRight.mark();
                      List<Points.Point> repairedRight = repairRollupsOnRead(locator, g, actualEnd + g.milliseconds(), to);
                      for (Points.Point repairedPoint : repairedRight) {
                          metricData.getData().add(repairedPoint);
                      }
  
                      if (repairedRight.isEmpty()) {
                          rollupsRepairedRightEmpty.mark();
                      }
                  }
              }
              rollupsCalcCtx.stop();
          }
          ctx.stop();
  
          if (g == Granularity.FULL) {
              numFullPointsReturned.update(metricData.getData().getPoints().size());
          } else {
              numRollupPointsReturned.update(metricData.getData().getPoints().size());
          }
  
          return metricData;
      } 
                              #location 66 
                              #vulnerability type NULL_DEREFERENCE