JDK-8204590 : NPE in sun.font.PhysicalStrike.getGlyphPoint(PhysicalStrike.java:138)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 8u172
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: os_x
  • CPU: x86_64
  • Submitted: 2018-06-01
  • Updated: 2022-09-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
macOS High Sierra 10.13.4


A DESCRIPTION OF THE PROBLEM :
FontMetrics.stringWidth causes a null pointer exception.
Have tried with the following versions
1.8.0_161 OK
10.0.1 OK
1.8.0_162 CRASH
1.8.0_172 CRASH

The crash was introduced in 1.8.0_162

Stack Trace:
Exception in thread "main" java.lang.NullPointerException
	at sun.font.PhysicalStrike.getGlyphPoint(PhysicalStrike.java:138)
	at sun.font.SunLayoutEngine.nativeLayout(Native Method)
	at sun.font.SunLayoutEngine.layout(SunLayoutEngine.java:158)
	at sun.font.GlyphLayout$EngineRecord.layout(GlyphLayout.java:685)
	at sun.font.GlyphLayout.layout(GlyphLayout.java:466)
	at sun.font.ExtendedTextSourceLabel.createGV(ExtendedTextSourceLabel.java:329)
	at sun.font.ExtendedTextSourceLabel.getGV(ExtendedTextSourceLabel.java:315)
	at sun.font.ExtendedTextSourceLabel.createLogicalBounds(ExtendedTextSourceLabel.java:225)
	at sun.font.ExtendedTextSourceLabel.getAdvance(ExtendedTextSourceLabel.java:134)
	at java.awt.font.TextLine.init(TextLine.java:281)
	at java.awt.font.TextLine.<init>(TextLine.java:129)
	at java.awt.font.TextLine.fastCreateTextLine(TextLine.java:983)
	at java.awt.font.TextLayout.fastInit(TextLayout.java:612)
	at java.awt.font.TextLayout.<init>(TextLayout.java:393)
	at sun.font.FontDesignMetrics.stringWidth(FontDesignMetrics.java:478)
	at seo.spider.serps.TestMe.getFontMetricsPixelWidth(TestMe.java:25)
	at seo.spider.serps.TestMe.main(TestMe.java:16)


REGRESSION : Last worked in version 8u161

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the supplied source code and you will experience the crash.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Shouldn't crash with a NPE in 
ACTUAL -
Exception in thread "main" java.lang.NullPointerException
	at sun.font.PhysicalStrike.getGlyphPoint(PhysicalStrike.java:138)
	at sun.font.SunLayoutEngine.nativeLayout(Native Method)
	at sun.font.SunLayoutEngine.layout(SunLayoutEngine.java:158)
	at sun.font.GlyphLayout$EngineRecord.layout(GlyphLayout.java:685)
	at sun.font.GlyphLayout.layout(GlyphLayout.java:466)
	at sun.font.ExtendedTextSourceLabel.createGV(ExtendedTextSourceLabel.java:329)
	at sun.font.ExtendedTextSourceLabel.getGV(ExtendedTextSourceLabel.java:315)
	at sun.font.ExtendedTextSourceLabel.createLogicalBounds(ExtendedTextSourceLabel.java:225)
	at sun.font.ExtendedTextSourceLabel.getAdvance(ExtendedTextSourceLabel.java:134)
	at java.awt.font.TextLine.init(TextLine.java:281)
	at java.awt.font.TextLine.<init>(TextLine.java:129)
	at java.awt.font.TextLine.fastCreateTextLine(TextLine.java:983)
	at java.awt.font.TextLayout.fastInit(TextLayout.java:612)
	at java.awt.font.TextLayout.<init>(TextLayout.java:393)
	at sun.font.FontDesignMetrics.stringWidth(FontDesignMetrics.java:478)
	at seo.spider.serps.TestMe.getFontMetricsPixelWidth(TestMe.java:25)
	at seo.spider.serps.TestMe.main(TestMe.java:16)

---------- BEGIN SOURCE ----------
import java.awt.Canvas;
import java.awt.Font;
import java.awt.FontMetrics;

