Yalantis/uCrop · error · CImgArgumentException
[" cimg_appname "_math_parser] CImg<%s>::%s: Unbalanced pare
Error message
[" cimg_appname "_math_parser] CImg<%s>::%s: Unbalanced parentheses/brackets, in expression '%s'.
What it means
After tokenizing the math expression, the CImg parser tracks nesting depth (_level). If the level is non-zero at the end of parsing, some '(' or '[' was never closed (or a ')' / ']' was closed out of order), so it throws CImgArgumentException for unbalanced parentheses/brackets. This is a structural validation pass that always runs before the compiled expression is returned.
Source
Thrown at ucrop/src/main/jni/CImg.h:25023
}
*(pd++) = (unsigned int)(mode>=1 || is_escaped?_level + (mode==1):
*ps=='(' || *ps=='['?_level++:
*ps==')' || *ps==']'?--_level:
_level);
mode = next_mode;
is_escaped = next_is_escaped;
next_is_escaped = false;
}
if (mode) {
cimg::strellipsize(_expr,64);
throw CImgArgumentException("[" cimg_appname "_math_parser] "
"CImg<%s>::%s: Unterminated string literal, in expression '%s'.",
pixel_type(),_cimg_mp_calling_function,
_expr._data);
}
if (_level) {
cimg::strellipsize(_expr,64);
throw CImgArgumentException("[" cimg_appname "_math_parser] "
"CImg<%s>::%s: Unbalanced parentheses/brackets, in expression '%s'.",
pixel_type(),_cimg_mp_calling_function,
_expr._data);
}
return res;
}
// Find and return index of current image 'imgin' within image list 'imglist'.
unsigned int get_mem_img_index() {
if (mem_img_index==~0U) {
if (&imgout>=imglist.data() && &imgout<imglist.end())
mem_img_index = const_scalar((double)(&imgout - imglist.data()));
else {
unsigned int pos = ~0U;
cimglist_for(imglist,l)
if (imgout._data==imglist[l]._data && imgout.is_sameXYZC(imglist[l])) { pos = l; break; }
if (pos!=~0U) mem_img_index = const_scalar((double)pos);
}View on GitHub (pinned to f788b534b4)
Solutions
- Count and match every '(' with ')' and every '[' with ']' in the expression string
- Log the full expression (the error truncates it to 64 chars) and check the tail for dangling open brackets
- If generating expressions in code, build them with a small helper that tracks nesting depth and asserts balance before calling CImg
- Validate the expression with a paren-balance check before passing it to the CImg API
Example fix
// before
img.fill("sin(x*(cos(y)"); // unbalanced: missing one ')'
// after
img.fill("sin(x*(cos(y)))"); Defensive patterns
Strategy: validation
Validate before calling
// C++: verify parentheses/bracket balance before calling CImg
bool brackets_balanced(const std::string& e) {
int d = 0;
for (char c : e) {
if (c == '(' || c == '[') ++d;
else if (c == ')' || c == ']') --d;
if (d < 0) return false;
}
return d == 0;
}
if (!brackets_balanced(expr)) throw std::invalid_argument("unbalanced parentheses in expression"); Type guard
bool has_balanced_brackets(const std::string& e); // see validationCode
Try / catch
try {
img.fill(expr);
} catch (const cimg_library::CImgArgumentException& e) {
std::cerr << "Unbalanced brackets in: " << expr << std::endl;
} Prevention
- Build nested expressions with a builder that tracks depth
- Keep indentation in generated expression strings aligned to nesting
- Run a paren-balance unit test over every expression constant in the codebase
When it happens
Trigger: Calling a CImg function with an expression string such as img.fill("sin(x*(cos(y)") where an opening '(' or '[' lacks its closing partner, or brackets are closed in the wrong order like "(x]")". Also occurs when a builder or template generates expressions with conditionally dropped closing brackets.
Common situations: Hand-written formulas with deeply nested function calls; code-generated expressions where a branch omits a closing paren; editing expressions by hand and deleting one side of a bracket pair; macro/template substitution producing broken formulas.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- [" cimg_appname "_math_parser] CImg<%s>::%s: Unterminated st
- [cimg_appname_math_parser] CImg<%s>::%s: %s%s Missing %s, in
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Too much specif
- [cimg_appname_math_parser] CImg<%s>::%s: %s: %s name specifi
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Invalid assignm
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/5d683305fa96328c.
Report an issue: GitHub.