Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-exfat: Commit

external/exfat


Commit MetaInfo

Revisiónbbf4594405ceef9defeba24a596b46d26f73b512 (tree)
Tiempo2021-07-06 17:30:40
AutorChih-Wei Huang <cwhuang@linu...>
CommiterChih-Wei Huang

Log Message

Merge branch 'master' of git://github.com/relan/exfat into pie-x86

Cambiar Resumen

Diferencia incremental

--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,56 @@
1+#
2+# .travis.yml (29.02.20)
3+# Travis Contiguous Integration configuration.
4+#
5+# Free exFAT implementation.
6+# Copyright (C) 2010-2020 Andrew Nayenko
7+#
8+# This program is free software; you can redistribute it and/or modify
9+# it under the terms of the GNU General Public License as published by
10+# the Free Software Foundation, either version 2 of the License, or
11+# (at your option) any later version.
12+#
13+# This program is distributed in the hope that it will be useful,
14+# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+# GNU General Public License for more details.
17+#
18+# You should have received a copy of the GNU General Public License along
19+# with this program; if not, write to the Free Software Foundation, Inc.,
20+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21+#
22+
23+---
24+language: c
25+
26+jobs:
27+ include:
28+ - os: linux
29+ dist: bionic
30+ arch: amd64
31+ - os: linux
32+ dist: bionic
33+ arch: ppc64le
34+ - os: linux
35+ dist: bionic
36+ arch: s390x
37+ - os: osx
38+ osx_image: xcode12.2
39+
40+addons:
41+ apt:
42+ packages:
43+ - libfuse-dev
44+ homebrew:
45+ update: true
46+ casks:
47+ - osxfuse
48+
49+script:
50+ - autoreconf --install
51+ - ./configure CFLAGS='-Wall -Wextra'
52+ - make -k
53+ - dd if=/dev/zero of=foo.img bs=1048576 count=1
54+ - mkfs/mkexfatfs -i 12345678 foo.img
55+ - fsck/exfatfsck foo.img
56+ - echo 'f1b3a11f781533f5b69086596be38367d0ebfb77 foo.img' | shasum -c
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -132,6 +132,7 @@ static void fsck(struct exfat* ef, const char* spec, const char* options)
132132 }
133133
134134 exfat_print_info(ef->sb, exfat_count_free_clusters(ef));
135+ exfat_soil_super_block(ef);
135136 dirck(ef, "");
136137 exfat_unmount(ef);
137138
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -98,7 +98,8 @@ static int fuse_exfat_truncate(const char* path, off_t size)
9898 }
9999
100100 static int fuse_exfat_readdir(const char* path, void* buffer,
101- fuse_fill_dir_t filler, off_t offset, struct fuse_file_info* fi)
101+ fuse_fill_dir_t filler, UNUSED off_t offset,
102+ UNUSED struct fuse_file_info* fi)
102103 {
103104 struct exfat_node* parent;
104105 struct exfat_node* node;
@@ -158,7 +159,7 @@ static int fuse_exfat_open(const char* path, struct fuse_file_info* fi)
158159 return 0;
159160 }
160161
161-static int fuse_exfat_create(const char* path, mode_t mode,
162+static int fuse_exfat_create(const char* path, UNUSED mode_t mode,
162163 struct fuse_file_info* fi)
163164 {
164165 struct exfat_node* node;
@@ -176,7 +177,8 @@ static int fuse_exfat_create(const char* path, mode_t mode,
176177 return 0;
177178 }
178179
179-static int fuse_exfat_release(const char* path, struct fuse_file_info* fi)
180+static int fuse_exfat_release(UNUSED const char* path,
181+ struct fuse_file_info* fi)
180182 {
181183 /*
182184 This handler is called by FUSE on close() syscall. If the FUSE
@@ -190,7 +192,7 @@ static int fuse_exfat_release(const char* path, struct fuse_file_info* fi)
190192 return 0; /* FUSE ignores this return value */
191193 }
192194
193-static int fuse_exfat_flush(const char* path, struct fuse_file_info* fi)
195+static int fuse_exfat_flush(UNUSED const char* path, struct fuse_file_info* fi)
194196 {
195197 /*
196198 This handler may be called by FUSE on close() syscall. FUSE also deals
@@ -202,8 +204,8 @@ static int fuse_exfat_flush(const char* path, struct fuse_file_info* fi)
202204 return exfat_flush_node(&ef, get_node(fi));
203205 }
204206
205-static int fuse_exfat_fsync(const char* path, int datasync,
206- struct fuse_file_info *fi)
207+static int fuse_exfat_fsync(UNUSED const char* path, UNUSED int datasync,
208+ UNUSED struct fuse_file_info *fi)
207209 {
208210 int rc;
209211
@@ -217,15 +219,15 @@ static int fuse_exfat_fsync(const char* path, int datasync,
217219 return exfat_fsync(ef.dev);
218220 }
219221
220-static int fuse_exfat_read(const char* path, char* buffer, size_t size,
221- off_t offset, struct fuse_file_info* fi)
222+static int fuse_exfat_read(UNUSED const char* path, char* buffer,
223+ size_t size, off_t offset, struct fuse_file_info* fi)
222224 {
223225 exfat_debug("[%s] %s (%zu bytes)", __func__, path, size);
224226 return exfat_generic_pread(&ef, get_node(fi), buffer, size, offset);
225227 }
226228
227-static int fuse_exfat_write(const char* path, const char* buffer, size_t size,
228- off_t offset, struct fuse_file_info* fi)
229+static int fuse_exfat_write(UNUSED const char* path, const char* buffer,
230+ size_t size, off_t offset, struct fuse_file_info* fi)
229231 {
230232 exfat_debug("[%s] %s (%zu bytes)", __func__, path, size);
231233 return exfat_generic_pwrite(&ef, get_node(fi), buffer, size, offset);
@@ -267,13 +269,14 @@ static int fuse_exfat_rmdir(const char* path)
267269 return exfat_cleanup_node(&ef, node);
268270 }
269271
270-static int fuse_exfat_mknod(const char* path, mode_t mode, dev_t dev)
272+static int fuse_exfat_mknod(const char* path, UNUSED mode_t mode,
273+ UNUSED dev_t dev)
271274 {
272275 exfat_debug("[%s] %s 0%ho", __func__, path, mode);
273276 return exfat_mknod(&ef, path);
274277 }
275278
276-static int fuse_exfat_mkdir(const char* path, mode_t mode)
279+static int fuse_exfat_mkdir(const char* path, UNUSED mode_t mode)
277280 {
278281 exfat_debug("[%s] %s 0%ho", __func__, path, mode);
279282 return exfat_mkdir(&ef, path);
@@ -302,7 +305,7 @@ static int fuse_exfat_utimens(const char* path, const struct timespec tv[2])
302305 return rc;
303306 }
304307
305-static int fuse_exfat_chmod(const char* path, mode_t mode)
308+static int fuse_exfat_chmod(UNUSED const char* path, mode_t mode)
306309 {
307310 const mode_t VALID_MODE_MASK = S_IFREG | S_IFDIR |
308311 S_IRWXU | S_IRWXG | S_IRWXO;
@@ -313,7 +316,7 @@ static int fuse_exfat_chmod(const char* path, mode_t mode)
313316 return 0;
314317 }
315318
316-static int fuse_exfat_chown(const char* path, uid_t uid, gid_t gid)
319+static int fuse_exfat_chown(UNUSED const char* path, uid_t uid, gid_t gid)
317320 {
318321 exfat_debug("[%s] %s %u:%u", __func__, path, uid, gid);
319322 if (uid != ef.uid || gid != ef.gid)
@@ -321,7 +324,7 @@ static int fuse_exfat_chown(const char* path, uid_t uid, gid_t gid)
321324 return 0;
322325 }
323326
324-static int fuse_exfat_statfs(const char* path, struct statvfs* sfs)
327+static int fuse_exfat_statfs(UNUSED const char* path, struct statvfs* sfs)
325328 {
326329 exfat_debug("[%s]", __func__);
327330
@@ -351,10 +354,14 @@ static void* fuse_exfat_init(struct fuse_conn_info* fci)
351354 #ifdef FUSE_CAP_BIG_WRITES
352355 fci->want |= FUSE_CAP_BIG_WRITES;
353356 #endif
357+
358+ /* mark super block as dirty; failure isn't a big deal */
359+ exfat_soil_super_block(&ef);
360+
354361 return NULL;
355362 }
356363
357-static void fuse_exfat_destroy(void* unused)
364+static void fuse_exfat_destroy(UNUSED void* unused)
358365 {
359366 exfat_debug("[%s]", __func__);
360367 exfat_unmount(&ef);
--- a/libexfat/cluster.c
+++ b/libexfat/cluster.c
@@ -122,7 +122,7 @@ static cluster_t find_bit_and_set(bitmap_t* bitmap, size_t start, size_t end)
122122
123123 for (i = start_index; i < end_index; i++)
124124 {
125- if (bitmap[i] == ~((bitmap_t) 0))
125+ if (bitmap[i] == (bitmap_t) ~((bitmap_t) 0))
126126 continue;
127127 start_bitindex = MAX(i * sizeof(bitmap_t) * 8, start);
128128 end_bitindex = MIN((i + 1) * sizeof(bitmap_t) * 8, end);
@@ -280,7 +280,7 @@ static int grow_file(struct exfat* ef, struct exfat_node* node,
280280 shrink_file(ef, node, current + allocated, allocated);
281281 return -ENOSPC;
282282 }
283- if (next != previous - 1 && node->is_contiguous)
283+ if (next != previous + 1 && node->is_contiguous)
284284 {
285285 /* it's a pity, but we are not able to keep the file contiguous
286286 anymore */
--- a/libexfat/compiler.h
+++ b/libexfat/compiler.h
@@ -33,6 +33,7 @@
3333 #define PRINTF __attribute__((format(printf, 1, 2)))
3434 #define NORETURN __attribute__((noreturn))
3535 #define PACKED __attribute__((packed))
36+#define UNUSED __attribute__((unused))
3637 #if __has_extension(c_static_assert)
3738 #define USE_C11_STATIC_ASSERT
3839 #endif
@@ -42,6 +43,7 @@
4243 #define PRINTF __attribute__((format(printf, 1, 2)))
4344 #define NORETURN __attribute__((noreturn))
4445 #define PACKED __attribute__((packed))
46+#define UNUSED __attribute__((unused))
4547 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
4648 #define USE_C11_STATIC_ASSERT
4749 #endif
@@ -51,6 +53,7 @@
5153 #define PRINTF
5254 #define NORETURN
5355 #define PACKED
56+#define UNUSED
5457
5558 #endif
5659
--- a/libexfat/exfat.h
+++ b/libexfat/exfat.h
@@ -201,12 +201,13 @@ le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name,
201201 void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb);
202202 void exfat_print_info(const struct exfat_super_block* sb,
203203 uint32_t free_clusters);
204+bool exfat_match_option(const char* options, const char* option_name);
204205
205-int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
206+int exfat_utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
206207 size_t insize);
207-int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
208+int exfat_utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
208209 size_t insize);
209-size_t utf16_length(const le16_t* str);
210+size_t exfat_utf16_length(const le16_t* str);
210211
211212 struct exfat_node* exfat_get_node(struct exfat_node* node);
212213 void exfat_put_node(struct exfat* ef, struct exfat_node* node);
@@ -225,6 +226,7 @@ void exfat_update_mtime(struct exfat_node* node);
225226 const char* exfat_get_label(struct exfat* ef);
226227 int exfat_set_label(struct exfat* ef, const char* label);
227228
229+int exfat_soil_super_block(const struct exfat* ef);
228230 int exfat_mount(struct exfat* ef, const char* spec, const char* options);
229231 void exfat_unmount(struct exfat* ef);
230232
--- a/libexfat/io.c
+++ b/libexfat/io.c
@@ -373,24 +373,27 @@ ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size,
373373 ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node,
374374 void* buffer, size_t size, off_t offset)
375375 {
376+ uint64_t newsize = offset;
376377 cluster_t cluster;
377378 char* bufp = buffer;
378379 off_t lsize, loffset, remainder;
379380
380- if (offset >= node->size)
381+ if (offset < 0)
382+ return -EINVAL;
383+ if (newsize >= node->size)
381384 return 0;
382385 if (size == 0)
383386 return 0;
384387
385- cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb));
388+ cluster = exfat_advance_cluster(ef, node, newsize / CLUSTER_SIZE(*ef->sb));
386389 if (CLUSTER_INVALID(*ef->sb, cluster))
387390 {
388391 exfat_error("invalid cluster 0x%x while reading", cluster);
389392 return -EIO;
390393 }
391394
392- loffset = offset % CLUSTER_SIZE(*ef->sb);
393- remainder = MIN(size, node->size - offset);
395+ loffset = newsize % CLUSTER_SIZE(*ef->sb);
396+ remainder = MIN(size, node->size - newsize);
394397 while (remainder > 0)
395398 {
396399 if (CLUSTER_INVALID(*ef->sb, cluster))
@@ -412,40 +415,43 @@ ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node,
412415 }
413416 if (!(node->attrib & EXFAT_ATTRIB_DIR) && !ef->ro && !ef->noatime)
414417 exfat_update_atime(node);
415- return MIN(size, node->size - offset) - remainder;
418+ return MIN(size, node->size - newsize) - remainder;
416419 }
417420
418421 ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node,
419422 const void* buffer, size_t size, off_t offset)
420423 {
424+ uint64_t newsize = offset;
421425 int rc;
422426 cluster_t cluster;
423427 const char* bufp = buffer;
424428 off_t lsize, loffset, remainder;
425429
426- if (offset > node->size)
430+ if (offset < 0)
431+ return -EINVAL;
432+ if (newsize > node->size)
427433 {
428- rc = exfat_truncate(ef, node, offset, true);
434+ rc = exfat_truncate(ef, node, newsize, true);
429435 if (rc != 0)
430436 return rc;
431437 }
432- if (offset + size > node->size)
438+ if (newsize + size > node->size)
433439 {
434- rc = exfat_truncate(ef, node, offset + size, false);
440+ rc = exfat_truncate(ef, node, newsize + size, false);
435441 if (rc != 0)
436442 return rc;
437443 }
438444 if (size == 0)
439445 return 0;
440446
441- cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb));
447+ cluster = exfat_advance_cluster(ef, node, newsize / CLUSTER_SIZE(*ef->sb));
442448 if (CLUSTER_INVALID(*ef->sb, cluster))
443449 {
444450 exfat_error("invalid cluster 0x%x while writing", cluster);
445451 return -EIO;
446452 }
447453
448- loffset = offset % CLUSTER_SIZE(*ef->sb);
454+ loffset = newsize % CLUSTER_SIZE(*ef->sb);
449455 remainder = size;
450456 while (remainder > 0)
451457 {
--- a/libexfat/lookup.c
+++ b/libexfat/lookup.c
@@ -86,7 +86,7 @@ static int lookup_name(struct exfat* ef, struct exfat_node* parent,
8686
8787 *node = NULL;
8888
89- rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n);
89+ rc = exfat_utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n);
9090 if (rc != 0)
9191 return rc;
9292
@@ -194,7 +194,7 @@ int exfat_split(struct exfat* ef, struct exfat_node** parent,
194194 exfat_put_node(ef, *parent);
195195 return -ENOENT;
196196 }
197- rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n);
197+ rc = exfat_utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n);
198198 if (rc != 0)
199199 {
200200 exfat_put_node(ef, *parent);
--- a/libexfat/mount.c
+++ b/libexfat/mount.c
@@ -79,18 +79,6 @@ static int get_int_option(const char* options, const char* option_name,
7979 return strtol(p, NULL, base);
8080 }
8181
82-static bool match_option(const char* options, const char* option_name)
83-{
84- const char* p;
85- size_t length = strlen(option_name);
86-
87- for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name))
88- if ((p == options || p[-1] == ',') &&
89- (p[length] == ',' || p[length] == '\0'))
90- return true;
91- return false;
92-}
93-
9482 static void parse_options(struct exfat* ef, const char* options)
9583 {
9684 int opt_umask;
@@ -102,7 +90,7 @@ static void parse_options(struct exfat* ef, const char* options)
10290 ef->uid = get_int_option(options, "uid", 10, geteuid());
10391 ef->gid = get_int_option(options, "gid", 10, getegid());
10492
105- ef->noatime = match_option(options, "noatime");
93+ ef->noatime = exfat_match_option(options, "noatime");
10694
10795 switch (get_int_option(options, "repair", 10, 0))
10896 {
@@ -122,7 +110,7 @@ static bool verify_vbr_checksum(const struct exfat* ef, void* sector)
122110 {
123111 off_t sector_size = SECTOR_SIZE(*ef->sb);
124112 uint32_t vbr_checksum;
125- int i;
113+ size_t i;
126114
127115 if (exfat_pread(ef->dev, sector, sector_size, 0) < 0)
128116 {
@@ -166,11 +154,8 @@ static int commit_super_block(const struct exfat* ef)
166154 return exfat_fsync(ef->dev);
167155 }
168156
169-static int prepare_super_block(const struct exfat* ef)
157+int exfat_soil_super_block(const struct exfat* ef)
170158 {
171- if (le16_to_cpu(ef->sb->volume_state) & EXFAT_STATE_MOUNTED)
172- exfat_warn("volume was not unmounted cleanly");
173-
174159 if (ef->ro)
175160 return 0;
176161
@@ -205,9 +190,9 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options)
205190
206191 parse_options(ef, options);
207192
208- if (match_option(options, "ro"))
193+ if (exfat_match_option(options, "ro"))
209194 mode = EXFAT_MODE_RO;
210- else if (match_option(options, "ro_fallback"))
195+ else if (exfat_match_option(options, "ro_fallback"))
211196 mode = EXFAT_MODE_ANY;
212197 else
213198 mode = EXFAT_MODE_RW;
@@ -286,7 +271,7 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options)
286271 return -EIO;
287272 }
288273 if (le64_to_cpu(ef->sb->sector_count) * SECTOR_SIZE(*ef->sb) >
289- exfat_get_size(ef->dev))
274+ (uint64_t) exfat_get_size(ef->dev))
290275 {
291276 /* this can cause I/O errors later but we don't fail mounting to let
292277 user rescue data */
@@ -305,6 +290,8 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options)
305290 exfat_free(ef);
306291 return -EIO;
307292 }
293+ if (le16_to_cpu(ef->sb->volume_state) & EXFAT_STATE_MOUNTED)
294+ exfat_warn("volume was not unmounted cleanly");
308295
309296 ef->root = malloc(sizeof(struct exfat_node));
310297 if (ef->root == NULL)
@@ -344,9 +331,6 @@ int exfat_mount(struct exfat* ef, const char* spec, const char* options)
344331 goto error;
345332 }
346333
347- if (prepare_super_block(ef) != 0)
348- goto error;
349-
350334 return 0;
351335
352336 error:
--- a/libexfat/node.c
+++ b/libexfat/node.c
@@ -87,7 +87,7 @@ static int read_entries(struct exfat* ef, struct exfat_node* dir,
8787
8888 size = exfat_generic_pread(ef, dir, entries,
8989 sizeof(struct exfat_entry[n]), offset);
90- if (size == sizeof(struct exfat_entry[n]))
90+ if (size == (ssize_t) sizeof(struct exfat_entry) * n)
9191 return 0; /* success */
9292 if (size == 0)
9393 return -ENOENT;
@@ -108,7 +108,7 @@ static int write_entries(struct exfat* ef, struct exfat_node* dir,
108108
109109 size = exfat_generic_pwrite(ef, dir, entries,
110110 sizeof(struct exfat_entry[n]), offset);
111- if (size == sizeof(struct exfat_entry[n]))
111+ if (size == (ssize_t) sizeof(struct exfat_entry) * n)
112112 return 0; /* success */
113113 if (size < 0)
114114 return -EIO;
@@ -396,6 +396,7 @@ static int readdir(struct exfat* ef, struct exfat_node* parent,
396396 const struct exfat_entry_label* label;
397397 uint64_t upcase_size = 0;
398398 le16_t* upcase_comp = NULL;
399+ le16_t label_name[EXFAT_ENAME_MAX];
399400
400401 for (;;)
401402 {
@@ -508,7 +509,10 @@ static int readdir(struct exfat* ef, struct exfat_node* parent,
508509 exfat_error("too long label (%hhu chars)", label->length);
509510 return -EIO;
510511 }
511- if (utf16_to_utf8(ef->label, label->name,
512+ /* copy to a temporary buffer to avoid unaligned access to a
513+ packed member */
514+ memcpy(label_name, label->name, sizeof(label_name));
515+ if (exfat_utf16_to_utf8(ef->label, label_name,
512516 sizeof(ef->label), EXFAT_ENAME_MAX) != 0)
513517 return -EIO;
514518 break;
@@ -628,6 +632,7 @@ int exfat_flush_node(struct exfat* ef, struct exfat_node* node)
628632 struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0];
629633 struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1];
630634 int rc;
635+ le16_t edate, etime;
631636
632637 if (!node->is_dirty)
633638 return 0; /* no need to flush */
@@ -646,10 +651,14 @@ int exfat_flush_node(struct exfat* ef, struct exfat_node* node)
646651 return -EIO;
647652
648653 meta1->attrib = cpu_to_le16(node->attrib);
649- exfat_unix2exfat(node->mtime, &meta1->mdate, &meta1->mtime,
654+ exfat_unix2exfat(node->mtime, &edate, &etime,
650655 &meta1->mtime_cs, &meta1->mtime_tzo);
651- exfat_unix2exfat(node->atime, &meta1->adate, &meta1->atime,
656+ meta1->mdate = edate;
657+ meta1->mtime = etime;
658+ exfat_unix2exfat(node->atime, &edate, &etime,
652659 NULL, &meta1->atime_tzo);
660+ meta1->adate = edate;
661+ meta1->atime = etime;
653662 meta2->size = meta2->valid_size = cpu_to_le64(node->size);
654663 meta2->start_cluster = cpu_to_le32(node->start_cluster);
655664 meta2->flags = EXFAT_FLAG_ALWAYS1;
@@ -732,7 +741,7 @@ static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
732741 /* two subentries with meta info */
733742 entries += 2;
734743 /* subentries with file name */
735- entries += DIV_ROUND_UP(utf16_length(last_node->name),
744+ entries += DIV_ROUND_UP(exfat_utf16_length(last_node->name),
736745 EXFAT_ENAME_MAX);
737746 }
738747
@@ -800,7 +809,7 @@ static int check_slot(struct exfat* ef, struct exfat_node* dir, off_t offset,
800809 {
801810 struct exfat_entry entries[n];
802811 int rc;
803- size_t i;
812+ int i;
804813
805814 /* Root directory contains entries, that don't have any nodes associated
806815 with them (clusters bitmap, upper case table, label). We need to be
@@ -838,7 +847,7 @@ static int find_slot(struct exfat* ef, struct exfat_node* dir,
838847 return -ENOMEM;
839848 }
840849 for (p = dir->child; p != NULL; p = p->next)
841- for (i = 0; i < 1 + p->continuations; i++)
850+ for (i = 0; i < 1u + p->continuations; i++)
842851 BMAP_SET(dmap, p->entry_offset / sizeof(struct exfat_entry) + i);
843852
844853 /* find a slot in the directory entries bitmap */
@@ -883,23 +892,24 @@ static int commit_entry(struct exfat* ef, struct exfat_node* dir,
883892 const le16_t* name, off_t offset, uint16_t attrib)
884893 {
885894 struct exfat_node* node;
886- const size_t name_length = utf16_length(name);
895+ const size_t name_length = exfat_utf16_length(name);
887896 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
888897 struct exfat_entry entries[2 + name_entries];
889898 struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0];
890899 struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1];
891900 int i;
892901 int rc;
902+ le16_t edate, etime;
893903
894904 memset(entries, 0, sizeof(struct exfat_entry[2]));
895905
896906 meta1->type = EXFAT_ENTRY_FILE;
897907 meta1->continuations = 1 + name_entries;
898908 meta1->attrib = cpu_to_le16(attrib);
899- exfat_unix2exfat(time(NULL), &meta1->crdate, &meta1->crtime,
909+ exfat_unix2exfat(time(NULL), &edate, &etime,
900910 &meta1->crtime_cs, &meta1->crtime_tzo);
901- meta1->adate = meta1->mdate = meta1->crdate;
902- meta1->atime = meta1->mtime = meta1->crtime;
911+ meta1->adate = meta1->mdate = meta1->crdate = edate;
912+ meta1->atime = meta1->mtime = meta1->crtime = etime;
903913 meta1->mtime_cs = meta1->crtime_cs; /* there is no atime_cs */
904914 meta1->atime_tzo = meta1->mtime_tzo = meta1->crtime_tzo;
905915
@@ -956,7 +966,7 @@ static int create(struct exfat* ef, const char* path, uint16_t attrib)
956966 }
957967
958968 rc = find_slot(ef, dir, &offset,
959- 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
969+ 2 + DIV_ROUND_UP(exfat_utf16_length(name), EXFAT_ENAME_MAX));
960970 if (rc != 0)
961971 {
962972 exfat_put_node(ef, dir);
@@ -1012,7 +1022,7 @@ int exfat_mkdir(struct exfat* ef, const char* path)
10121022 static int rename_entry(struct exfat* ef, struct exfat_node* dir,
10131023 struct exfat_node* node, const le16_t* name, off_t new_offset)
10141024 {
1015- const size_t name_length = utf16_length(name);
1025+ const size_t name_length = exfat_utf16_length(name);
10161026 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
10171027 struct exfat_entry entries[2 + name_entries];
10181028 struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0];
@@ -1135,7 +1145,7 @@ int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
11351145 }
11361146
11371147 rc = find_slot(ef, dir, &offset,
1138- 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
1148+ 2 + DIV_ROUND_UP(exfat_utf16_length(name), EXFAT_ENAME_MAX));
11391149 if (rc != 0)
11401150 {
11411151 exfat_put_node(ef, dir);
@@ -1204,7 +1214,8 @@ int exfat_set_label(struct exfat* ef, const char* label)
12041214 struct exfat_entry_label entry;
12051215
12061216 memset(label_utf16, 0, sizeof(label_utf16));
1207- rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX + 1, strlen(label));
1217+ rc = exfat_utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX + 1,
1218+ strlen(label));
12081219 if (rc != 0)
12091220 return rc;
12101221
@@ -1215,7 +1226,7 @@ int exfat_set_label(struct exfat* ef, const char* label)
12151226 return rc;
12161227
12171228 entry.type = EXFAT_ENTRY_LABEL;
1218- entry.length = utf16_length(label_utf16);
1229+ entry.length = exfat_utf16_length(label_utf16);
12191230 memcpy(entry.name, label_utf16, sizeof(entry.name));
12201231 if (entry.length == 0)
12211232 entry.type ^= EXFAT_ENTRY_VALID;
--- a/libexfat/platform.h
+++ b/libexfat/platform.h
@@ -56,6 +56,16 @@
5656 #define EXFAT_LITTLE_ENDIAN _LITTLE_ENDIAN
5757 #define EXFAT_BIG_ENDIAN _BIG_ENDIAN
5858
59+#elif defined(__sun)
60+
61+#include <endian.h>
62+#define exfat_bswap16(x) bswap_16(x)
63+#define exfat_bswap32(x) bswap_32(x)
64+#define exfat_bswap64(x) bswap_64(x)
65+#define EXFAT_BYTE_ORDER __BYTE_ORDER
66+#define EXFAT_LITTLE_ENDIAN __LITTLE_ENDIAN
67+#define EXFAT_BIG_ENDIAN __BIG_ENDIAN
68+
5969 #else
6070 #error Unknown platform
6171 #endif
--- a/libexfat/repair.c
+++ b/libexfat/repair.c
@@ -77,7 +77,7 @@ bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector,
7777 return true;
7878 }
7979
80-bool exfat_fix_invalid_node_checksum(const struct exfat* ef,
80+bool exfat_fix_invalid_node_checksum(UNUSED const struct exfat* ef,
8181 struct exfat_node* node)
8282 {
8383 /* checksum will be rewritten by exfat_flush_node() */
--- a/libexfat/utf.c
+++ b/libexfat/utf.c
@@ -101,23 +101,25 @@ static const le16_t* utf16_to_wchar(const le16_t* input, wchar_t* wc,
101101 }
102102 }
103103
104-int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
104+int exfat_utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
105105 size_t insize)
106106 {
107- const le16_t* inp = input;
108- char* outp = output;
107+ const le16_t* iptr = input;
108+ const le16_t* iend = input + insize;
109+ char* optr = output;
110+ const char* oend = output + outsize;
109111 wchar_t wc;
110112
111- while (inp - input < insize)
113+ while (iptr < iend)
112114 {
113- inp = utf16_to_wchar(inp, &wc, insize - (inp - input));
114- if (inp == NULL)
115+ iptr = utf16_to_wchar(iptr, &wc, iend - iptr);
116+ if (iptr == NULL)
115117 {
116118 exfat_error("illegal UTF-16 sequence");
117119 return -EILSEQ;
118120 }
119- outp = wchar_to_utf8(outp, wc, outsize - (outp - output));
120- if (outp == NULL)
121+ optr = wchar_to_utf8(optr, wc, oend - optr);
122+ if (optr == NULL)
121123 {
122124 exfat_error("name is too long");
123125 return -ENAMETOOLONG;
@@ -125,64 +127,69 @@ int utf16_to_utf8(char* output, const le16_t* input, size_t outsize,
125127 if (wc == 0)
126128 return 0;
127129 }
128- if (outp - output >= outsize)
130+ if (optr >= oend)
129131 {
130132 exfat_error("name is too long");
131133 return -ENAMETOOLONG;
132134 }
133- *outp = '\0';
135+ *optr = '\0';
134136 return 0;
135137 }
136138
137139 static const char* utf8_to_wchar(const char* input, wchar_t* wc,
138140 size_t insize)
139141 {
140- if ((input[0] & 0x80) == 0 && insize >= 1)
142+ size_t size;
143+ size_t i;
144+
145+ if (insize == 0)
146+ exfat_bug("no input for utf8_to_wchar");
147+
148+ if ((input[0] & 0x80) == 0)
141149 {
142150 *wc = (wchar_t) input[0];
143151 return input + 1;
144152 }
145- if ((input[0] & 0xe0) == 0xc0 && insize >= 2)
153+ else if ((input[0] & 0xe0) == 0xc0)
146154 {
147- *wc = (((wchar_t) input[0] & 0x1f) << 6) |
148- ((wchar_t) input[1] & 0x3f);
149- return input + 2;
155+ *wc = ((wchar_t) input[0] & 0x1f) << 6;
156+ size = 2;
150157 }
151- if ((input[0] & 0xf0) == 0xe0 && insize >= 3)
158+ else if ((input[0] & 0xf0) == 0xe0)
152159 {
153- *wc = (((wchar_t) input[0] & 0x0f) << 12) |
154- (((wchar_t) input[1] & 0x3f) << 6) |
155- ((wchar_t) input[2] & 0x3f);
156- return input + 3;
160+ *wc = ((wchar_t) input[0] & 0x0f) << 12;
161+ size = 3;
157162 }
158- if ((input[0] & 0xf8) == 0xf0 && insize >= 4)
163+ else if ((input[0] & 0xf8) == 0xf0)
159164 {
160- *wc = (((wchar_t) input[0] & 0x07) << 18) |
161- (((wchar_t) input[1] & 0x3f) << 12) |
162- (((wchar_t) input[2] & 0x3f) << 6) |
163- ((wchar_t) input[3] & 0x3f);
164- return input + 4;
165+ *wc = ((wchar_t) input[0] & 0x07) << 18;
166+ size = 4;
165167 }
166- if ((input[0] & 0xfc) == 0xf8 && insize >= 5)
168+ else if ((input[0] & 0xfc) == 0xf8)
167169 {
168- *wc = (((wchar_t) input[0] & 0x03) << 24) |
169- (((wchar_t) input[1] & 0x3f) << 18) |
170- (((wchar_t) input[2] & 0x3f) << 12) |
171- (((wchar_t) input[3] & 0x3f) << 6) |
172- ((wchar_t) input[4] & 0x3f);
173- return input + 5;
170+ *wc = ((wchar_t) input[0] & 0x03) << 24;
171+ size = 5;
174172 }
175- if ((input[0] & 0xfe) == 0xfc && insize >= 6)
173+ else if ((input[0] & 0xfe) == 0xfc)
174+ {
175+ *wc = ((wchar_t) input[0] & 0x01) << 30;
176+ size = 6;
177+ }
178+ else
179+ return NULL;
180+
181+ if (insize < size)
182+ return NULL;
183+
184+ /* the first byte is handled above */
185+ for (i = 1; i < size; i++)
176186 {
177- *wc = (((wchar_t) input[0] & 0x01) << 30) |
178- (((wchar_t) input[1] & 0x3f) << 24) |
179- (((wchar_t) input[2] & 0x3f) << 18) |
180- (((wchar_t) input[3] & 0x3f) << 12) |
181- (((wchar_t) input[4] & 0x3f) << 6) |
182- ((wchar_t) input[5] & 0x3f);
183- return input + 6;
187+ if ((input[i] & 0xc0) != 0x80)
188+ return NULL;
189+ *wc |= (input[i] & 0x3f) << ((size - i - 1) * 6);
184190 }
185- return NULL;
191+
192+ return input + size;
186193 }
187194
188195 static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize)
@@ -202,23 +209,25 @@ static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize)
202209 return output + 2;
203210 }
204211
205-int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
212+int exfat_utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
206213 size_t insize)
207214 {
208- const char* inp = input;
209- le16_t* outp = output;
215+ const char* iptr = input;
216+ const char* iend = input + insize;
217+ le16_t* optr = output;
218+ const le16_t* oend = output + outsize;
210219 wchar_t wc;
211220
212- while (inp - input < insize)
221+ while (iptr < iend)
213222 {
214- inp = utf8_to_wchar(inp, &wc, insize - (inp - input));
215- if (inp == NULL)
223+ iptr = utf8_to_wchar(iptr, &wc, iend - iptr);
224+ if (iptr == NULL)
216225 {
217226 exfat_error("illegal UTF-8 sequence");
218227 return -EILSEQ;
219228 }
220- outp = wchar_to_utf16(outp, wc, outsize - (outp - output));
221- if (outp == NULL)
229+ optr = wchar_to_utf16(optr, wc, oend - optr);
230+ if (optr == NULL)
222231 {
223232 exfat_error("name is too long");
224233 return -ENAMETOOLONG;
@@ -226,16 +235,16 @@ int utf8_to_utf16(le16_t* output, const char* input, size_t outsize,
226235 if (wc == 0)
227236 break;
228237 }
229- if (outp - output >= outsize)
238+ if (optr >= oend)
230239 {
231240 exfat_error("name is too long");
232241 return -ENAMETOOLONG;
233242 }
234- *outp = cpu_to_le16(0);
243+ *optr = cpu_to_le16(0);
235244 return 0;
236245 }
237246
238-size_t utf16_length(const le16_t* str)
247+size_t exfat_utf16_length(const le16_t* str)
239248 {
240249 size_t i = 0;
241250
--- a/libexfat/utils.c
+++ b/libexfat/utils.c
@@ -48,7 +48,7 @@ void exfat_stat(const struct exfat* ef, const struct exfat_node* node,
4848 void exfat_get_name(const struct exfat_node* node,
4949 char buffer[EXFAT_UTF8_NAME_BUFFER_MAX])
5050 {
51- if (utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX,
51+ if (exfat_utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX,
5252 EXFAT_NAME_MAX) != 0)
5353 exfat_bug("failed to convert name to UTF-8");
5454 }
@@ -60,7 +60,7 @@ static uint16_t add_checksum_byte(uint16_t sum, uint8_t byte)
6060
6161 static uint16_t add_checksum_bytes(uint16_t sum, const void* buffer, size_t n)
6262 {
63- int i;
63+ size_t i;
6464
6565 for (i = 0; i < n; i++)
6666 sum = add_checksum_byte(sum, ((const uint8_t*) buffer)[i]);
@@ -70,7 +70,7 @@ static uint16_t add_checksum_bytes(uint16_t sum, const void* buffer, size_t n)
7070 uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry)
7171 {
7272 uint16_t sum = 0;
73- int i;
73+ size_t i;
7474
7575 for (i = 0; i < sizeof(struct exfat_entry); i++)
7676 if (i != 2 && i != 3) /* skip checksum field itself */
@@ -178,3 +178,15 @@ void exfat_print_info(const struct exfat_super_block* sb,
178178 exfat_humanize_bytes(avail_space, &hb);
179179 printf("Available space %10"PRIu64" %s\n", hb.value, hb.unit);
180180 }
181+
182+bool exfat_match_option(const char* options, const char* option_name)
183+{
184+ const char* p;
185+ size_t length = strlen(option_name);
186+
187+ for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name))
188+ if ((p == options || p[-1] == ',') &&
189+ (p[length] == ',' || p[length] == '\0'))
190+ return true;
191+ return false;
192+}
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -121,9 +121,9 @@ static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size)
121121 return user_defined;
122122 }
123123
124- if (volume_size < 256ull * 1024 * 1024)
124+ if (volume_size < 256LL * 1024 * 1024)
125125 return MAX(0, 12 - sector_bits); /* 4 KB */
126- if (volume_size < 32ull * 1024 * 1024 * 1024)
126+ if (volume_size < 32LL * 1024 * 1024 * 1024)
127127 return MAX(0, 15 - sector_bits); /* 32 KB */
128128
129129 for (i = 17; ; i++) /* 128 KB or more */
@@ -136,7 +136,7 @@ static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s)
136136 memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t));
137137 if (s == NULL)
138138 return 0;
139- return utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s));
139+ return exfat_utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s));
140140 }
141141
142142 static uint32_t setup_volume_serial(uint32_t user_defined)
@@ -178,7 +178,7 @@ static int setup(struct exfat_dev* dev, int sector_bits, int spc_bits,
178178
179179 static int logarithm2(int n)
180180 {
181- int i;
181+ size_t i;
182182
183183 for (i = 0; i < sizeof(int) * CHAR_BIT - 1; i++)
184184 if ((1 << i) == n)
--- a/mkfs/mkexfat.c
+++ b/mkfs/mkexfat.c
@@ -52,7 +52,7 @@ static int check_size(off_t volume_size)
5252 }
5353
5454 static int erase_object(struct exfat_dev* dev, const void* block,
55- size_t block_size, off_t start, off_t size)
55+ off_t block_size, off_t start, off_t size)
5656 {
5757 const off_t block_count = DIV_ROUND_UP(size, block_size);
5858 off_t i;
@@ -78,12 +78,12 @@ static int erase(struct exfat_dev* dev)
7878 {
7979 const struct fs_object** pp;
8080 off_t position = 0;
81- const size_t block_size = 1024 * 1024;
81+ const off_t block_size = 1024 * 1024;
8282 void* block = malloc(block_size);
8383
8484 if (block == NULL)
8585 {
86- exfat_error("failed to allocate erase block of %zu bytes", block_size);
86+ exfat_error("failed to allocate erase block");
8787 return 1;
8888 }
8989 memset(block, 0, block_size);
--- a/mkfs/rootdir.c
+++ b/mkfs/rootdir.c
@@ -41,12 +41,12 @@ static void init_label_entry(struct exfat_entry_label* label_entry)
4141 memset(label_entry, 0, sizeof(struct exfat_entry_label));
4242 label_entry->type = EXFAT_ENTRY_LABEL ^ EXFAT_ENTRY_VALID;
4343
44- if (utf16_length(get_volume_label()) == 0)
44+ if (exfat_utf16_length(get_volume_label()) == 0)
4545 return;
4646
4747 memcpy(label_entry->name, get_volume_label(),
4848 EXFAT_ENAME_MAX * sizeof(le16_t));
49- label_entry->length = utf16_length(get_volume_label());
49+ label_entry->length = exfat_utf16_length(get_volume_label());
5050 label_entry->type |= EXFAT_ENTRY_VALID;
5151 }
5252
Show on old repository browser