Skip to content

Commit

Permalink
Safely call snakeyaml methods that have been changed in last versions. (
Browse files Browse the repository at this point in the history
#3904)

* Safely call snakeyaml methods that have been changed in last versions.
  • Loading branch information
filipelautert authored Mar 7, 2023
1 parent a7b0346 commit 8ef0c4f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public abstract class YamlParser implements LiquibaseParser {
public static LoaderOptions createLoaderOptions() {
LoaderOptions options = new LoaderOptions();
SnakeYamlUtil.setCodePointLimitSafely(options, Integer.MAX_VALUE);
options.setProcessComments(false);
SnakeYamlUtil.setProcessCommentsSafely(options, false);
options.setAllowDuplicateKeys(false);
options.setAllowRecursiveKeys(false);
return options;
Expand Down
44 changes: 34 additions & 10 deletions liquibase-core/src/main/java/liquibase/util/SnakeYamlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,49 @@
import liquibase.Scope;
import org.yaml.snakeyaml.LoaderOptions;

/**
* This class provides methods that are necessary because older (< 1.32) versions of SnakeYaml do not have
* those methods. Thus, if someone is using an older version of SnakeYaml, we do not want to interrupt Liquibase
* execution with an exception anymore.
*/
public class SnakeYamlUtil {

private static boolean showErrorMessage = true;

private SnakeYamlUtil() {

}

/**
* Safely set the code point limit when configuring a new SnakeYaml instance. This method is necessary because
* older versions of SnakeYaml do not have the ability to set a code point limit. Thus, if someone is using an older
* version of SnakeYaml, we do not want to interrupt Liquibase execution with an exception.
* Safely set the code point limit when configuring a new SnakeYaml instance.
*/
public static void setCodePointLimitSafely(LoaderOptions loaderOptions, int codePointLimit) {
safelyCallNewSnakeYamlMethod(() -> loaderOptions.setCodePointLimit(codePointLimit));
}

/**
* Safely set configuration to process comments when configuring a new SnakeYaml instance. This method
* had the return type changed.
*/
public static void setProcessCommentsSafely(LoaderOptions loaderOptions, boolean enable) {
safelyCallNewSnakeYamlMethod(() -> loaderOptions.setProcessComments(enable));
}

/**
* Helper method to make sure that we display the error message only once.
*/
private static void safelyCallNewSnakeYamlMethod(Runnable code) {
try {
loaderOptions.setCodePointLimit(codePointLimit);
} catch (NoSuchMethodError e) {
Scope.getCurrentScope().getLog(SnakeYamlUtil.class).warning(
"Failed to set code point limit for SnakeYaml, because the version of SnakeYaml being used is too old. " +
"Consider upgrading to a SnakeYaml version equal to or newer than 1.32, by downloading and " +
"installing a newer version of Liquibase (which includes a newer version of SnakeYaml). " +
"Loading particularly large JSON and YAML documents (like snapshots) in Liquibase may fail if SnakeYaml is not upgraded.", e);
code.run();
} catch (NoSuchMethodError | BootstrapMethodError e) {
if (showErrorMessage) {
showErrorMessage = false;
Scope.getCurrentScope().getLog(SnakeYamlUtil.class).warning(
"Failed to perform a method call for SnakeYaml because the version of SnakeYaml being used is too old. " +
"Consider upgrading to a SnakeYaml version equal to or newer than 1.32, by downloading and " +
"installing a newer version of Liquibase (which includes a newer version of SnakeYaml). " +
"Loading particularly large JSON and YAML documents (like snapshots) in Liquibase may fail if SnakeYaml is not upgraded.", e);
}
}
}
}

0 comments on commit 8ef0c4f

Please sign in to comment.