{"record":{"id":"a45788470889785a","repo":"Yalantis/uCrop","slug":"load-pnm-specified-image-dimensions-in-file-s","errorCode":null,"errorMessage":"load_pnm(): Specified image dimensions in file '%s' exceed file size.","messagePattern":"load_pnm\\(\\): Specified image dimensions in file '(.+?)' exceed file size\\.","errorType":"exception","errorClass":"CImgIOException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":57600,"sourceCode":"                              cimg_instance,\n                              filename?filename:\"(FILE*)\");\n      }\n      if (ppm_type!=1 && ppm_type!=4) {\n        if (err==2 || (err==3 && (ppm_type==5 || ppm_type==7 || ppm_type==8 || ppm_type==9))) {\n          while ((err=std::fscanf(nfile,\" %16383[^\\n]\",item.data()))!=EOF && (*item=='#' || !err)) std::fgetc(nfile);\n          if (cimg_sscanf(item,\"%u\",&colormax)!=1)\n            cimg::warn(_cimg_instance\n                       \"load_pnm(): COLORMAX field is undefined in file '%s'.\",\n                       cimg_instance,\n                       filename?filename:\"(FILE*)\");\n        } else { colormax = D; D = 1; }\n      }\n      std::fgetc(nfile);\n\n      if (filename) { // Check that dimensions specified in file does not exceed the buffer dimension\n        const cimg_int64 siz = cimg::fsize(filename);\n        if (W*H*D>siz)\n          throw CImgIOException(_cimg_instance\n                                \"load_pnm(): Specified image dimensions in file '%s' exceed file size.\",\n                                cimg_instance,\n                                filename);\n      }\n\n      switch (ppm_type) {\n      case 1 : { // 2D B&W ascii\n        assign(W,H,1,1);\n        T* ptrd = _data;\n        cimg_foroff(*this,off) { if (std::fscanf(nfile,\"%d\",&rval)>0) *(ptrd++) = (T)(rval?0:255); else break; }\n      } break;\n      case 2 : { // 2D grey ascii\n        assign(W,H,1,1);\n        T* ptrd = _data;\n        cimg_foroff(*this,off) { if (std::fscanf(nfile,\"%d\",&rval)>0) *(ptrd++) = (T)rval; else break; }\n      } break;\n      case 3 : { // 2D color ascii\n        assign(W,H,1,3);","sourceCodeStart":57582,"sourceCodeEnd":57618,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L57582-L57618","documentation":"load_pnm() validates that the declared image volume (W*H*D pixels) does not exceed the actual file size, because PNM raster data is at least one byte per sample. When the header claims more data than the file contains, the library refuses to load and throws CImgIOException instead of reading past EOF or allocating absurd buffers.","triggerScenarios":"Loading a PNM whose header dimensions are larger than the file's actual byte size via fsize() check: truncated file, hand-edited dimensions, wrong dimensions in a generator, or a header-only placeholder file.","commonSituations":"Interrupted downloads/uploads; log or test fixtures edited by hand; generated PNMs where the writer wrote header dimensions but crashed before writing the raster data; sparse placeholder files.","solutions":["Check the file size against the expected data size (W*H*D*channels) and re-transfer if truncated.","Correct the width/height in the header to match the actual raster data present.","Regenerate the PNM with a complete write (flush/close after raster data).","Compute expected size in the caller with cimg::fsize() or std::filesystem::file_size before loading and reject short files.","Catch CImgIOException and surface 'corrupt/truncated PNM' to the user."],"exampleFix":"// before\nimg.load_pnm(path); // throws when header dims exceed file size\n// after\nauto siz = (long long)std::filesystem::file_size(path);\nif (w * h * d <= siz) {\n  img.load_pnm(path);\n} else {\n  throw std::runtime_error(\"truncated PNM file\");\n}","handlingStrategy":"validation","validationCode":"bool pnmSizePlausible(const char* path, unsigned W, unsigned H, unsigned D) {\n  auto siz = (long long)std::filesystem::file_size(path);\n  return (long long)W * H * D <= siz;\n}","typeGuard":"bool dimsFitFile(long long fileSize, long long W, long long H, long long D) {\n  return W > 0 && H > 0 && D > 0 && W * H * D <= fileSize;\n}","tryCatchPattern":"try {\n  img.load_pnm(path);\n} catch (cimg_library::CImgIOException& e) {\n  std::cerr << \"Corrupt/truncated PNM: \" << e.what() << \"\\n\";\n}","preventionTips":["Compare file size with W*H*D expected bytes before loading","Use verified downloads (checksums) to avoid truncation","Flush and close writers after raster data","Reject short files early in ingestion pipelines"],"tags":["cimg","pnm","truncated-file","image-loading"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}