Modify ↓

Opened 2 hours ago

Last modified 106 minutes ago

#24940 new enhancement

[PATCH] Fall back to a UTF-8 locale on Linux, and explain unmappable file names instead of asking for a bug report

Reported by: wangi Owned by: team
Priority: normal Milestone:
Component: Core Version:
Keywords: linux locale encoding InvalidPathException flatpak template_report Cc:

Description

This follows up #14596, which is closed as invalid but still collects duplicates: more than 30 so far, and it was updated again this week. All of them are java.nio.file.InvalidPathException: Malformed input or input contains unmappable characters, thrown by the file chooser when a folder holds a file with a non-ASCII name.

What steps will reproduce the problem?

  1. On Linux, start JOSM with a UTF-8 locale which is not installed, e.g. LANG=fr_FR.UTF-8 on a system that has only en_US.UTF-8 — which is what happens inside a Flatpak sandbox — or with LANG=C.
  2. File > Open, and go to a folder which holds a file called Capture d'écran.png.

What is the expected result?

The folder is listed.

What happens instead?

InvalidPathException, and JOSM asks for a bug report.

Please provide any additional information below. Attach a screenshot if possible.

The reasoning in #14596 is that the user chose LANG=C. That doesn't match most of the duplicates: since the status report gained the encodings (#14596 comment:41), many show LANG=en_GB.UTF-8 next to sun.jnu.encoding=ANSI_X3.4-1968. That is a UTF-8 locale which is not installed: glibc falls back to C, and Java then decodes every file name as ASCII. Measured with OpenJDK 25:

Environment sun.jnu.encoding non-ASCII file name
LANG=en_GB.UTF-8 (installed) UTF-8 OK
LANG=C ANSI_X3.4-1968 InvalidPathException
LANG=fr_FR.UTF-8 (not installed) ANSI_X3.4-1968 InvalidPathException
LANG=C -Dsun.jnu.encoding=UTF-8 ANSI_X3.4-1968 InvalidPathException
LANG=C -Dfile.encoding=UTF-8 ANSI_X3.4-1968 InvalidPathException
LANG=C.UTF-8 UTF-8 OK
LANG=fr_FR.UTF-8 LC_CTYPE=C.UTF-8 ANSI_X3.4-1968 InvalidPathException
LANG=fr_FR.UTF-8 LC_ALL=C.UTF-8 UTF-8 OK

So JOSM cannot fix this once Java is running: sun.jnu.encoding is fixed at startup, and setting it with -D is ignored (the suggestion in #14596 comment:40 does not work); file.encoding is not used for file names at all. It has to be fixed in the environment before Java starts — which, as #14596 comment:74 says, depends on the installer. Note also the second-to-last row: setting only LC_CTYPE is not enough, because setlocale(LC_ALL, "") fails as a whole when any category names a locale which is not installed.

The attached patches are independent of each other.

utf8-file-names-launcher.patch — the installer part. The Linux launchers native/linux/{tested,latest}/usr/bin/josm* set LC_ALL=C.UTF-8 when the locale cannot be set or is ASCII, provided C.UTF-8 is available (it is built into glibc 2.35 and later):

if { [ -n "$(locale 2>&1 >/dev/null)" ] || [ "$(locale charmap 2>/dev/null)" = "ANSI_X3.4-1968" ]; } \
        && [ -z "$(LC_ALL=C.UTF-8 locale 2>&1 >/dev/null)" ]; then
    export LC_ALL=C.UTF-8
fi
  • This reaches Flatpak users as well: the Flathub package runs this script (its only patch adds HiDPI scaling).
  • It does not change the language of JOSM. When the locale cannot be set, Java already falls back to English.
  • Locales which work are left alone, including non-UTF-8 ones such as ISO-8859-1, where sun.jnu.encoding is legitimately not UTF-8. If locale is missing, or C.UTF-8 is not available, the check does nothing.
  • Tested by running both scripts, with a stand-in for java that lists such a folder, under LANG=C, a missing LANG, a missing LANG with a valid LC_CTYPE, and a working locale. All four list the folder; the unmodified script fails with the missing LANG. shellcheck 0.11.0 reports nothing new: its only finding, SC1091 about the sourced /etc/default/josm, is the same on the unmodified scripts.
  • One thing I could not check: whether /usr/bin/locale is present in the Freedesktop runtime. If it is not, the check does nothing there.

utf8-file-names-dialog.patch — for the ways of starting JOSM whose launcher JOSM does not control: Snap (#22887), Java Web Start and plain java -jar. A JNLP file can set system properties but not environment variables, so Web Start cannot be fixed from josm.jnlp. New ReportedException.isUnmappableFileName() recognises such an InvalidPathException in the cause chain while sun.jnu.encoding is not UTF-8, and BugReportDialog.showFor() then explains the problem instead of asking for a bug report, as it already does for an OutOfMemoryError:

JOSM cannot handle the name of a file, because it is running with the character set ANSI_X3.4-1968
for file names, which cannot represent it.
This happens when JOSM is started without a UTF-8 locale, for example with LANG=C, or with a locale
which is not installed.

Please start JOSM with the environment variable LC_ALL=C.UTF-8.

It is shown once per session, since browsing another folder throws the same exception again. Requiring sun.jnu.encoding not to be UTF-8 keeps it from blaming the locale when it is not at fault, e.g. for a file name in ISO-8859-1 on a UTF-8 system.

Unit tests: ReportedExceptionTest.testIsUnmappableFileName() covers the exception on its own and as a cause, another InvalidPathException, an unrelated exception, and a UTF-8 file name encoding. New BugReportDialogTest checks that the message is shown, exactly once, and that no bug report dialog is opened. Both fail without the patch. All tests in org.openstreetmap.josm.tools.bugreport and org.openstreetmap.josm.gui.bugreport pass, and checkstyle and PMD report nothing for the changed files. Both patches are against r19636.

Attachments (2)

utf8-file-names-launcher.patch​ (2.8 KB ) - added by wangi 2 hours ago.
utf8-file-names-dialog.patch​ (10.2 KB ) - added by wangi 2 hours ago.

Download all attachments as: .zip

Change History (3)

by wangi, 2 hours ago

by wangi, 2 hours ago

comment:1 by wangi, 108 minutes ago

Also suggested the shell script change on the snap #22887 ticket.

Last edited 106 minutes ago by wangi (previous) (diff)

Modify Ticket

Change Properties
Set your email in Preferences
Action
as new The owner will remain team.
as The resolution will be set. Next status will be 'closed'.
to The owner will be changed from team to the specified user.
Next status will be 'needinfo'. The owner will be changed from team to wangi.
as duplicate The resolution will be set to duplicate. Next status will be 'closed'. The specified ticket will be cross-referenced with this ticket.
The owner will be changed from team to anonymous. Next status will be 'assigned'.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.