On Tue, Oct 16, 2018 at 8:02 AM wjm wjm <[email protected]> wrote: > > seems that jackson have some problems when parse super number > Gson failed at once, but jackson block long times and then failed > because jackson parse the super number to BigInteger first and then convert > to target number type. > > i write a reproduce test case > please help me to resolve the problem, thanks > > package test.jackson; > > import java.util.concurrent.Callable; > > import com.fasterxml.jackson.databind.ObjectMapper; > import com.google.common.base.Strings; > import com.google.gson.Gson; > import com.google.gson.GsonBuilder; > > public class DoS { > static String input = Strings.repeat("1", 100_0000); > > static Gson gson = new GsonBuilder().create(); > > static ObjectMapper mapper = new ObjectMapper(); > > public static enum Color { > WHITE, > BLACK > } > > static void run(String name, Callable callable) { > System.out.println(name); > > long start = System.currentTimeMillis(); > try { > Object result = callable.call(); > System.out.println(" result:" + result); > } catch (Throwable e) { > //System.out.println(" failed: " + e.getMessage()); > System.out.println(" failed"); > } > System.out.println(" time:" + (System.currentTimeMillis() - start) + " > ms"); > } > > public static void main(String[] args) { > run("Gson enum:", () -> gson.fromJson(input, Color.class)); > run("Jackson enum:", () -> mapper.readValue(input, Color.class)); > System.out.println(); > > // byte/Byte/short/Short/int/Integer/long/Long > // all these types, jackson is very slow > run("Gson int:", () -> gson.fromJson(input, int.class)); > run("Jackson int:", () -> mapper.readValue(input, int.class)); > System.out.println(); > > // float/Float/double/Double > // all these types, jackson is very slow > run("Gson double:", () -> gson.fromJson(input, double.class)); > run("Jackson double:", () -> mapper.readValue(input, double.class)); > System.out.println(); > } > } > > > the output is : > Gson enum: > result:null > time:16 ms > Jackson enum: > failed > time:17469 ms > > Gson int: > failed > time:32 ms > Jackson int: > failed > time:17392 ms > > Gson double: > result:Infinity > time:8 ms > Jackson double: > result:Infinity > time:18187 ms
Ok, this is obviously a big problem. I filed: https://github.com/FasterXML/jackson-databind/issues/2157 to cover it, and this is related to earlier https://github.com/FasterXML/jackson-databind/issues/2141 Unfortunately problem is difficult to tackle. Jackson does figure out magnitude part during decoding, and use "smallest possible" type for integral numbers, from group of `int`, `long` and `BigInteger` (for floating-point logic is bit different, but similar idea applies). Problem occurs when target type needed by databinding is something else: like very long integer number that is to be used for filling `int` field. This operation is slow with JDK, and should be avoided partly because overflow check would fail anyway -- but this is only applied after very slow conversion, allowing DoS attacks. I have some questions on how this could and should be handled, regarding things like: 1. On "too big" (big magnitude) number, should we typically truncate to MAX_VALUE (for `double`), or throw exception (latter for integral I think) 2. On "too small" (small magnitude) number, should we truncate to zero 3. If applying strict limits to longest BigInteger/BigDecimal, are there safe length limits? Same use cases (like cryptography) use relatively long numbers legitimately, for example But. Maybe I can figure out solution to bounds-check-fail case at least, first. -+ Tatu +- ps. This is not limited to json either; almost certainly applicable to XML, YAML, possibly CSV, Properties. So I think help would be useful in figuring out extent of the problem. -- You received this message because you are subscribed to the Google Groups "jackson-user" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. For more options, visit https://groups.google.com/d/optout.
