All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Vladimir 'φ-coder/phcoder' Serbinenko" <phcoder@gmail.com>
To: Anton Altaparmakov <anton@tuxera.com>,
	linux-ntfs-dev@lists.sourceforge.net,
	linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH 7/8] Support non-BMP characters in NTFS.
Date: Wed, 16 May 2012 01:13:16 +0200	[thread overview]
Message-ID: <4FB2E30C.4010304@gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3183 bytes --]

ntfs-3g supports non-BMP characters just fine. This patch make standard read-only driver work as well.
Patch is bigger than required since checkpatch.pl asked me to restructure the code to avoid overlong lines.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
---
 fs/ntfs/unistr.c |   70 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 41 insertions(+), 29 deletions(-)

diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c
index 0d371e7..79f82d2 100644
--- a/fs/ntfs/unistr.c
+++ b/fs/ntfs/unistr.c
@@ -265,33 +265,35 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins,
 	int i, o, wc_len;
 
 	/* We do not trust outside sources. */
-	if (likely(ins)) {
-		ucs = kmem_cache_alloc(ntfs_name_cache, GFP_NOFS);
-		if (likely(ucs)) {
-			for (i = o = 0; i < ins_len; i += wc_len) {
-				wc_len = nls->char2uni(ins + i, ins_len - i,
-						&wc);
-				if (likely(wc_len >= 0 && wc <= 0xffff
-					   && o < NTFS_MAX_NAME_LEN)) {
-					if (likely(wc)) {
-						ucs[o++] = cpu_to_le16(wc);
-						continue;
-					} /* else if (!wc) */
-					break;
-				} /* else if (wc_len < 0 ||
-						o >= NTFS_MAX_NAME_LEN) */
-				goto name_err;
-			}
-			ucs[o] = 0;
-			*outs = ucs;
-			return o;
-		} /* else if (!ucs) */
-		ntfs_error(vol->sb, "Failed to allocate buffer for converted "
-				"name from ntfs_name_cache.");
+	if (unlikely(!ins)) {
+		ntfs_error(vol->sb, "Received NULL pointer.");
+		return -EINVAL;
+	}
+
+	ucs = kmem_cache_alloc(ntfs_name_cache, GFP_NOFS);
+	if (unlikely(!ucs)) {
+		ntfs_error(vol->sb,
+			   "Failed to allocate buffer for converted "
+			   "name from ntfs_name_cache.");
 		return -ENOMEM;
-	} /* else if (!ins) */
-	ntfs_error(vol->sb, "Received NULL pointer.");
-	return -EINVAL;
+	}
+
+	for (i = o = 0; i < ins_len; i += wc_len) {
+		int s;
+		wc_len = nls->char2uni(ins + i, ins_len - i, &wc);
+		if (unlikely(wc_len < 0 || o >= NTFS_MAX_NAME_LEN))
+			goto name_err;
+		if (unlikely(!wc))
+			break;
+		s = unicode_to_utf16s(wc, UTF16_LITTLE_ENDIAN, ucs + o,
+				      NTFS_MAX_NAME_LEN - o);
+		if (s <= 0)
+			break;
+		o += s;
+	}
+	ucs[o] = 0;
+	*outs = ucs;
+	return o;
 name_err:
 	kmem_cache_free(ntfs_name_cache, ucs);
 	if (wc_len < 0) {
@@ -342,6 +344,7 @@ int ntfs_ucstonls(const ntfs_volume *vol, const ntfschar *ins,
 
 	/* We don't trust outside sources. */
 	if (ins) {
+		int step;
 		ns = *outs;
 		ns_len = outs_len;
 		if (ns && !ns_len) {
@@ -354,9 +357,18 @@ int ntfs_ucstonls(const ntfs_volume *vol, const ntfschar *ins,
 			if (!ns)
 				goto mem_err_out;
 		}
-		for (i = o = 0; i < ins_len; i++) {
-retry:			wc = nls->uni2char(le16_to_cpu(ins[i]), ns + o,
-					ns_len - o);
+		for (i = o = 0; i < ins_len; i += step) {
+			unicode_t uni;
+retry:
+			step = utf16s_to_unicode(ins + i, ins_len - i,
+						 UTF16_LITTLE_ENDIAN,
+						 &uni);
+			if (step <= 0) {
+				uni = le16_to_cpu(ins[i]);
+				step = 1;
+			}
+
+			wc = nls->uni2char(uni, ns + o, ns_len - o);
 			if (wc > 0) {
 				o += wc;
 				continue;
-- 
1.7.10

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

                 reply	other threads:[~2012-05-15 23:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4FB2E30C.4010304@gmail.com \
    --to=phcoder@gmail.com \
    --cc=anton@tuxera.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-ntfs-dev@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.