aboutsummaryrefslogtreecommitdiffstats
path: root/libexfat/lookup.c
diff options
context:
space:
mode:
authorrelan <relan@users.noreply.github.com>2009-09-28 08:56:07 +0000
committerrelan <relan@users.noreply.github.com>2015-08-24 08:26:10 +0300
commit80b9c1e94de2950ea78606924bad83fa66db41a7 (patch)
tree4c89d3e066fe1702a72ce283b831fdcd502b0e7c /libexfat/lookup.c
parent26ab8a8e360cd0c977366e55acec446054d0923e (diff)
downloadandroid_external_exfat-80b9c1e94de2950ea78606924bad83fa66db41a7.tar.gz
android_external_exfat-80b9c1e94de2950ea78606924bad83fa66db41a7.tar.bz2
android_external_exfat-80b9c1e94de2950ea78606924bad83fa66db41a7.zip
Path parsing cleanup.
Now only path component length is limited to 256 chars (this is exFAT limitation), not the whole path.
Diffstat (limited to 'libexfat/lookup.c')
-rw-r--r--libexfat/lookup.c63
1 files changed, 26 insertions, 37 deletions
diff --git a/libexfat/lookup.c b/libexfat/lookup.c
index a40550b..3ab3f08 100644
--- a/libexfat/lookup.c
+++ b/libexfat/lookup.c
@@ -234,14 +234,20 @@ static int compare_name(struct exfat* ef, const le16_t* a, const le16_t* b)
}
static int lookup_name(struct exfat* ef, struct exfat_node* node,
- const le16_t* name)
+ const char* name, size_t n)
{
struct exfat_iterator it;
+ le16_t buffer[EXFAT_NAME_MAX + 1];
+ int rc;
+
+ rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX, n);
+ if (rc != 0)
+ return rc;
exfat_opendir(node, &it);
while (exfat_readdir(ef, node, &it) == 0)
{
- if (compare_name(ef, name, node->name) == 0)
+ if (compare_name(ef, buffer, node->name) == 0)
{
exfat_closedir(&it);
return 0;
@@ -251,23 +257,23 @@ static int lookup_name(struct exfat* ef, struct exfat_node* node,
return -ENOENT;
}
-int exfat_lookup(struct exfat* ef, struct exfat_node* node,
- const char* path)
+size_t get_comp(const char* path, const char** comp)
{
- le16_t buffer[EXFAT_NAME_MAX + 1];
- int rc;
- le16_t* p;
- le16_t* subpath;
+ const char* end;
- if (strlen(path) > EXFAT_NAME_MAX)
- {
- exfat_error("file name `%s' is too long", path);
- return -ENAMETOOLONG;
- }
+ *comp = path + strspn(path, "/"); /* skip leading slashes */
+ end = strchr(*comp, '/');
+ if (end == NULL)
+ return strlen(*comp);
+ else
+ return end - *comp;
+}
- rc = utf8_to_utf16(buffer, path, EXFAT_NAME_MAX, strlen(path));
- if (rc != 0)
- return rc;
+int exfat_lookup(struct exfat* ef, struct exfat_node* node,
+ const char* path)
+{
+ const char* p;
+ size_t n;
/* start from the root directory */
node->flags = EXFAT_ATTRIB_DIR;
@@ -278,28 +284,11 @@ int exfat_lookup(struct exfat* ef, struct exfat_node* node,
node->mtime = ef->mount_time;
node->atime = ef->mount_time;
- for (subpath = p = buffer; p; subpath = p + 1)
+ for (p = path; (n = get_comp(p, &p)); p += n)
{
- while (le16_to_cpu(*subpath) == '/')
- subpath++; /* skip leading slashes */
- for (p = subpath; ; p++)
- {
- if (le16_to_cpu(*p) == '\0')
- {
- p = NULL;
- break;
- }
- if (le16_to_cpu(*p) == '/')
- {
- *p = cpu_to_le16('\0');
- break;
- }
- }
- if (le16_to_cpu(*subpath) == '\0')
- break; /* skip trailing slashes */
- if (le16_to_cpu(subpath[0]) == '.' && le16_to_cpu(subpath[1]) == '\0')
- continue; /* skip "." component */
- if (lookup_name(ef, node, subpath) != 0)
+ if (n == 1 && *p == '.') /* skip "." component */
+ continue;
+ if (lookup_name(ef, node, p, n) != 0)
return -ENOENT;
}
return 0;