• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

database-rider / database-rider / #911

27 Oct 2024 07:44PM CUT coverage: 83.964% (+0.01%) from 83.951%
#911

push

web-flow
#610 fix support for parent classes hierarchy (#612)

* refs #610 fix annotation support for parent classes hierarchy

---------

Co-authored-by: Lee <hosing.lee@hsl-it-solutions.nl>

9 of 9 new or added lines in 1 file covered. (100.0%)

3084 of 3673 relevant lines covered (83.96%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.57
/rider-core/src/main/java/com/github/database/rider/core/configuration/SnakeYamlHelper.java
1
package com.github.database.rider.core.configuration;
2

3
import org.yaml.snakeyaml.LoaderOptions;
4
import org.yaml.snakeyaml.Yaml;
5
import org.yaml.snakeyaml.nodes.Tag;
6

7
import java.lang.invoke.CallSite;
8
import java.lang.invoke.LambdaMetafactory;
9
import java.lang.invoke.MethodHandle;
10
import java.lang.invoke.MethodHandles;
11
import java.lang.invoke.MethodType;
12
import java.lang.reflect.Method;
13

14
/**
15
 * A Helper to create {@link Yaml} instance that is pre-configured to not restrict types which can be instantiated
16
 * during deserialization. Works with both SnakeYaml 1.x and 2.x.
17
 * <p>
18
 * SnakeYaml 2.0 solved the
19
 * <a href="https://www.cve.org/CVERecord?id=CVE-2022-1471">unsafe deserialization vulnerability</a> by changing the
20
 * default behavior of constructed {@link Yaml} instance to restrict types which can be instantiated during
21
 * deserialization. This behavior made impossible to define custom DataSet replacers in YAML as they must be
22
 * instantiated during deserialization. This helper uses reflection to conditionally configure {@link Yaml} instance
23
 * to accept any types during deserialization if SnakeYaml 2.x is used.
24
 */
25
public class SnakeYamlHelper {
×
26

27
    public static Yaml createYaml() {
28
        LoaderOptions loaderOptions = createLoaderOptions();
1✔
29
        return new Yaml(loaderOptions);
1✔
30
    }
31

32
    private static LoaderOptions createLoaderOptions() {
33
        LoaderOptions loaderOptions = new LoaderOptions();
1✔
34

35
        try {
36
            // If Snakeyaml 2.x is used, loaderOptions.setTagInspector(tag -> true) must be called to allow
37
            // to instantiate any classes during deserialization (e.g. properties.replacers in dbunit.yml).
38
            // There is no such method in Snakeyaml 1.x, so the reflection is used to try to call the method
39
            // to support both Snakeyaml 1.x and 2.x.
40
            Class<?> tagInspectorClass = Class.forName("org.yaml.snakeyaml.inspector.TagInspector");
×
41
            Method setTagInspector = loaderOptions.getClass().getMethod("setTagInspector", tagInspectorClass);
×
42
            Object isGlobalTagAllowedLambda = createIsGlobalTagAllowedLambda(tagInspectorClass);
×
43
            setTagInspector.invoke(loaderOptions, isGlobalTagAllowedLambda);
×
44
        } catch (ClassNotFoundException e) {
1✔
45
            // Do nothing as Snakeyaml 1.x is used that allows any classes to be created by default
46
        } catch (Throwable e) {
×
47
            throw new IllegalStateException("Unable to create SnakeYaml LoaderOptions", e);
×
48
        }
1✔
49

50
        return loaderOptions;
1✔
51
    }
52

53
    private static Object createIsGlobalTagAllowedLambda(Class<?> tagInspectorClass) throws Throwable {
54
        MethodType methodType = MethodType.methodType(boolean.class, Tag.class);
×
55
        MethodHandles.Lookup lookup = MethodHandles.lookup();
×
56
        MethodHandle handle = lookup.findStatic(SnakeYamlHelper.class, "isGlobalTagAllowed", methodType);
×
57
        CallSite callSite = LambdaMetafactory.metafactory(
×
58
                lookup,
59
                "isGlobalTagAllowed",
60
                MethodType.methodType(tagInspectorClass),
×
61
                methodType,
62
                handle,
63
                methodType
64
        );
65
        MethodHandle target = callSite.getTarget();
×
66
        return target.invoke();
×
67
    }
68

69
    private static boolean isGlobalTagAllowed(Tag tag) {
70
        return true;
×
71
    }
72

73
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc