{"record":{"id":"65a803a3db205734","repo":"Yalantis/uCrop","slug":"save-pnk-specified-filename-is-null","errorCode":null,"errorMessage":"save_pnk(): Specified filename is (null).","messagePattern":"save_pnk\\(\\): Specified filename is \\(null\\)\\.","errorType":"exception","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":62410,"sourceCode":"      return *this;\n    }\n\n    //! Save image as a PNK file.\n    /**\n      \\param filename Filename, as a C-string.\n    **/\n    const CImg<T>& save_pnk(const char *const filename) const {\n      return _save_pnk(0,filename);\n    }\n\n    //! Save image as a PNK file \\overloading.\n    const CImg<T>& save_pnk(std::FILE *const file) const {\n      return _save_pnk(file,0);\n    }\n\n    const CImg<T>& _save_pnk(std::FILE *const file, const char *const filename) const {\n      if (!file && !filename)\n        throw CImgArgumentException(_cimg_instance\n                                    \"save_pnk(): Specified filename is (null).\",\n                                    cimg_instance);\n      if (is_empty()) { cimg::fempty(file,filename); return *this; }\n      if (_spectrum>1)\n        cimg::warn(_cimg_instance\n                   \"save_pnk(): Instance is multispectral, only the first channel will be saved in file '%s'.\",\n                   cimg_instance,\n                   filename?filename:\"(FILE*)\");\n\n      const ulongT buf_size = std::min((ulongT)1024*1024,(ulongT)_width*_height*_depth);\n      std::FILE *const nfile = file?file:cimg::fopen(filename,\"wb\");\n      const T *ptr = data(0,0,0,0);\n\n      if (!cimg::type<T>::is_float() && sizeof(T)==1 && _depth<2) // Can be saved as regular PNM file\n        _save_pnm(file,filename,0);\n      else if (!cimg::type<T>::is_float() && sizeof(T)==1) { // Save as extended P5 file: Binary byte-valued 3D\n        std::fprintf(nfile,\"P5\\n%u %u %u\\n255\\n\",_width,_height,_depth);\n        CImg<ucharT> buf((unsigned int)buf_size);","sourceCodeStart":62392,"sourceCodeEnd":62428,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L62392-L62428","documentation":"save_pnk() (Portable Anymap single-channel writer) throws CImgArgumentException when both the FILE* and the filename are null, because there is no output target. It mirrors the same guard used by the other _save_* overloads.","triggerScenarios":"Calling save_pnk((std::FILE*)0), or _save_pnk with both arguments null; passing a FILE* returned NULL by fopen() without checking.","commonSituations":"fopen failure not checked before forwarding the stream; null path from environment/config; refactored code that dropped the filename parameter.","solutions":["Pass a non-null filename to save_pnk()","Check fopen() return value before passing a FILE*","Validate the output path before calling save_pnk()"],"exampleFix":"// before\nstd::FILE *f = std::fopen(path.c_str(), \"wb\");\nimg.save_pnk(f); // f may be NULL\n// after\nstd::FILE *f = std::fopen(path.c_str(), \"wb\");\nif (f) img.save_pnk(f); else throw std::runtime_error(\"cannot open \" + path);","handlingStrategy":"validation","validationCode":"if (!file && (!filename || !*filename)) throw std::invalid_argument(\"save_pnk requires a filename or FILE*\");","typeGuard":"bool hasDestination(std::FILE *f, const char *name) { return f != NULL || (name != NULL && name[0] != '\\0'); }","tryCatchPattern":"try { img.save_pnk(path.c_str()); } catch (CImgArgumentException &e) { /* handle */ }","preventionTips":["Guard all output paths at call sites","Check fopen() before forwarding FILE*","Use std::string instead of raw char* where possible"],"tags":["null-argument","image-io","api-misuse"],"backgroundTag":"null-argument","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}