Yalantis/uCrop · error · CImgArgumentException
cimg::fopen(): File '%s', specified mode is (null).
Error message
cimg::fopen(): File '%s', specified mode is (null).
What it means
cimg::fopen() is CImg's thin wrapper over std fopen that validates its arguments before delegating to the OS. It throws CImgArgumentException when the caller passes a NULL mode string (e.g. fopen(path, NULL)); the path is still printed to help identify the call site. This is a pure caller-contract violation, not an I/O problem.
Source
Thrown at ucrop/src/main/jni/CImg.h:7553
}
// Open a file (similar to std:: fopen(), but with wide character support on Windows).
inline std::FILE *std_fopen(const char *const path, const char *const mode);
//! Open a file.
/**
\param path Path of the filename to open.
\param mode C-string describing the opening mode.
\return Opened file.
\note Same as <tt>std::fopen()</tt> but throw a \c CImgIOException when
the specified file cannot be opened, instead of returning \c 0.
**/
inline std::FILE *fopen(const char *const path, const char *const mode) {
if (!path)
throw CImgArgumentException("cimg::fopen(): Specified file path is (null).");
if (!mode)
throw CImgArgumentException("cimg::fopen(): File '%s', specified mode is (null).",
path);
std::FILE *res = 0;
if (*path=='-' && (!path[1] || path[1]=='.')) {
res = (*mode=='r')?cimg::_stdin():cimg::_stdout();
#if cimg_OS==2
if (*mode && mode[1]=='b') { // Force stdin/stdout to be in binary mode
#ifdef __BORLANDC__
if (setmode(_fileno(res),0x8000)==-1) res = 0;
#else
if (_setmode(_fileno(res),0x8000)==-1) res = 0;
#endif
}
#endif
} else res = cimg::std_fopen(path,mode);
if (!res) throw CImgIOException("cimg::fopen(): Failed to open file '%s' with mode '%s'.",
path,mode);
return res;
}View on GitHub (pinned to f788b534b4)
Solutions
- Pass a valid mode string literal such as "r", "rb", "w", or "wb" as the second argument to cimg::fopen()
- Check the caller that computes the mode string and give it a non-NULL default
- If the mode may be absent, guard with `if (mode)` before calling, or throw your own descriptive error
Example fix
// before std::FILE *f = cimg::fopen(path, mode); // mode may be NULL // after if (!mode) mode = "rb"; std::FILE *f = cimg::fopen(path, mode);
Defensive patterns
Strategy: validation
Validate before calling
if (!mode || !*mode) mode = "rb"; // or throw app-level error before cimg::fopen
Type guard
bool validMode(const char *m){ return m && *m; } Try / catch
try { f = cimg::fopen(path, mode); } catch (const cimg_library::CImgArgumentException &e) { log_error("bad fopen args: %s", e.what()); } Prevention
- Always pass string-literal modes ("r","rb","w","wb")
- Never forward a possibly-NULL mode parameter; default it at the function boundary
- Enable compiler warnings for uninitialized pointers
When it happens
Trigger: Calling cimg::fopen(path, mode) with mode == NULL, typically when a mode string is built conditionally and ends up unset, or a function parameter is forwarded uninitialized.
Common situations: Passing a std::string::c_str() from an empty/unset variable used as mode; refactoring that removed a default "r"/"rb" argument; uninitialized const char* mode in JNI/Native code paths.
Related errors
- cimg::fopen(): Specified file path is (null).
- cimg::fread(): Invalid reading request of %u %s%s from file
- cimg::fwrite(): Invalid writing request of %u %s%s from buff
- cimg::fempty(): Specified filename is (null).
- draw_spline(): Specified color is (null).
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/4a22dc109cc76750.
Report an issue: GitHub.