Yalantis/uCrop · error · CImgArgumentException

[cimg_appname_math_parser] CImg<%s>::%s: Empty expression.

Error message

[cimg_appname_math_parser] CImg<%s>::%s: Empty expression.

What it means

CImg's built-in math-expression parser (cimg_math_parser, used by CImg<T>::fill("expr"), eval(), etc.) requires a non-null, non-empty expression string. When the expression pointer is null or the string is empty, it throws CImgArgumentException tagged [cimg_appname_math_parser].

Source

Thrown at ucrop/src/main/jni/CImg.h:17958

      }

      _cimg_math_parser(const char *const expression, const char *const funcname=0,
                        const CImg<T>& img_input=CImg<T>::const_empty(), CImg<T> *const img_output=0,
                        CImgList<T> *const list_images=0, const bool _is_fill=false):
        code(_code),code_begin_t(_code_begin_t),code_end_t(_code_end_t),
        p_break((CImg<ulongT>*)(cimg_ulong)-2),imgin(img_input),
        imgout(img_output?*img_output:CImg<T>::empty()),imglist(list_images?*list_images:CImgList<T>::empty()),
        img_stats(_img_stats),list_stats(_list_stats),list_median(_list_median),list_norm(_list_norm),user_macro(0),
        mem_img_median(~0U),mem_img_norm(~0U),mem_img_index(~0U),debug_indent(0),result_dim(0),result_end_dim(0),
        break_type(0),constcache_size(0),is_parallelizable(true),is_noncritical_run(false),is_fill(_is_fill),
        need_input_copy(false),result_end(0),rng((cimg::_rand(),cimg::rng())),
        calling_function(funcname?funcname:"cimg_math_parser") {

#if cimg_use_openmp!=0
        rng+=omp_get_thread_num();
#endif
        if (!expression || !*expression)
          throw CImgArgumentException("[" cimg_appname "_math_parser] "
                                      "CImg<%s>::%s: Empty expression.",
                                      pixel_type(),_cimg_mp_calling_function);
        const char *_expression = expression;
        while (*_expression && (cimg::is_blank(*_expression) || *_expression==';')) ++_expression;
        CImg<charT>::string(_expression).move_to(expr);
        char *ps = &expr.back() - 1;
        while (ps>expr._data && (cimg::is_blank(*ps) || *ps==';')) --ps;
        *(++ps) = 0; expr._width = (unsigned int)(ps - expr._data + 1);

        // Ease the retrieval of previous non-space characters afterwards.
        pexpr.assign(expr._width);
        char c, *pe = pexpr._data;
        for (ps = expr._data, c = ' '; *ps; ++ps) {
          if (!cimg::is_blank(*ps)) c = *ps; else *ps = ' ';
          *(pe++) = c;
        }
        *pe = 0;
        level = get_level(expr);

View on GitHub (pinned to f788b534b4)

Solutions

  1. Validate the expression is non-null and non-empty before passing it to fill()/eval().
  2. Trim and check the string after loading from config or user input.
  3. Provide a default formula when the configured one is blank.
  4. Catch CImgArgumentException and report 'empty formula' to the user instead of crashing.

Example fix

// before
const char* expr = cfg.get("formula"); // may be NULL/empty
img.fill(expr); // throws: Empty expression
// after
const char* expr = cfg.get("formula");
if (expr && *expr) {
  img.fill(expr);
} else {
  img.fill("0"); // sensible default
}
Defensive patterns

Strategy: validation

Validate before calling

if (!expr || !*expr) { /* reject before calling CImg */ return ERR_EMPTY_FORMULA; }
img.fill(expr);

Type guard

bool valid_expression(const char* s) { return s != nullptr && *s != '\0'; }

Try / catch

try {
  img.fill(expr);
} catch (const CImgArgumentException& e) {
  // e.what() contains '[appname_math_parser] ... Empty expression.'
  showUserError("formula is empty");
}

Prevention

When it happens

Trigger: Calling img.fill(""), img.eval(""), get_eval(NULL), or passing an expression from a config file/CLI that resolved to empty; also strings that contain only blanks/semicolons after trimming in some paths.

Common situations: Formula read from preferences/INI file where the key is missing or empty; user submitted a blank formula; a variable holding the expression was never initialized.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/d765397ba5705e47. Report an issue: GitHub.