static CDFstatus ValidateVariableLinks (struct CDFstruct *CDF, vFILE *fp, Logical zVar, Logical debug) { CDFstatus status; OFF_T offset, headVXR, tailVXR, nextVXR, nextVDR, cprOffset; Int32 num, lastRec, flags; int ix, numVars, *visit; numVars = (zVar ? GDR.NzVars : GDR.NrVars); visit = (int *) cdf_AllocateMemory(numVars * sizeof(Int32), NULL); for (ix = 0; ix < numVars; ++ix) visit[ix] = 0; offset = (zVar ? GDR.zVDRhead : GDR.rVDRhead); for (ix = 0; ix < numVars; ++ix) { status = ValidateVDR (CDF, fp, offset, zVar, debug); if (status != CDF_OK) { cdf_FreeMemory (visit, NULL); return status; } status = ReadVDR64 (CDF, fp, offset, zVar, VDR_NUM, &num, VDR_FLAGS, &flags, VDR_MAXREC, &lastRec, VDR_VDRNEXT, &nextVDR, VDR_CPRorSPR, &cprOffset, VDR_VXRHEAD, &headVXR, VDR_VXRTAIL, &tailVXR, VDR_NULL); if (CDF->singleFile && lastRec > -1) { status = ValidateVariableValueLinks (CDF, fp, lastRec, headVXR, debug); if (status != CDF_OK) { cdf_FreeMemory (visit, NULL); return status; } } if (VARcompressionBITset(flags)) { status = ValidateCPR (fp, cprOffset, debug); if (status != CDF_OK) { cdf_FreeMemory (visit, NULL); return status; } } visit[num] = 1; offset = nextVDR; } for (ix = 0; ix < numVars; ++ix) { if (visit[ix] == 0) { cdf_FreeMemory (visit, NULL); if (zVar) return QuitCDF ("CDF: a zVariable unreachable in the variable chain: ", (OFF_T) -1, 4, 1, &ix, 0, debug); else return QuitCDF ("CDF: a rVariable unreachable in the variable chain: ", (OFF_T) -1, 4, 1, &ix, 0, debug); } } cdf_FreeMemory (visit, NULL); if (offset != 0) { status = ReadVDR64 (CDF, fp, offset, zVar, VDR_NUM, &num, VDR_VDRNEXT, &nextVDR, VDR_NULL); if (status == CDF_OK) { if (num >= numVars) { if (zVar) return QuitCDF ("CDF(VDR): a zVariable unreachable in the variable chain: ", offset, 4, 1, &num, 0, debug); else return QuitCDF ("CDF(VDR): a rVariable unreachable in the variable chain: ", offset, 4, 1, &num, 0, debug); } else { if (zVar) return QuitCDF ("CDF(VDR): a zVariable is repeated in the variable chain: ", offset, 4, 1, &num, 0, debug); else return QuitCDF ("CDF(VDR): a rVariable unreachable in the variable chain: ", offset, 4, 1, &num, 0, debug); } } } return CDF_OK; }
static CDFstatus ValidateVDR (struct CDFstruct *CDF, vFILE *fp, OFF_T offset, Logical zVar, Logical debug) { struct VDRstruct64 VDR; void *padValue; Int32 nDims, numVars; int ix; CDFstatus status; size_t nBytes; if (debug) #if defined(win32) || defined(__MINGW32__) printf(" Checking VDR...@%I64d\n", offset); #else printf(" Checking VDR...@%lld\n", offset); #endif status = ReadVDR64 (CDF, fp, offset, zVar, VDR_RECORD, &VDR, NULL, VDR_NULL); if (status != CDF_OK) return status; if ((zVar && VDR.RecordType != zVDR_) || (!zVar && VDR.RecordType != rVDR_)) return QuitCDF ("CDF(VDR): record type is invalid ", offset, 4, 1, &(VDR.RecordType), 0, debug); if (VDR.RecordSize < (zVar ? zVDR_BASE_SIZE64 : rVDR_BASE_SIZE64)) return QuitCDF ("CDF(VDR): record size is invalid ", offset, 8, 1, &(VDR.RecordSize), 0, debug); if (!ValidDataType(VDR.DataType)) return QuitCDF ("CDF(VDR): data type is invalid ", offset, 4, 1, &(VDR.DataType), 0, debug); if (VDR.MaxRec < -1) return QuitCDF ("CDF(VDR): max record is invalid ", offset, 4, 1, &(VDR.MaxRec), 0, debug); if (VDR.NumElems < 1 || (!STRINGdataType(VDR.DataType) && VDR.NumElems != 1)) return QuitCDF ("CDF(VDR): number of elements is invalid ", offset, 4, 1, &(VDR.NumElems), 0, debug); if (zVar) numVars = CDF->NzVars; else numVars = CDF->NrVars; if (VDR.Num < 0 || VDR.Num > numVars) return QuitCDF ("CDF(VDR): variable number is invalid ", offset, 4, 2, &(VDR.Num), &numVars, debug); if ((VDR.Num < (numVars-1)) && (VDR.VDRnext < 1)) return QuitCDF ("CDF(VDR): offset to next VDR is invalid ", offset, 8, 1, &(VDR.VDRnext), 0, debug); if (VARcompressionBITset(VDR.Flags) && VDR.CPRorSPRoffset <= NO_OFFSET64) return QuitCDF ("CDF(VDR): offset to CPRorSPR is invalid ", offset, 8, 1, &(VDR.CPRorSPRoffset), 0, debug); if (VDR.blockingFactor < 0) return QuitCDF ("CDF(VDR): blocking factor is invalid ", offset, 4, 1, &(VDR.blockingFactor), 0, debug); if (!ValidVarName(VDR.Name)) return QuitCDF ("CDF(VDR): variable name is invalid ", offset, 0, 1, VDR.Name, 0, debug); if (zVar) { if (VDR.zNumDims < 0 || VDR.zNumDims > CDF_MAX_DIMS) return QuitCDF ("CDF(VDR): number of dimensions is invalid ", offset, 4, 1, &(VDR.zNumDims), 0, debug); for (ix = 0; ix < (int)VDR.zNumDims; ++ix) if (VDR.zDimSizes[ix] < 1) return QuitCDF ("CDF(VDR): dimensional size is invalid ", offset, 4, 1, &(VDR.zDimSizes[ix]), 0, debug); } nBytes = (size_t) (CDFelemSize(VDR.DataType)*VDR.NumElems); if (nBytes < 1) return QuitCDF ("CDF(VDR): pad value size is invalid ", offset, 4, 1, &nBytes, 0, debug); if (VDR.RecordSize > ((zVar ? zVDR_MAX_SIZE64 : rVDR_MAX_SIZE64) + nBytes)) return QuitCDF ("CDF(VDR): record size is invalid ", offset, 8, 1, &(VDR.RecordSize), 0, debug); return CDF_OK; }
CDFstatus ValidateVDR (struct CDFstruct *CDF, vFILE *fp, Int32 offset, Logical zVar, Logical debug) { struct VDRstruct VDR; void *padValue; Int32 nDims, numVars; int ix; CDFstatus status; size_t nBytes; if (debug) printf(" Checking VDR...@%d\n", (int) offset); status = ReadVDR (CDF, fp, offset, zVar, VDR_RECORD, &VDR, NULL, VDR_NULL); if (status != CDF_OK) return status; if ((!zVar && VDR.RecordType != rVDR_) || (zVar && VDR.RecordType != zVDR_)) return QuitCDF ("CDF: record type is invalid ", 4, 1, &(VDR.RecordType), 0, debug); if (VDR.RecordSize < (zVar ? zVDR_BASE_SIZE : rVDR_BASE_SIZE)) return QuitCDF ("CDF: record size is invalid ", 4, 1, &(VDR.RecordSize), 0, debug); if (!ValidDataType(VDR.DataType) || InValidDataType(VDR.DataType)) return QuitCDF ("CDF: data type is invalid ", 4, 1, &(VDR.DataType), 0, debug); if (VDR.MaxRec < -1) return QuitCDF ("CDF: max record is invalid ", 4, 1, &(VDR.MaxRec), 0, debug); if (VDR.NumElems < 1 || (!STRINGdataType(VDR.DataType) && VDR.NumElems != 1)) return QuitCDF ("CDF: number of elements is invalid ", 4, 1, &(VDR.NumElems), 0, debug); if (zVar) numVars = CDF->NzVars; else numVars = CDF->NrVars; if (VDR.Num < 0 || VDR.Num > numVars) return QuitCDF ("CDF: variable number is invalid ", 4, 2, &(VDR.Num), &numVars, debug); if ((VDR.Num < (numVars-1)) && VDR.VDRnext < 1) return QuitCDF ("CDF: offset to next VDR is invalid ", 4, 1, &(VDR.VDRnext), 0, debug); if (VARcompressionBITset(VDR.Flags) && VDR.CPRorSPRoffset <= (int) NO_OFFSET) return QuitCDF ("CDF: offset to CPRorSPR is invalid ", 4, 1, &(VDR.CPRorSPRoffset), 0, debug); if (VDR.blockingFactor < 0) return QuitCDF ("CDF: blocking factor is invalid ", 4, 1, &(VDR.blockingFactor), 0, debug); if (!ValidVarName(VDR.Name)) return QuitCDF ("CDF: variable name is invalid ", 0, 1, VDR.Name, 0, debug); if (zVar) { if (VDR.zNumDims < 0 || VDR.zNumDims > CDF_MAX_DIMS) return QuitCDF ("CDF: number of dimensions is invalid ", 4, 1, &(VDR.zNumDims), 0, debug); for (ix = 0; ix < (int)VDR.zNumDims; ++ix) if (VDR.zDimSizes[ix] < 1) return QuitCDF ("CDF: dimensional size is invalid ", 4, 1, &(VDR.zDimSizes[ix]), 0, debug); } nBytes = (size_t) (CDFelemSize(VDR.DataType)*VDR.NumElems); if (nBytes < 1) return QuitCDF ("CDF: pad value size is invalid ", 4, 1, &nBytes, 0, debug); if (VDR.RecordSize > ((zVar ? zVDR_MAX_SIZE : rVDR_MAX_SIZE) + nBytes + (CDF->wastedSpace ? VDR_WASTED_SIZE : 0))) return QuitCDF ("CDF: record size is invalid ", 4, 1, &(VDR.RecordSize), 0, debug); return CDF_OK; }