From owner-svn-src-all@freebsd.org Mon Dec 23 02:41:14 2019 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 948C21E26B5; Mon, 23 Dec 2019 02:41:14 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47h3WZ3TvSz460x; Mon, 23 Dec 2019 02:41:14 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 72E6D9210; Mon, 23 Dec 2019 02:41:14 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id xBN2fEcC092406; Mon, 23 Dec 2019 02:41:14 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id xBN2fDte091985; Mon, 23 Dec 2019 02:41:13 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201912230241.xBN2fDte091985@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Mon, 23 Dec 2019 02:41:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356032 - head/usr.sbin/fstyp X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: head/usr.sbin/fstyp X-SVN-Commit-Revision: 356032 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Dec 2019 02:41:14 -0000 Author: cem Date: Mon Dec 23 02:41:13 2019 New Revision: 356032 URL: https://svnweb.freebsd.org/changeset/base/356032 Log: fstyp(8): Use iconv(3) to convert NTFS vol labels correctly Rather than hackily extracting only the ASCII subset of UTF-16LE, go ahead and convert the label to the user's locale correctly. Modified: head/usr.sbin/fstyp/fstyp.c head/usr.sbin/fstyp/fstyp.h head/usr.sbin/fstyp/ntfs.c Modified: head/usr.sbin/fstyp/fstyp.c ============================================================================== --- head/usr.sbin/fstyp/fstyp.c Sun Dec 22 22:33:22 2019 (r356031) +++ head/usr.sbin/fstyp/fstyp.c Mon Dec 23 02:41:13 2019 (r356032) @@ -67,7 +67,7 @@ static struct { { "ext2fs", &fstyp_ext2fs, false, NULL }, { "geli", &fstyp_geli, true, NULL }, { "msdosfs", &fstyp_msdosfs, false, NULL }, - { "ntfs", &fstyp_ntfs, false, NULL }, + { "ntfs", &fstyp_ntfs, false, NTFS_ENC }, { "ufs", &fstyp_ufs, false, NULL }, #ifdef HAVE_ZFS { "zfs", &fstyp_zfs, true, NULL }, Modified: head/usr.sbin/fstyp/fstyp.h ============================================================================== --- head/usr.sbin/fstyp/fstyp.h Sun Dec 22 22:33:22 2019 (r356031) +++ head/usr.sbin/fstyp/fstyp.h Mon Dec 23 02:41:13 2019 (r356032) @@ -38,6 +38,11 @@ /* The spec doesn't seem to permit UTF-16 surrogates; definitely LE. */ #define EXFAT_ENC "UCS-2LE" +/* + * NTFS itself is agnostic to encoding; it just stores 255 u16 wchars. In + * practice, UTF-16 seems expected for NTFS. (Maybe also for exFAT.) + */ +#define NTFS_ENC "UTF-16LE" extern bool show_label; /* -l flag */ Modified: head/usr.sbin/fstyp/ntfs.c ============================================================================== --- head/usr.sbin/fstyp/ntfs.c Sun Dec 22 22:33:22 2019 (r356031) +++ head/usr.sbin/fstyp/ntfs.c Mon Dec 23 02:41:13 2019 (r356032) @@ -31,6 +31,8 @@ #include __FBSDID("$FreeBSD$"); +#include +#include #include #include #include @@ -92,6 +94,38 @@ struct ntfs_bootfile { uint32_t bf_volsn; } __packed; +static void +convert_label(const void *label /* LE */, size_t labellen, char *label_out, + size_t label_sz) +{ + char *label_out_orig; + iconv_t cd; + size_t rc; + + /* dstname="" means convert to the current locale. */ + cd = iconv_open("", NTFS_ENC); + if (cd == (iconv_t)-1) { + warn("ntfs: Could not open iconv"); + return; + } + + label_out_orig = label_out; + + rc = iconv(cd, __DECONST(char **, &label), &labellen, &label_out, + &label_sz); + if (rc == (size_t)-1) { + warn("ntfs: iconv()"); + *label_out_orig = '\0'; + } else { + /* NUL-terminate result (iconv advances label_out). */ + if (label_sz == 0) + label_out--; + *label_out = '\0'; + } + + iconv_close(cd); +} + int fstyp_ntfs(FILE *fp, char *label, size_t size) { @@ -101,14 +135,15 @@ fstyp_ntfs(FILE *fp, char *label, size_t size) off_t voloff; char *filerecp, *ap; int8_t mftrecsz; - char vnchar; - int recsize, j; + int recsize; filerecp = NULL; bf = (struct ntfs_bootfile *)read_buf(fp, 0, 512); if (bf == NULL || strncmp(bf->bf_sysid, "NTFS ", 8) != 0) goto fail; + if (!show_label) + goto ok; mftrecsz = bf->bf_mftrecsz; recsize = (mftrecsz > 0) ? (mftrecsz * bf->bf_bps * bf->bf_spc) : (1 << -mftrecsz); @@ -127,29 +162,15 @@ fstyp_ntfs(FILE *fp, char *label, size_t size) for (ap = filerecp + fr->fr_attroff; atr = (struct ntfs_attr *)ap, (int)atr->a_type != -1; ap += atr->reclen) { - if (atr->a_type == NTFS_A_VOLUMENAME) { - if(atr->a_datalen >= size *2){ - goto fail; - } - /* - *UNICODE to ASCII. - * Should we need to use iconv(9)? - */ - for (j = 0; j < atr->a_datalen; j++) { - vnchar = *(ap + atr->a_dataoff + j); - if (j & 1) { - if (vnchar) { - goto fail; - } - } else { - label[j / 2] = vnchar; - } - } - label[j / 2] = 0; - break; - } + if (atr->a_type != NTFS_A_VOLUMENAME) + continue; + + convert_label(ap + atr->a_dataoff, + atr->a_datalen, label, size); + break; } +ok: free(bf); free(filerecp);