Fresco: Fatal Exception: java.lang.NullPointerException: Attempt to get length of null array

Created on 26 May 2020  路  5Comments  路  Source: facebook/fresco

We are getting following crash on Crashlytics for good number of users with Android OS 8, with more than 47 devices.
We are using "com.facebook.fresco:fresco:2.2.0"

Could you please help us, since its happening on. multiple users.

Logs :

Fatal Exception: java.lang.NullPointerException: Attempt to get length of null array
at java.util.Formatter$FormatSpecifier.addZeros(Formatter.java:3505)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:3401)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:3332)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:3317)
at java.util.Formatter$FormatSpecifier.printFloat(Formatter.java:2891)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2844)
at java.util.Formatter.format(Formatter.java:2523)
at java.util.Formatter.format(Formatter.java:2458)
at java.lang.String.format(String.java:2814)
at com.facebook.common.logging.FLog.formatString(FLog.java:491)
at com.facebook.common.logging.FLog.v(FLog.java:118)
at com.facebook.imagepipeline.transcoder.DownsampleUtil.determineDownsampleRatio(DownsampleUtil.java:87)
at com.facebook.imagepipeline.transcoder.DownsampleUtil.determineSampleSize(DownsampleUtil.java:43)
at com.facebook.imagepipeline.producers.DecodeProducer$ProgressiveDecoder$1.run(DecodeProducer.java:163)
at com.facebook.imagepipeline.producers.JobScheduler.doJob(JobScheduler.java:202)
at com.facebook.imagepipeline.producers.JobScheduler.access$000(JobScheduler.java:22)
at com.facebook.imagepipeline.producers.JobScheduler$1.run(JobScheduler.java:73)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at com.facebook.imagepipeline.core.PriorityThreadFactory$1.run(PriorityThreadFactory.java:51)
at java.lang.Thread.run(Thread.java:764)

bug good first issue help wanted

Most helpful comment

I was curious about the problem the other day, even without the evidence and ability to reproduce it. Here is what I've found.

Initially, I was thinking that the problem somehow related to the locale that has not been set up in FLog.formatString()

Screen Shot 2020-07-13 at 2 20 27 PM

However, there are _three_ concerns.
First of all, in the particular example FLog.v() works with the conversion from primitives to String, not vice-versa. So, probably, there is no need to worry about Locale problems like , (comma) or . (dot) for decimals.

Second, despite the fact of the @NonNull argument, String.format() allows passing null Locale

Screen Shot 2020-07-13 at 2 26 11 PM

Nevertheless, String.format has overloading without passing Locale

Screen Shot 2020-07-13 at 2 34 13 PM

that sets just to default Locale for Formatter.

Screen Shot 2020-07-13 at 2 35 22 PM

I believe, the reason behind setting it to the null in the FLog.formatString() is that _Lint_ has a LocaleDetector check that reminds about that decision. So, probably, that was a way to suppress it? If it is then, I believe, it's not a good practice.

And the last concern is the reason why NPE happens in the first place.
If to look down the road of the stack, the problem is in Formatter.addZeroes() where it's simply one of the arguments, char[] v which is not guarded

Screen Shot 2020-07-13 at 3 04 37 PM

Back to the caller, print() shows that this is a mantissa which converts from double value to char[] with help of FormattedFloatingDecimal

Screen Shot 2020-07-13 at 3 09 39 PM

FormattedFloatingDecimal is part of the sun.misc package that is not _Android-Changed_.

Screen Shot 2020-07-13 at 3 11 13 PM

And it's possible to obtain a null mantissa since it's not guarded.

Screen Shot 2020-07-13 at 3 14 15 PM

However, in all cases of the constructor logic mantissa has to be assigned, even if it's just new char[0].

At the same time, I've found that WebRTC team that is part of the _Android SDK_ has faced the same problem 2 years ago where they specified it as

crashes... on some devices

and suggests a _Speculative_ fix by using DecimalFormat instead of String.Format for floats.
By the way, initially, they've had used Locale.US in String.Format while getting the problem, so it's feasible to assume the problem is not related to the Locale.

On the other hand, DecimalFormat doesn't use anything from sun.misc packages.

Conclusion.

I'm curious if the problem anyhow correlated with the fact that it's about FormattedFloatingDecimal from sun.misc package. Maybe these devices have been using some sort of customized _AOSP_? I've found no other evidence of the problem than that with WebRTC.

