{"record":{"id":"61699324c19d9a6b","repo":"didi/DoKit","slug":"multiple-wildcards-present-in-rule-expression","errorCode":null,"errorMessage":"Multiple wildcards present in rule expression \" + ruleExpression","messagePattern":"Multiple wildcards present in rule expression \" \\+ ruleExpression","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/core/MimeMatcher.java","lineNumber":53,"sourceCode":"    return null;\n  }\n\n  @SuppressLint(\"BadMethodUse-java.lang.String.length\")\n  private class MimeMatcherRule {\n    private final boolean mHasWildcard;\n    private final String mMatchPrefix;\n    private final T mResultIfMatched;\n\n    public MimeMatcherRule(String ruleExpression, T resultIfMatched) {\n      if (ruleExpression.endsWith(\"*\")) {\n        mHasWildcard = true;\n        mMatchPrefix = ruleExpression.substring(0, ruleExpression.length() - 1);\n      } else {\n        mHasWildcard = false;\n        mMatchPrefix = ruleExpression;\n      }\n      if (mMatchPrefix.contains(\"*\")) {\n        throw new IllegalArgumentException(\"Multiple wildcards present in rule expression \" +\n            ruleExpression);\n      }\n      mResultIfMatched = resultIfMatched;\n    }\n\n    public boolean match(String mimeType) {\n      if (!mimeType.startsWith(mMatchPrefix)) {\n        return false;\n      }\n      return (mHasWildcard || mimeType.length() == mMatchPrefix.length());\n    }\n\n    public T getResultIfMatched() {\n      return mResultIfMatched;\n    }\n  }\n}\n","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/core/MimeMatcher.java#L35-L71","documentation":"Thrown by MimeMatcher.MimeMatcherRule's constructor when a rule expression contains more than one '*' wildcard. Only a single trailing wildcard (e.g. \"image/*\") is supported: the constructor strips one trailing '*' into a prefix match, then rejects any remaining '*' in the prefix because prefix matching cannot express interior wildcards.","triggerScenarios":"Constructing a rule with expression \"*/*\", \"image/*;q=*\", \"application/*+json*\", or any string where '*' appears anywhere except the final character. The check runs at rule-creation time, before any match() call.","commonSituations":"Registering MIME rules for the network/image inspector with patterns borrowed from Accept headers (where \"*/*\" is idiomatic) or glob habits from other libraries; trying to express suffix patterns like \"*+json\".","solutions":["Use a single trailing wildcard only: \"image/*\" instead of \"*/*\" — for match-everything use an empty prefix with trailing '*', i.e. \"*\"","Express interior/suffix patterns as multiple explicit rules or match on substring in your own code instead of MimeMatcher","Validate the expression at configuration load time and fail fast with a clear config error"],"exampleFix":"// before\nmatcher.addRule(\"*/*\", MATCH_ALL); // second '*' inside prefix -> throws\n\n// after\nmatcher.addRule(\"*\", MATCH_ALL); // single trailing wildcard, matches everything","handlingStrategy":"validation","validationCode":"static boolean isValidMimeRule(String expr) {\n  if (expr == null) return false;\n  String prefix = expr.endsWith(\"*\") ? expr.substring(0, expr.length() - 1) : expr;\n  return prefix.indexOf('*') == -1;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use only a single trailing wildcard ('image/*', '*')","Do not copy Accept-header patterns like '*/*' or '*+json' into MimeMatcher rules"],"tags":["android","network","mime-type","validation"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}