public class TestMe
{
    private static final Canvas mCanvas = new Canvas();
    private static final String ARIAL_FONT_NAME = "ArialUnicodeMS";
    
    public static void main(
        String[] args)
    {
        System.out.println(System.getProperty("java.version"));
        int width = getFontMetricsPixelWidth("دائ����ا ��ا ��ت�� تجد��د ا����عدات ا��ت����������ج��ة ����", 14);        
        System.out.println("width " + width);
    }
    
    private static int getFontMetricsPixelWidth(
        final String str,
        int fontSize)
    {
        final FontMetrics fm = mCanvas.getFontMetrics(new Font(ARIAL_FONT_NAME, Font.PLAIN, fontSize));
        return fm.stringWidth(str);
    }

}
---------- END SOURCE ----------

FREQUENCY : always



Comments
Assuming I am not missing a case, CStrike over-rides all the other methods except this one, which is why we haven't seen a problem in non layout cases, although it still is unclear why harfbuzz isn't hitting it. We do install this method as the one to be used to get a contour point. So it looks like we needs to override here too ince getGlyphPoint will need to reference the pScalerContext - which CStrike doesn't use - and pass it to the CFont to get the information. But wait, CFont doesn't over-ride the default implementation in that class getGlyphPoint either. So fixing this to avoid the NPE is fine, but the information being returned is a (0,0) point which is not right. CStrike has a method getNativeGlyphOutline which returns a GeneralPath. Maybe use that ? Or look deeper into the native code that it uses (AWTGetGlyphOutline) and iterate over the CGPath to find the point, avoiding the overhead of the Java path creation. And if CStrike needs to over-ride everything .. is there something we can do short of creating a new super interface. So there's going to be more to fixing this properly.
14-09-2018

The problem is that the macos class CStrike in its constructor does not call super(font, desc) which should be PhysicalStrike(PhysicalFont, FontDesc) so instead calls the no-args super class which of course does not initialise the physicalFont variable. Hence when we try to dereference it, there's an NPE. I don't know why we even added the no-args constructor in PhysicalStrike since the only case it would be useful is if a subclass could and does over-ride *every* method. If it was removed, then CStrike would have had to call super(font, desc). I am a little surprised that even though the Mac font code is quite different than the other platforms that we haven't seen this cause other problems. Inspection shows that this is still the same in 12 so needs to be fixed there.
14-09-2018

