{"record":{"id":"01902397b6138638","repo":"Yalantis/uCrop","slug":"permute-axes-invalid-specified-axes-order-s","errorCode":null,"errorMessage":"permute_axes(): Invalid specified axes order '%s'.","messagePattern":"permute_axes\\(\\): Invalid specified axes order '(.+?)'\\.","errorType":"validation","errorClass":"CImgArgumentException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":39314,"sourceCode":"    }\n\n    //! Permute axes order \\newinstance.\n    CImg<T> get_permute_axes(const char *const axes_order) const {\n      const T foo = (T)0;\n      return _permute_axes(axes_order,foo);\n    }\n\n    unsigned int _permute_axes_uicase(const char *const axes_order) const { // Convert axes to integer case number\n      unsigned char s_axes[4] = { 0,1,2,3 }, n_axes[4] = { };\n      bool is_error = false;\n      if (axes_order) for (unsigned int l = 0; axes_order[l]; ++l) {\n          int c = cimg::lowercase(axes_order[l]);\n          if (l>=4 || (c!='x' && c!='y' && c!='z' && c!='c')) { is_error = true; break; }\n          else { ++n_axes[c%=4]; s_axes[l] = (unsigned char)c; }\n        }\n      is_error|=(*n_axes>1) || (n_axes[1]>1) || (n_axes[2]>1) || (n_axes[3]>1);\n      if (is_error)\n        throw CImgArgumentException(_cimg_instance\n                                    \"permute_axes(): Invalid specified axes order '%s'.\",\n                                    cimg_instance,\n                                    axes_order);\n      return (s_axes[0]<<12) | (s_axes[1]<<8) | (s_axes[2]<<4) | (s_axes[3]);\n    }\n\n    bool _permute_axes_is_optim(const unsigned int uicase) const { // Determine cases where nothing has to be done\n      const unsigned int co = ((_width>1)<<3)|((_height>1)<<2)|((_depth>1)<<1)|(_spectrum>1);\n      if (co<=2 || uicase==0x0123) return true;\n      switch (uicase) {\n      case (0x0132) : if ((co>=4 && co<=6) || (co>=8 && co<=10) || (co>=12 && co<=14)) return true; break;\n      case (0x0213) : if ((co>=3 && co<=5) || (co>=8 && co<=13)) return true; break;\n      case (0x0231) : if (co==3 || co==4 || (co>=8 && co<=12)) return true; break;\n      case (0x0312) : if (co==4 || co==6 || co==8 || co==9 || co==10 || co==12 || co==14) return true; break;\n      case (0x0321) : if (co==4 || (co>=8 && co<=10) || co==12) return true; break;\n      case (0x1023) : if (co>=3 && co<=11) return true; break;\n      case (0x1032) : if ((co>=4 && co<=6) || (co>=8 && co<=10)) return true; break;\n      case (0x1203) : if (co>=3 && co<=9) return true; break;","sourceCodeStart":39296,"sourceCodeEnd":39332,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L39296-L39332","documentation":"CImg's permute_axes() accepts an axes_order string of up to 4 characters that must be some permutation of 'x','y','z','c'. The parsing loop marks is_error if the string is longer than 4 characters, contains any character outside {x,y,z,c}, or repeats an axis (any n_axes count > 1). On error it throws CImgArgumentException showing the supplied order string.","triggerScenarios":"Calling CImg<T>::permute_axes(axes_order) with: a string longer than 4 chars (e.g. \"xyzcxyz\"), invalid characters (uppercase \"XYZC\", digits, whitespace), or a duplicated axis like \"xxy\" or \"xyzx\". Also an empty or short string like \"xy\" — short strings are allowed only as abbreviations, but \"xyy\" is not.","commonSituations":"Building the axes string dynamically from user config with wrong case ('YX'); typo'd axis strings ('xyyz'); porting code from libraries that use 0-3 numeric permutations; locale/formatting bugs appending separators like commas ('x,y,z,c').","solutions":["Supply a string whose characters are exactly a permutation of x, y, z, c, with each axis appearing at most once (e.g. \"zyxc\", \"yx\").","Convert to lowercase and strip non-axis characters (commas, spaces) before calling.","Add pre-call validation: check length <= 4, all chars in {x,y,z,c}, and no duplicates; raise an app-level error otherwise.","If you need to permute by indices, generate the string programmatically from indices 0-3 mapped to \"xyzc\"."],"exampleFix":"// before\nimg.permute_axes(\"XYZC\"); // uppercase and 4+ chars rejected per rules\n// after\nimg.permute_axes(\"zyxc\"); // lowercase permutation of x,y,z,c","handlingStrategy":"validation","validationCode":"// C++\nbool isValidAxesOrder(const std::string& order) {\n    if (order.empty() || order.size() > 4) return false;\n    int count[4] = {0,0,0,0};\n    for (char ch : order) {\n        int i = std::string(\"xyzc\").find(std::tolower(ch));\n        if (i < 0 || ++count[i] > 1) return false;\n    }\n    return true;\n}\nstd::string order = normalize(userOrder); // lowercase, strip separators\nif (!isValidAxesOrder(order)) throw std::invalid_argument(\"axes_order must be a permutation of xyzc\");\nimg.permute_axes(order.c_str());","typeGuard":"bool isValidAxesOrder(const std::string& s) {\n    if (s.empty() || s.size() > 4) return false;\n    int n[4] = {0,0,0,0};\n    for (char c : s) { int i = std::string(\"xyzc\").find(c); if (i<0 || ++n[i]>1) return false; }\n    return true;\n}","tryCatchPattern":"try {\n    img.permute_axes(order.c_str());\n} catch (const cimg_library::CImgArgumentException& e) {\n    // log e.what(); keep original axis order\n}","preventionTips":["Normalize case and strip separators (commas/spaces) from axes strings at input boundaries","Reject duplicates early with a small validator mirroring CImg's rules","Build axes strings programmatically from indices 0-3 mapped to \"xyzc\" rather than hand-typing","Add a unit test covering each invalid form: uppercase, >4 chars, duplicated axis"],"tags":["cimg","invalid-argument","permute-axes","axis-order"],"backgroundTag":"invalid-argument-format","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"}