--- old/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java 2020-02-26 10:29:27.997713000 -0500 +++ new/src/jdk.incubator.jpackage/macosx/classes/jdk/incubator/jpackage/internal/MacPkgBundler.java 2020-02-26 10:29:26.339499200 -0500 @@ -510,22 +510,43 @@ return "pkg"; } + public boolean isValidBundleIdentifier(String id) { + for (int i = 0; i < id.length(); i++) { + char a = id.charAt(i); + // We check for ASCII codes first which we accept. If check fails, + // check if it is acceptable extended ASCII or unicode character. + if ((a >= 'A' && a <= 'Z') || (a >= 'a' && a <= 'z') + || (a >= '0' && a <= '9') || (a == '-' || a == '.')) { + continue; + } + return false; + } + return true; + } + @Override public boolean validate(Map params) throws ConfigException { try { Objects.requireNonNull(params); - // run basic validation to ensure requirements are met + // run basic validation to ensure requirements are met // we are not interested in return code, only possible exception validateAppImageAndBundeler(params); - if (MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params) == null) { + String identifier = MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params); + if (identifier == null) { throw new ConfigException( I18N.getString("message.app-image-requires-identifier"), I18N.getString( "message.app-image-requires-identifier.advice")); } + if (!isValidBundleIdentifier(identifier)) { + throw new ConfigException( + MessageFormat.format(I18N.getString( + "message.invalid-identifier"), identifier), + I18N.getString("message.invalid-identifier.advice")); + } // reject explicitly set sign to true and no valid signature key if (Optional.ofNullable(MacAppImageBuilder.