Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8252965

[macos] Font.canDisplayUpTo returns wrong index for Indic text which causes crash later | OpenJDK Corretto 8.265.01.2

    XMLWordPrintable

Details

    • 2d
    • x86_64
    • os_x

    Description

      ADDITIONAL SYSTEM INFORMATION :
      macOS 10.15.6 (also breaks on 10.14 and 10.13)
      OpenJDK Corretto 8.265.01.2

      A DESCRIPTION OF THE PROBLEM :
      We have a JTable that displays rows of information. One column in the table has data in the language of the content associated with the row. Some characters in the text are not displayable by the UI font. So we use java.awt.Font.caDisplayUpTo on the entries in this column. If any cannot be displayed, then we hide the column.
      With a specific dataset with Malayalam text, the API return -1 (saying that it can be displayed with Lucida Grande font) while on Windows it return 0 (saying that it can't display any of the text with Tahoma font). On Linux it return -1 and displays correctly.

      Later on, when trying to display the text in the JTable, an exception happens in:

      libfontmanager.dylib
      IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage&, IndicRearrangementVerb, LEErrorCode&)

      Sometime, the callstack is slightly different or it can't determine it.

      Here is a crash report from the sample code below:
      https://drive.google.com/file/d/18-6TVQ591J_YgtaOP1-o3NFgPiGIhyfV/view?usp=sharing

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Install Scripture App Builder (https://software.sil.org/scriptureappbuilder/download)
      Install Corretto JDK
      Create a new project
      Add book with Malayalam text (USFM markup with \h tag with Malayalam book name)

      Here is a video showlng how to to reproduce the crash:
      https://www.loom.com/share/8a93b968dee04bd79297b06ef68af9de

      Here is the dataset that causes the crash:
      https://drive.google.com/drive/folders/1hlq4_D3SG9BTY6B4-I0CbjT_YI4w3Ftc?usp=sharing



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Either:
      1 - Font.canDisplayTo should return 0 so that we know to not display the column of text (Like Windows)
      2 - Display the text correctly (Like Linux)
      ACTUAL -
      App crashes when trying to display text that the system has said it could display.

      ---------- BEGIN SOURCE ----------
      package org.sil;

      import javax.swing.*;
      import javax.swing.table.DefaultTableModel;
      import java.awt.*;

      public class Main {
          public static void main(String[] args) {
              Main app = new Main();
              app.buildAndDisplayGui();
          }

          private void buildAndDisplayGui() {
              JFrame frame = new JFrame("Test");
              buildContent(frame);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.pack();
              frame.setVisible(true);
          }

          private void buildContent(JFrame frame) {
              JPanel panel = new JPanel();
              JTable table = new JTable();

              String[] columnNames = new String[2];
              columnNames[0] = "Book Id";
              columnNames[1] = "Book Name";

              DefaultTableModel model = new DefaultTableModel(columnNames, 2);
              table.setModel(model);

              // This works
              addRow(model, table.getFont(), "1", "Test");
              // This crashes
              addRow(model, table.getFont(), "2", "പത്രൊസ്");
              updateRowHeights(table);

              panel.add(table);
              frame.getContentPane().add(panel);
          }

          private void addRow(DefaultTableModel model, Font font, String bookId, String bookName) {
              Object[] columns = new Object[2];

              columns[0] = bookId;
              if (font.canDisplayUpTo(bookName) < 0) {
                  columns[1] = bookName;
              } else {
                  columns[1] = "Fail";
              }

              model.addRow(columns);
          }

          private void updateRowHeights(JTable table)
          {
              try {
                  for (int row = 0; row < table.getRowCount(); row++) {
                      int rowHeight = table.getRowHeight();

                      for (int column = 0; column < table.getColumnCount(); column++) {
                          Component comp = table.prepareRenderer(table.getCellRenderer(row, column), row, column);
                          rowHeight = Math.max(rowHeight, comp.getPreferredSize().height);
                      }

                      table.setRowHeight(row, rowHeight);
                  }
              }
              catch(ClassCastException e) {
              }
          }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use JDK 8u202 (we are nonprofit so can't use JDK 8u261)

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              simonis Volker Simonis
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: