NroffEdit Internet Draft Editor - Bugfix for 2020

The editor "NroffEdit" (Internet Draft Editor) stops working as soon as the computer clock hits Januar 1st 2020.

Currently, there is no official patch.  Scroll down for an inofficial patch.

Symptoms

Opening NroffEdit.jar will not work.

If you call java -jar NroffEdit.jar in the command line, you will see following error:

C:\Users\DELL User>java -jar "C:\Users\DELL User\Desktop\NroffEditJar208Fixed\NroffEdit\NroffEdit.jar"
Mai 22, 2020 10:20:16 PM org.jdesktop.application.Application$1 run
SCHWERWIEGEND: Application class idtools.NroffEditApp failed to launch
java.lang.IllegalArgumentException: setSelectedIndex: 12 out of bounds (*)
at javax.swing.JComboBox.setSelectedIndex(Unknown Source)
at idtools.NroffEditView.getDateTime(NroffEditView.java:899)
at idtools.NroffEditView.<init>(NroffEditView.java:281)
at idtools.NroffEditApp.startup(NroffEditApp.java:20)
at org.jdesktop.application.Application$1.run(Application.java:171)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Exception in thread "AWT-EventQueue-0" java.lang.Error: Application class idtools.NroffEditApp failed to launch
at org.jdesktop.application.Application$1.run(Application.java:177)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: setSelectedIndex: 12 out of bounds (*)
at javax.swing.JComboBox.setSelectedIndex(Unknown Source)
at idtools.NroffEditView.getDateTime(NroffEditView.java:899)
at idtools.NroffEditView.<init>(NroffEditView.java:281)
at idtools.NroffEditApp.startup(NroffEditApp.java:20)
at org.jdesktop.application.Application$1.run(Application.java:171)
... 14 more

(*) "12 out of bounds" in 2020, "13 out of bounds" in 2021, "14 out of bounds" in 2022 etc.

Cause of the problem

In NroffEdit, you see a date-selection "Issue date" which contains a combo box to select the year. By default, the combo box is filled with the years 2008 till 2019.

The current year is automatically selected - and that's the problem: The year 2020 is not available in the list, therefore the application will crash with an "out of bounds" error.

The de-compilation using Recaf shows:

public NroffEditView(SingleFrameApplication app, String[] arguments) {
    ..........

    this.jComboBoxYear.removeAllItems();
    for (i = 2008; i < 2020; ++i) { // HOTFIX: Change to i<2100
        this.jComboBoxYear.addItem(i);
    }
    this.getDateTime(); 

    ..........
}

public void getDateTime() {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date date = new Date();
    int year = Integer.valueOf(dateFormat.format(date).substring(0, 4));
    int month = Integer.valueOf(dateFormat.format(date).substring(5, 7));
    int day = Integer.valueOf(dateFormat.format(date).substring(8, 10));
    if ((year -= 2008) < 0) {
        year = 0;
    }
    if (year > 21) { // HOTFIX: Change to year>91 (2008+91=2099); Original value "21" makes no sense because 2008+21 = 2029, but the combobox was only filled with 2008-2019
        year = 21;   // HOTFIX: Change to year=91 (2008+91=2099)
    }
    this.jComboBoxYear.setSelectedIndex(year); // Program crashes here with "out of bounds" Exception
    this.jComboBoxMonth.setSelectedIndex(--month);
    this.setDayComboBox();
    this.jComboBoxDay.setSelectedIndex(--day);
}

Patch by Daniel Marschall

The simple patch fills the combobox with years 2008 till 2099 and removes the capping to 2029 in the auto-selection.

Download the patched JAR file here:

Manual patch:

  1. Open NrOffEdit.jar with WinRAR
  2. Navigate to directory "idtools"
  3. Extract file "NroffEditView.class"
  4. Open NroffEditView.class file with an hex editor (e.g. HxD) and perform following hex sequence replacements:
  5. Add the modified file back into the JAR file.
  6. The JAR file can now be executed again

Better patch

A better patch would be filling the combo box from 2008 till "current year + 1"  (or "current year" if you don't want issue dates in the future).

Unfortunately, I don't know how to do such a complex change to the bytecode.

Here would be the theoretical patch of the source code:

public NroffEditView(SingleFrameApplication app, String[] arguments) {
    ..........

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date date = new Date();
    int maxYear = Integer.valueOf(dateFormat.format(date).substring(0, 4)) + 1;

    this.jComboBoxYear.removeAllItems();
    for (i = 2008; i <= maxYear; ++i) {
        this.jComboBoxYear.addItem(i);
    }
    this.getDateTime(); 

    ..........
}

public void getDateTime() {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    Date date = new Date();
    int year = Integer.valueOf(dateFormat.format(date).substring(0, 4));
    int month = Integer.valueOf(dateFormat.format(date).substring(5, 7));
    int day = Integer.valueOf(dateFormat.format(date).substring(8, 10));
    if ((year -= 2008) < 0) {
        year = 0;
    }
    //if (year > 21) {
    //    year = 21;
    //}
    this.jComboBoxYear.setSelectedIndex(year);
    this.jComboBoxMonth.setSelectedIndex(--month);
    this.setDayComboBox();
    this.jComboBoxDay.setSelectedIndex(--day);
}