diff --git a/README b/README index d3e37b2..929fed7 100644 --- a/README +++ b/README @@ -42,6 +42,16 @@ The basic syntax of these URLs is : nfs://[:]/path[?arg=val[&arg=val]*] +Special characters in 'path' are escaped using %-hex-hex syntax. + +For example '?' must be escaped if it occurs in a path as '?' is also used to +separate the path from the optional list of url arguments. + +Example: +nfs://127.0.0.1/my?path/?version=4 +must be escaped as +nfs://127.0.0.1/my%3Fpath/?version=4 + Arguments supported by libnfs are : tcp-syncnt= : Number of SYNs to send during the session establish before failing setting up the tcp connection to the diff --git a/lib/libnfs.c b/lib/libnfs.c index acd77fb..62d7a04 100755 --- a/lib/libnfs.c +++ b/lib/libnfs.c @@ -303,11 +303,25 @@ nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val) return 0; } +static int +tohex(char ch) +{ + if (ch >= '0' && ch <= '9') { + return ch - '0'; + } + ch &= 0xDF; + if (ch >= 'A' && ch <= 'F') { + return ch - 'A' + 10; + } + return -1; +} + static struct nfs_url * nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete) { struct nfs_url *urls; - char *strp, *flagsp, *strp2; + char *strp, *flagsp, *strp2, ch; + int tmp; if (strncmp(url, "nfs://", 6)) { nfs_set_error(nfs, "Invalid URL specified"); @@ -328,6 +342,30 @@ nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete) return NULL; } + /* unescape all % hex hex characters */ + strp = urls->server; + while (strp && *strp) { + strp = strchr(strp, '%'); + if (strp == NULL) { + break; + } + tmp = tohex(strp[1]); + if (tmp < 0) { + strp++; + continue; + } + ch = (tmp & 0x0f) << 4; + tmp = tohex(strp[2]); + if (tmp < 0) { + strp++; + continue; + } + ch |= tmp & 0x0f; + *strp = ch; + strcpy(strp + 1, strp + 3); + strp++; + } + if (urls->server[0] == '/' || urls->server[0] == '\0' || urls->server[0] == '?') { if (incomplete) {