51
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

APFSで再燃したNFD問題

Last updated at Posted at 2017-03-29

iOS 10.3 でAPFSが本番投入されました。それでiPhoneやiPadが文鎮化するなどの深刻な問題はみられなかったものの、やはり無問題とはいかなかったようで。

原因を調べてみました。

nfdtest.pl
#!/usr/bin/env perl
use strict;
use warnings;
use feature ':all';
use Encode;
use Unicode::Normalize;
use utf8;
binmode STDOUT, ':utf8';

sub listdir {
    my $dn = shift;
    opendir my $dh, $dn or die "$dn: $!";
    my @fn = map { decode_utf8($_) } readdir $dh;
    closedir $dh;
    map { encode( 'ascii', $_, Encode::FB_PERLQQ ) } @fn;
}

my $dir = shift or die "usage: $0 dirname";
my $fn     = 'かばん.txt';
my $fn_nfd = NFD($fn);
say 'fn     =', encode( 'ascii', $fn,     Encode::FB_PERLQQ );
say 'fn_nfd =', encode( 'ascii', $fn_nfd, Encode::FB_PERLQQ );
eval {
    my $path = "$dir/$fn";
    open my $fh, '>:utf8', $path or die "$path:$!";
    say $fh "食べないでくださーい";
    close $fh;
};
say $@ if $@;
eval {
    my $path = "$dir/$fn_nfd";
    open my $fh, '<:utf8', "$dir/$fn_nfd" or die "$fn:$!";
    say <$fh>;
    close $fh;
};
say $@ if $@;
{
    say for listdir($dir);
    unlink "$dir/$fn";
}

上記のscriptを macOS Sierra v10.2.4 で実行した場合、HFS+では

HFS+
fn     =\x{304b}\x{3070}\x{3093}.txt
fn_nfd =\x{304b}\x{306f}\x{3099}\x{3093}.txt
食べないでくださーい

.
..
\x{304b}\x{306f}\x{3099}\x{3093}.txt

となりますが、APFSでは

APFS
fn     =\x{304b}\x{3070}\x{3093}.txt
fn_nfd =\x{304b}\x{306f}\x{3099}\x{3093}.txt
かばん.txt:No such file or directory at ./test.pl line 32.

.
..
\x{304b}\x{3070}\x{3093}.txt

となります。かばん.txtというファイルは:

  • HFS+
    • '\x{304b}\x{3070}\x{3093}.txt'でも'\x{304b}\x{306f}\x{3099}\x{3093} .txt'でも読み書きできる
    • 正式名称は\x{304b}\x{306f}\x{3099}\x{3093}.txt
  • APFS
    • '\x{304b}\x{3070}\x{3093}.txt'のみ読み書きできる
    • 正式名称は\x{304b}\x{3070}\x{3093}.txt

余談ですが、

  • ZFS + normalization=FormD
    • 双方読み書きできる
    • 正式名称は\x{304b}\x{3070}\x{3093}.txt

でした。

より深刻なのは後者の、正式名称がNFD分解されるかいなかでしょう。HFS+では分解された方(decomposed)が正式名称ですが、APFS(というよりHFS+以外)は逆です。

ご覧の通り、HFS+の方はどちらのファイル名でもアクセスできるので、常に分解されていない方(composed)を用いればよいだけの話ではあるのですが…

Dan the Man with too Many Filesystems to Support

51
36
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
51
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?