Hi,
(I'm not subscribed to the list -- please cc me on reply)
I'm updating the ntfs-3g package in openSUSE, and I see that we have two
patches here. I have absolutely no idea if they have been sent upstream
and/or if they're okay. I'd appreciate if someone could take a few
minutes to give an opinion about this.
The first one is ntfs-3g-warnings.patch and should be relatively safe.
It just makes sure that ntfs-3g can be compiled "-Wformat
-Wformat-security -W -Wno-sign-compare -Werror". My guess is that we
compile it this way for extra security. Some changes, like the
fprintf() ones, are indeed good practice.
The second one is ntfs-3g-utf8-fallback.patch. There's a header
explaining the goal of the patch.
Thanks,
Vincent
--
Les gens heureux ne sont pas pressés.
fusermount.c: In function 'mount_fuse':
fusermount.c:657: warning: ignoring return value of 'fchdir', declared with attribute warn_unused_result
# Checked with author of ntfs-3g: Currently it's best to ignore the return value (for now, not critical)
Index: libfuse-lite/fusermount.c
===================================================================
--- libfuse-lite/fusermount.c.orig
+++ libfuse-lite/fusermount.c
@@ -588,6 +588,7 @@ static int mount_fuse(const char *mnt, c
&source, &mnt_opts);
if (currdir_fd != -1) {
+ __attribute__((unused))int ignored_fchdir_status =
fchdir(currdir_fd);
close(currdir_fd);
}
Index: include/ntfs-3g/logging.h
===================================================================
--- include/ntfs-3g/logging.h.orig
+++ include/ntfs-3g/logging.h
@@ -91,23 +91,23 @@ int ntfs_log_redirect(const char *functi
/* Macros to simplify logging. One for each level defined above.
* Note, ntfs_log_debug/trace have effect only if DEBUG is defined.
*/
-#define ntfs_log_critical(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_CRITICAL,NULL,FORMAT,##ARGS)
-#define ntfs_log_error(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ERROR,NULL,FORMAT,##ARGS)
-#define ntfs_log_info(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_INFO,NULL,FORMAT,##ARGS)
-#define ntfs_log_perror(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PERROR,NULL,FORMAT,##ARGS)
-#define ntfs_log_progress(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PROGRESS,NULL,FORMAT,##ARGS)
-#define ntfs_log_quiet(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_QUIET,NULL,FORMAT,##ARGS)
-#define ntfs_log_verbose(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_VERBOSE,NULL,FORMAT,##ARGS)
-#define ntfs_log_warning(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_WARNING,NULL,FORMAT,##ARGS)
+#define ntfs_log_critical(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_CRITICAL,NULL,FORMAT,##ARGS)
+#define ntfs_log_error(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ERROR,NULL,FORMAT,##ARGS)
+#define ntfs_log_info(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_INFO,NULL,FORMAT,##ARGS)
+#define ntfs_log_perror(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PERROR,NULL,FORMAT,##ARGS)
+#define ntfs_log_progress(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_PROGRESS,NULL,FORMAT,##ARGS)
+#define ntfs_log_quiet(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_QUIET,NULL,FORMAT,##ARGS)
+#define ntfs_log_verbose(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_VERBOSE,NULL,FORMAT,##ARGS)
+#define ntfs_log_warning(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_WARNING,NULL,FORMAT,##ARGS)
/* By default debug and trace messages are compiled into the program,
* but not displayed.
*/
#ifdef DEBUG
-#define ntfs_log_debug(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_DEBUG,NULL,FORMAT,##ARGS)
-#define ntfs_log_trace(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_TRACE,NULL,FORMAT,##ARGS)
-#define ntfs_log_enter(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ENTER,NULL,FORMAT,##ARGS)
-#define ntfs_log_leave(FORMAT, ARGS...) ntfs_log_redirect(__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_LEAVE,NULL,FORMAT,##ARGS)
+#define ntfs_log_debug(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_DEBUG,NULL,FORMAT,##ARGS)
+#define ntfs_log_trace(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_TRACE,NULL,FORMAT,##ARGS)
+#define ntfs_log_enter(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_ENTER,NULL,FORMAT,##ARGS)
+#define ntfs_log_leave(FORMAT, ARGS...) ntfs_log_redirect((const char *)__FUNCTION__,__FILE__,__LINE__,NTFS_LOG_LEVEL_LEAVE,NULL,FORMAT,##ARGS)
#else
#define ntfs_log_debug(FORMAT, ARGS...)do {} while (0)
#define ntfs_log_trace(FORMAT, ARGS...)do {} while (0)
Index: libntfs-3g/unistr.c
===================================================================
--- libntfs-3g/unistr.c.orig
+++ libntfs-3g/unistr.c
@@ -531,7 +531,7 @@ int ntfs_mbstoucs(const char *ins, ntfsc
s = ins;
#if defined(HAVE_MBSINIT)
memset(&mbstate, 0, sizeof(mbstate));
- ins_len = mbsrtowcs(NULL, (const char **)&s, 0, &mbstate);
+ ins_len = mbsrtowcs(NULL, (__const char **)&s, 0, &mbstate);
#ifdef __CYGWIN32__
if (!ins_len && *ins) {
/* Older Cygwin had broken mbsrtowcs() implementation. */
Index: libntfs-3g/logging.c
===================================================================
--- libntfs-3g/logging.c.orig
+++ libntfs-3g/logging.c
@@ -472,7 +472,7 @@ int ntfs_log_handler_fprintf(const char
ret += fprintf(stream, " ");
#endif
if (col_prefix)
- ret += fprintf(stream, col_prefix);
+ ret += fprintf(stream, "%s", col_prefix);
if ((ntfs_log.flags & NTFS_LOG_FLAG_ONLYNAME) &&
(strchr(file, PATH_SEP))) /* Abbreviate the filename */
@@ -497,7 +497,7 @@ int ntfs_log_handler_fprintf(const char
ret += fprintf(stream, ": %s\n", strerror(olderr));
if (col_suffix)
- ret += fprintf(stream, col_suffix);
+ ret += fprintf(stream, "%s", col_suffix);
#ifdef DEBUG
if (level == NTFS_LOG_LEVEL_ENTER)
Index: src/ntfs-3g.c
===================================================================
--- src/ntfs-3g.c.orig
+++ src/ntfs-3g.c
@@ -2014,7 +2014,7 @@ static void mknod_dev_fuse(const char *d
if (mknod(dev, S_IFCHR | 0666, makedev(10, 229))) {
ntfs_log_perror("Failed to create '%s'", dev);
if (errno == EPERM)
- ntfs_log_error(dev_fuse_msg);
+ ntfs_log_error("%s", dev_fuse_msg);
}
umask(mask);
}
@@ -2291,7 +2291,7 @@ int main(int argc, char *argv[])
#if defined(linux) || defined(__uClinux__)
if (S_ISBLK(sbuf.st_mode) && (fstype == FSTYPE_FUSE))
- ntfs_log_info(fuse26_kmod_msg);
+ ntfs_log_info("%s", fuse26_kmod_msg);
#endif
setup_logging(parsed_options);
Index: src/utils.c
===================================================================
--- src/utils.c.orig
+++ src/utils.c
@@ -133,7 +133,7 @@ void utils_mount_error(const char *volum
ntfs_log_error(hibernated_volume_msg, volume, mntpoint);
break;
case NTFS_VOLUME_UNCLEAN_UNMOUNT:
- ntfs_log_error(unclean_journal_msg);
+ ntfs_log_error("%s", unclean_journal_msg);
ntfs_log_error(forced_mount_msg, volume, mntpoint,
volume, mntpoint);
break;
Index: libntfs-3g/device.c
===================================================================
--- libntfs-3g/device.c.orig
+++ libntfs-3g/device.c
@@ -410,7 +410,7 @@ s64 ntfs_cluster_read(const ntfs_volume
errno = ESPIPE;
ntfs_log_perror("Trying to read outside of volume "
"(%lld < %lld)", (long long)vol->nr_clusters,
- (long long)lcn + count);
+ (long long)(lcn + count));
return -1;
}
br = ntfs_pread(vol->dev, lcn << vol->cluster_size_bits,
@@ -446,7 +446,7 @@ s64 ntfs_cluster_write(const ntfs_volume
errno = ESPIPE;
ntfs_log_perror("Trying to write outside of volume "
"(%lld < %lld)", (long long)vol->nr_clusters,
- (long long)lcn + count);
+ (long long)(lcn + count));
return -1;
}
if (!NVolReadOnly(vol))
Index: libntfs-3g/mft.c
===================================================================
--- libntfs-3g/mft.c.orig
+++ libntfs-3g/mft.c
@@ -95,7 +95,7 @@ int ntfs_mft_records_read(const ntfs_vol
vol->mft_record_size_bits) {
errno = ESPIPE;
ntfs_log_perror("Trying to read non-allocated mft records "
- "(%lld > %lld)", (long long)m + count,
+ "(%lld > %lld)", (long long)(m + count),
(long long)vol->mft_na->initialized_size >>
vol->mft_record_size_bits);
return -1;
@@ -157,7 +157,7 @@ int ntfs_mft_records_write(const ntfs_vo
vol->mft_record_size_bits) {
errno = ESPIPE;
ntfs_log_perror("Trying to write non-allocated mft records "
- "(%lld > %lld)", (long long)m + count,
+ "(%lld > %lld)", (long long)(m + count),
(long long)vol->mft_na->initialized_size >>
vol->mft_record_size_bits);
return -1;
@@ -612,7 +612,7 @@ leave:
return ret;
}
-int ntfs_mft_attr_extend(ntfs_volume *vol, ntfs_attr *na)
+int ntfs_mft_attr_extend(__attribute__((unused)) ntfs_volume *vol, ntfs_attr *na)
{
int ret = STATUS_ERROR;
ntfs_log_enter("Entering\n");
@@ -1498,7 +1498,7 @@ undo_mftbmp_alloc:
err_out:
if (!errno)
errno = EIO;
-err_exit:
+/*err_exit:*/
ni = NULL;
goto out;
}
- [EMAIL PROTECTED]:
#
# NTFS uses Unicode (UTF-16LE [NTFS-3G uses UCS-2LE, which is enough
# for now]) for path names, but the Unicode code points need to be
# converted before a path can be accessed under NTFS. For 7 bit ASCII/ANSI,
# glibc does this even without a locale in a hard-coded fashion as that
# appears to be is easy because the low 7-bit ASCII range appears to be
# available # in all charsets but it does not convert anything if
# there was some error with the locale setup or none set up like
# when mount is called during early boot where he (by policy) do
# not use locales (and may be not available if /usr is not yet mounted),
# so this patch fixes the resulting issues for systems which use
# UTF-8 and for others, specifying the locale in fstab brings them
# the encoding which they want.
#
# If no locale is defined or there was a problem with setting one
# up and whenever nl_langinfo(CODESET) returns a sting starting with
# "ANSI", use an internal UCS-2LE <-> UTF-8 codeset converter to fix
# the bug where NTFS-3G does not show any path names which include
# international characters!!! (and also fails on creating them) as result.
#
# Author: Bernhard Kaindl <[EMAIL PROTECTED]>
#
--- include/ntfs-3g/unistr.h
+++ include/ntfs-3g/unistr.h
@@ -26,6 +26,8 @@
#include "types.h"
#include "layout.h"
+extern int use_utf8;
+
extern BOOL ntfs_names_are_equal(const ntfschar *s1, size_t s1_len,
const ntfschar *s2, size_t s2_len, const IGNORE_CASE_BOOL ic,
const ntfschar *upcase, const u32 upcase_size);
--- libntfs-3g/unistr.c
+++ libntfs-3g/unistr.c
@@ -47,6 +47,8 @@
#include "logging.h"
#include "misc.h"
+int use_utf8;
+
/*
* IMPORTANT
* =========
@@ -373,6 +375,85 @@ int ntfs_file_values_compare(const FILE_
err_val, ic, upcase, upcase_len);
}
+/* Return the amount of 16-bit elements in UTF-16LE needed (without
+ * the terminating null to store given UTF-8 string and -1 if it does
+ * noy fit into PATH_MAX
+ * TODO: Extend this with a function to suppport UTF-16LE.
+*/
+static int ucs2_to_utf8_size(const ntfschar *ins, const int ins_len, int outs_len)
+{
+ int i;
+ int count = 0;
+
+ for (i = 0; i < ins_len && ins[i]; i++) {
+ unsigned short c = le16_to_cpu(ins[i]);
+ if (c < 0x80)
+ count++;
+ else
+ count += (c & 0xf800) ? 3 : 2;
+ if (count > outs_len)
+ goto fail;
+ }
+ return count;
+fail:
+ return -1;
+}
+
+/*
+ * ntfs_ucs_to_utf8 - convert a little endian Unicode string to an UTF-8 string
+ * @ins: input Unicode string buffer
+ * @ins_len: length of input string in Unicode characters
+ * @outs: on return contains the (allocated) output multibyte string
+ * @outs_len: length of output buffer in bytes
+ * TODO: Replace this with a function which converts from UTF-16LE because
+ * NTFS uses UTF-16LE. UTF-16 supports more rare/unusual characters than UCS-2
+ */
+int ntfs_ucs_to_utf8(const ntfschar *ins, const int ins_len, char **outs, int outs_len)
+{
+ char *t, *end;
+ int i, size;
+
+ if (!*outs)
+ outs_len = PATH_MAX;
+
+ size = ucs2_to_utf8_size(ins, ins_len, outs_len);
+
+ if (size < 0) {
+ errno = ENAMETOOLONG;
+ goto fail;
+ }
+ if (!*outs)
+ *outs = ntfs_malloc((outs_len = size + 1));
+
+ t = *outs;
+ end = t + outs_len;
+
+ for (i = 0; i < ins_len && ins[i]; i++) {
+ unsigned short c = le16_to_cpu(ins[i]);
+ if (c < 0x80) {
+ *t++ = c;
+ if (t == end)
+ goto fail;
+ } else {
+ if (c & 0xf800) {
+ if (t+3 >= end)
+ goto fail;
+ *t++ = 0xe0 | (c >> 12);
+ *t++ = 0x80 | ((c >> 6) & 0x3f);
+ } else {
+ if (t+2 >= end)
+ goto fail;
+ *t++ = (0xc0 | ((c >> 6) & 0x3f));
+ }
+ *t++ = 0x80 | (c & 0x3f);
+ }
+ }
+ *t = '\0';
+ return t - *outs;
+fail:
+ return -1;
+}
+
/**
* ntfs_ucstombs - convert a little endian Unicode string to a multibyte string
* @ins: input Unicode string buffer
@@ -397,6 +478,8 @@ int ntfs_file_values_compare(const FILE_
* sequence according to the current locale.
* ENAMETOOLONG Destination buffer is too small for input string.
* ENOMEM Not enough memory to allocate destination buffer.
+ * TODO: Replace this with a function which converts from UTF-16LE because
+ * NTFS uses UTF-16LE. UTF-16 supports more rare/unusual characters than UCS-2
*/
int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
int outs_len)
@@ -419,12 +502,15 @@ int ntfs_ucstombs(const ntfschar *ins, c
errno = ENAMETOOLONG;
return -1;
}
+ if (use_utf8)
+ return ntfs_ucs_to_utf8(ins, ins_len, outs, outs_len);
if (!mbs) {
mbs_len = (ins_len + 1) * MB_CUR_MAX;
mbs = ntfs_malloc(mbs_len);
if (!mbs)
return -1;
}
+
#ifdef HAVE_MBSINIT
memset(&mbstate, 0, sizeof(mbstate));
#else
@@ -487,6 +573,107 @@ err_out:
return -1;
}
+/* Return the amount of 16-bit elements in UTF-16LE needed (without
+ * the terminating null to store given UTF-8 string and -1 if it does
+ * noy fit into PATH_MAX
+ * TODO: Extend this with a function to suppport UTF-16LE.
+*/
+static int utf8_to_ucs2_size(const char *s)
+{
+ unsigned int byte;
+ size_t count = 0;
+
+ while ((byte = *((unsigned char *)s++))) {
+ if (++count >= PATH_MAX || byte >= 0xF0)
+ goto fail;
+ if (!*s) break;
+ if (byte >= 0xC0) s++;
+ if (!*s) break;
+ if (byte >= 0xE0) s++;
+ }
+ return count;
+fail:
+ return -1;
+}
+/* This converts one UTF-8 sequence to cpu-endian UCS-2
+ * TODO: Replace this with a function which converts to UTF-16LE because
+ * NTFS uses UTF-16LE. UTF-16 supports more rare/unusual characters than UCS-2
+*/
+static int utf8toucs2(wchar_t *wc, const char *s)
+{
+ unsigned int byte = *((unsigned char *)s);
+
+ if (byte == 0) {
+ *wc = (wchar_t) 0;
+ return 0;
+ } else if (byte < 0xC0) {
+ *wc = (wchar_t) byte;
+ return 1;
+ } else if (byte < 0xE0) {
+ if(strlen(s) < 2)
+ goto fail;
+ if ((s[1] & 0xC0) == 0x80) {
+ *wc = (wchar_t) (((byte & 0x1F) << 6) | (s[1] & 0x3F));
+ return 2;
+ } else
+ goto fail;
+ } else if (byte < 0xF0) {
+ if(strlen(s) < 3)
+ goto fail;
+ if (((s[1] & 0xC0) == 0x80) && ((s[2] & 0xC0) == 0x80)) {
+ *wc = (wchar_t) (((byte & 0x0F) << 12)
+ | ((s[1] & 0x3F) << 6) | (s[2] & 0x3F));
+ /* Surrogates range */
+ if((*wc >= 0xD800 && *wc <= 0xDFFF) ||
+ (*wc == 0xFFFE || *wc == 0xFFFF))
+ goto fail;
+ return 3;
+ }
+ }
+fail:
+ return -1;
+}
+
+/**
+ * ntfs_utf8_to_ucs - convert a UTF-8 string to a UCS-2LE Unicode string
+ * @ins: input multibyte string buffer
+ * @outs: on return contains the (allocated) output Unicode string
+ * @outs_len: length of output buffer in Unicode characters
+ * TODO: Replace this with a function which converts to UTF-16LE because
+ * NTFS uses UTF-16LE. UTF-16 supports more rare/unusual characters than UCS-2
+ */
+int ntfs_utf8_to_ucs(const char *ins, ntfschar **outs)
+{
+ const char *t = ins;
+ wchar_t wc;
+ ntfschar *outpos;
+ int shorts = utf8_to_ucs2_size(ins);
+
+ if (shorts < 0) {
+ errno = EILSEQ;
+ goto fail;
+ }
+ if (!*outs)
+ *outs = ntfs_malloc((shorts+1) * sizeof(ntfschar));
+
+ outpos = *outs;
+
+ while(1) {
+ int m = utf8toucs2(&wc, t);
+ if (m < 0) {
+ errno = EILSEQ;
+ goto fail;
+ }
+ *outpos++ = cpu_to_le16(wc);
+ if (m == 0)
+ break;
+ t += m;
+ }
+ return --outpos - *outs;
+fail:
+ return -1;
+}
+
/**
* ntfs_mbstoucs - convert a multibyte string to a little endian Unicode string
* @ins: input multibyte string buffer
@@ -509,6 +696,8 @@ err_out:
* string according to the current locale.
* ENAMETOOLONG Destination buffer is too small for input string.
* ENOMEM Not enough memory to allocate destination buffer.
+ * TODO: Replace this with a function which converts to UTF-16LE because
+ * NTFS uses UTF-16LE. UTF-16 supports more rare/unusual characters than UCS-2
*/
int ntfs_mbstoucs(const char *ins, ntfschar **outs)
{
@@ -524,6 +713,8 @@ int ntfs_mbstoucs(const char *ins, ntfsc
errno = EINVAL;
return -1;
}
+ if (use_utf8)
+ return ntfs_utf8_to_ucs(ins, outs);
/* Determine the size of the multi-byte string in bytes. */
ins_size = strlen(ins);
--- src/ntfs-3g.c
+++ src/ntfs-3g.c
@@ -69,6 +69,7 @@
#include <getopt.h>
#include <syslog.h>
#include <sys/wait.h>
+#include <langinfo.h>
#ifdef HAVE_SETXATTR
#include <sys/xattr.h>
@@ -2224,6 +2225,15 @@ static void setup_logging(char *parsed_o
ntfs_log_info("Mount options: %s\n", parsed_options);
}
+void check_codeset() {
+ char *codeset = nl_langinfo(CODESET);
+ if (!codeset || !strncmp(codeset, "ANSI", 4)) {
+ ntfs_log_info("Locale invalid or has ANSI codeset: "
+ "Using UTF-8 for international characters.\n");
+ use_utf8 = 1;
+ }
+}
+
int main(int argc, char *argv[])
{
char *parsed_options = NULL;
@@ -2260,6 +2270,8 @@ int main(int argc, char *argv[])
err = NTFS_VOLUME_SYNTAX_ERROR;
goto err_out;
}
+
+ check_codeset();
#if defined(linux) || defined(__uClinux__)
fstype = get_fuse_fstype();
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
ntfs-3g-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ntfs-3g-devel