I reproduced this : ~/jdk8u162b01/Contents/Home/bin/java TestMe 1.8.0_162-ea Exception in thread "main" java.lang.NullPointerException at sun.font.PhysicalStrike.getGlyphPoint(PhysicalStrike.java:138) at sun.font.SunLayoutEngine.nativeLayout(Native Method) at sun.font.SunLayoutEngine.layout(SunLayoutEngine.java:158) at sun.font.GlyphLayout$EngineRecord.layout(GlyphLayout.java:685) at sun.font.GlyphLayout.layout(GlyphLayout.java:466) at sun.font.ExtendedTextSourceLabel.createGV(ExtendedTextSourceLabel.java:329) at sun.font.ExtendedTextSourceLabel.getGV(ExtendedTextSourceLabel.java:315) at sun.font.ExtendedTextSourceLabel.createLogicalBounds(ExtendedTextSourceLabel.java:225) at sun.font.ExtendedTextSourceLabel.getAdvance(ExtendedTextSourceLabel.java:134) at java.awt.font.TextLine.init(TextLine.java:281) at java.awt.font.TextLine.<init>(TextLine.java:129) at java.awt.font.TextLine.fastCreateTextLine(TextLine.java:983) at java.awt.font.TextLayout.fastInit(TextLayout.java:612) at java.awt.font.TextLayout.<init>(TextLayout.java:393) at sun.font.FontDesignMetrics.stringWidth(FontDesignMetrics.java:478) at TestMe.getFontMetricsPixelWidth(TestMe.java:24) at TestMe.main(TestMe.java:15) It seems to only reproduce with the ICU code path - in 9, 10, 11, 12 it does NOT reproduce, except in 9 if I specify -Dsun.font.layoutengine=icu : ~/jdk9/Contents/Home/bin/java -Dsun.font.layoutengine=icu TestMe 9 Exception in thread "main" java.lang.NullPointerException at java.desktop/sun.font.PhysicalStrike.getGlyphPoint(PhysicalStrike.java:138) at java.desktop/sun.font.SunLayoutEngine.nativeLayout(Native Method) at java.desktop/sun.font.SunLayoutEngine.layout(SunLayoutEngine.java:184) at java.desktop/sun.font.GlyphLayout$EngineRecord.layout(GlyphLayout.java:687) at java.desktop/sun.font.GlyphLayout.layout(GlyphLayout.java:468) at java.desktop/sun.font.ExtendedTextSourceLabel.createGV(ExtendedTextSourceLabel.java:329) at java.desktop/sun.font.ExtendedTextSourceLabel.getGV(ExtendedTextSourceLabel.java:315) at java.desktop/sun.font.ExtendedTextSourceLabel.createLogicalBounds(ExtendedTextSourceLabel.java:225) at java.desktop/sun.font.ExtendedTextSourceLabel.getAdvance(ExtendedTextSourceLabel.java:134) at java.desktop/java.awt.font.TextLine.init(TextLine.java:281) at java.desktop/java.awt.font.TextLine.<init>(TextLine.java:129) at java.desktop/java.awt.font.TextLine.fastCreateTextLine(TextLine.java:978) at java.desktop/java.awt.font.TextLayout.fastInit(TextLayout.java:611) at java.desktop/java.awt.font.TextLayout.<init>(TextLayout.java:392) at java.desktop/sun.font.FontDesignMetrics.stringWidth(FontDesignMetrics.java:478) at TestMe.getFontMetricsPixelWidth(TestMe.java:24) at TestMe.main(TestMe.java:15) It needs a bit of digging to learn if that is just because harfbuzz doesn't make the same call or something else.
14-09-2018

Leaving aside whether we can reproduce this, if it really is new from 8u162 I suspect it is a side-effect of https://bugs.openjdk.java.net/browse/JDK-8169862, since without that fix, we wouldn't be calling the code that calls getGlyphPoint().
14-09-2018

does it affect 12?
14-09-2018

Additional Information ================= I should have made it clearer in the title that this bug happens when you pass Arabic text to the FontMetrics.stringWidth method. I did have an Arabic string in the test code that I submitted but the string seems to have got garbled due to encoding issues unfortunately. =================== Attaching updated reproducer as shared by the submitter. This still need to be checked.
14-09-2018

Checked with updated test case including Arabic test string (see attached), but couldn't reproduce with JDK 8u162 as well as 8u172. Writing back to the submitter with exact test case including mentioned string.
03-07-2018

Additional information from the submitter: =============================== Additional Information: I should have made it clearer in the title that this bug happens when you pass Arabic text to the FontMetrics.stringWidth method. I did have an Arabic string in the test code that I submitted but the string seems to have got garbled due to encoding issues unfortunately. Here is a string that will cause the problem if you pass it to the FontMetrics.stringWidth method: تُعد Aerotecnica Coltri Spa واحدة من الشركات التي تحظى بسمعة طيبة في العالم فيما يتعلق بتصميم وتصنيع ضواغط هواء التنفس وضواغط الغاز الفني للغطس. ==============================================
28-06-2018

As per description in MAC OS X 10.13.4, FontMetrics.stringWidth causes a null pointer exception with JDK 8u172. Checked this for reported JDK version in MAC OS X 10.13.3 and couldn't reproduce the issue. Results: 8u161: OK 8u162: OK 8u171: OK 8u172: Ok 10.0.1: OK 11 ea b15: OK This still need to be verified with reported OS version 10.13.4. TO verify, run the attached test case with respective JDK versions. Meanwhile written back to the submitter requesting additional information to ascertain if the issue is reproducible on any other system including tested version 10.13.3.
08-06-2018