_Speculative_ fix is to use DecimalFormat. The problem is that it has to be done through FLog.formatString() since the problem is in there.

@pnkshir it would be great to have a bit more information about the devices with crashes if it's possible.
@oprisnik Please, let me know what you think and if there are enough reasons to apply a _Speculative_ fix.

All 5 comments

Thanks for the bug report.

That's weird, looks like the log statement is failing: https://github.com/facebook/fresco/blob/e791687a6617eaeb5f8e5524452541777ddc4aa4/imagepipeline-base/src/main/java/com/facebook/imagepipeline/transcoder/DownsampleUtil.java#L103

Setting your log level to anything that's smaller than verbose (like ERROR or WARN) should help: FLog.setMinimumLoggingLevel(WARN)

Ideally, we should figure out why String.format is failing here.

I was curious about the problem the other day, even without the evidence and ability to reproduce it. Here is what I've found.

Initially, I was thinking that the problem somehow related to the locale that has not been set up in FLog.formatString()

Screen Shot 2020-07-13 at 2 20 27 PM

However, there are _three_ concerns.
First of all, in the particular example FLog.v() works with the conversion from primitives to String, not vice-versa. So, probably, there is no need to worry about Locale problems like , (comma) or . (dot) for decimals.

Second, despite the fact of the @NonNull argument, String.format() allows passing null Locale

Screen Shot 2020-07-13 at 2 26 11 PM

Nevertheless, String.format has overloading without passing Locale

Screen Shot 2020-07-13 at 2 34 13 PM

that sets just to default Locale for Formatter.

Screen Shot 2020-07-13 at 2 35 22 PM

I believe, the reason behind setting it to the null in the FLog.formatString() is that _Lint_ has a LocaleDetector check that reminds about that decision. So, probably, that was a way to suppress it? If it is then, I believe, it's not a good practice.

And the last concern is the reason why NPE happens in the first place.
If to look down the road of the stack, the problem is in Formatter.addZeroes() where it's simply one of the arguments, char[] v which is not guarded

Screen Shot 2020-07-13 at 3 04 37 PM

Back to the caller, print() shows that this is a mantissa which converts from double value to char[] with help of FormattedFloatingDecimal

Screen Shot 2020-07-13 at 3 09 39 PM

FormattedFloatingDecimal is part of the sun.misc package that is not _Android-Changed_.

Screen Shot 2020-07-13 at 3 11 13 PM

And it's possible to obtain a null mantissa since it's not guarded.

Screen Shot 2020-07-13 at 3 14 15 PM

However, in all cases of the constructor logic mantissa has to be assigned, even if it's just new char[0].

At the same time, I've found that WebRTC team that is part of the _Android SDK_ has faced the same problem 2 years ago where they specified it as

crashes... on some devices

and suggests a _Speculative_ fix by using DecimalFormat instead of String.Format for floats.
By the way, initially, they've had used Locale.US in String.Format while getting the problem, so it's feasible to assume the problem is not related to the Locale.

On the other hand, DecimalFormat doesn't use anything from sun.misc packages.

Conclusion.

I'm curious if the problem anyhow correlated with the fact that it's about FormattedFloatingDecimal from sun.misc package. Maybe these devices have been using some sort of customized _AOSP_? I've found no other evidence of the problem than that with WebRTC.

_Speculative_ fix is to use DecimalFormat. The problem is that it has to be done through FLog.formatString() since the problem is in there.

@pnkshir it would be great to have a bit more information about the devices with crashes if it's possible.
@oprisnik Please, let me know what you think and if there are enough reasons to apply a _Speculative_ fix.

Hi,
Our users are having the same problem on Android 8.1.0, but not on Fresco.
These are the devices:
image
Xiaomi Redmi 6 Pro
Xiaomi Redmi 5 Plus
Vivo V1818A
Vivo V1732A
Samsung Galaxy J7(2016)
Samsung Galaxy J2 Core
OPPO A5
Huawei Y3 2018

It is failing on formatting the latitude and longitude (double):
String.format(Locale.ENGLISH, "%.6f", latitude)

Hey @tsybanov - thank you for the detailed report and sorry for the late reply.

I think we should try your speculative fix, so it would be great if you could submit a PR.

yet another device

vivo(vivo Y85A) on android 8.1

Was this page helpful?
0 / 5 - 0 ratings