diff --git a/include/ipfs/path/path.h b/include/ipfs/path/path.h index 9ad58f4..17850bf 100644 --- a/include/ipfs/path/path.h +++ b/include/ipfs/path/path.h @@ -4,6 +4,7 @@ #ifdef IPFS_PATH_C char *ErrPath[] = { NULL, + "ErrAllocFailed", // ErrBadPath is returned when a given path is incorrectly formatted "invalid 'ipfs ref' path", // Paths after a protocol must contain at least one component @@ -17,7 +18,8 @@ #endif // IPFS_PATH_C enum { - ErrBadPath = 1, + ErrAllocFailed = 1, + ErrBadPath, ErrNoComponents, ErrCidDecode, ErrNoLink, diff --git a/namesys/dns.c b/namesys/dns.c index 0991a8d..23d7e9a 100644 --- a/namesys/dns.c +++ b/namesys/dns.c @@ -51,7 +51,7 @@ type lookupRes struct { int ipfs_dns_resolver_resolve_once (char **path, char *name) { char **segments, *domain, *dnslink, buf[500], dlprefix[] = "_dnslink."; - int p1[2], p2[2], r, c=2; + int p1[2], p2[2], r, l, c=2; struct pollfd event[2], *e; segments = ipfs_path_split_n(name, "/", 2); @@ -84,12 +84,14 @@ int ipfs_dns_resolver_resolve_once (char **path, char *name) case 0: // child close(p2[STDIN_FILENO]); // we don't need to read at child process. - dnslink = malloc(strlen(domain) + sizeof(dlprefix)); + l = strlen(domain) + sizeof(dlprefix); + dnslink = malloc(l); if (!dnslink) { return ErrAllocFailed; } - strcpy (dnslink, dlprefix); - strcat (dnslink, domain); + dnslink[--l] = '\0'; + strncpy (dnslink, dlprefix, l); + strncat (dnslink, domain, l - strlen(dnslink)); return ipfs_dns_work_domain (p2[STDOUT_FILENO], r, dnslink); } @@ -114,7 +116,8 @@ int ipfs_dns_resolver_resolve_once (char **path, char *name) buf[r] = '\0'; *path = malloc(r+1); if (*path) { - strcpy(*path, buf); + *path[r] = '\0'; + strncpy(*path, buf, r); } } else if (r <= 0) { return ErrPoll; @@ -187,7 +190,7 @@ int ipfs_dns_parse_entry (char **path, char *txt) if (!*path) { return ErrAllocFailed; } - strcpy(*path, buf); + memcpy(*path, buf, strlen(buf) + 1); return 0; } return ipfs_dns_try_parse_dns_link(path, txt); @@ -205,7 +208,7 @@ int ipfs_dns_try_parse_dns_link(char **path, char *txt) if (! *parts) { return ErrAllocFailed; } - strcpy(*parts, buf); + memcpy(*parts, buf, strlen(buf) + 1); return 0; } return err; diff --git a/namesys/isdomain.c b/namesys/isdomain.c index ec9d2ca..5317070 100644 --- a/namesys/isdomain.c +++ b/namesys/isdomain.c @@ -90,10 +90,14 @@ int ipfs_isdomain_is_tld (char *s) // It first checks the TLD, and then uses a regular expression. int ipfs_isdomain_is_domain (char *s) { - char str[strlen(s)]; - char *tld; + int err; + char *str, *tld; - strcpy(str, s); + str = malloc(strlen(s) + 1); + if (!str) { + return ErrAllocFailed; + } + memcpy(str, s, strlen(s) + 1); s = str; // work with local copy. if (ipfs_isdomain_has_suffix (s, ".")) { @@ -112,5 +116,7 @@ int ipfs_isdomain_is_domain (char *s) return 0; } - return ipfs_isdomain_match_string(s); + err = ipfs_isdomain_match_string(s); + free (s); + return err; } diff --git a/namesys/namesys.c b/namesys/namesys.c index fd534a4..f6eed85 100644 --- a/namesys/namesys.c +++ b/namesys/namesys.c @@ -55,7 +55,7 @@ int ipfs_namesys_resolve_n(char **path, char *name, int depth) ipfs_path_parse(p, name); *path = malloc(strlen(p) + 1); if (*p) { - strcpy(*path, p); + memcpy(*path, p, strlen(p) + 1); } else { err = ErrAllocFailed; } @@ -63,18 +63,22 @@ int ipfs_namesys_resolve_n(char **path, char *name, int depth) } if (*name == '/') { - int err; - char *str = malloc(sizeof(ipfs_prefix) + strlen(name)); + int err, l; + char *str; + + l = sizeof(ipfs_prefix) + strlen(name); + str = malloc(l); if (!str) { return ErrAllocFailed; } - strcpy(str, ipfs_prefix); - strcat(str, name+1); // ignore inital / from name, because ipfs_prefix already has it. + str[--l] = '\0'; + strncpy(str, ipfs_prefix, l); + strncat(str, name+1, l - strlen (str)); // ignore inital / from name, because ipfs_prefix already has it. err = ipfs_path_parse(p, str); // save return value. free (str); // so we can free allocated memory before return. *path = malloc(strlen(p) + 1); if (*p) { - strcpy(*path, p); + memcpy(*path, p, strlen(p) + 1); } else { err = ErrAllocFailed; } @@ -97,12 +101,14 @@ int ipfs_namesys_resolve_once (char **path, char *name) } if (memcmp (name, ipns_prefix, strlen(ipns_prefix)) == 0) { // prefix missing. - ptr = malloc(strlen(name) + sizeof(ipns_prefix)); + i = strlen(name) + sizeof(ipns_prefix); + ptr = malloc(i); if (!ptr) { // allocation fail. return ErrAllocFailed; } - strcpy(ptr, ipns_prefix); - strcat(ptr, name); + ptr[--i] = '\0'; + strncpy(ptr, ipns_prefix, i); + strncat(ptr, name, i - strlen(ptr)); segs = ipfs_path_split_segments(ptr); free (ptr); } else { diff --git a/namesys/proquint.c b/namesys/proquint.c index ded1995..561b4f0 100644 --- a/namesys/proquint.c +++ b/namesys/proquint.c @@ -176,7 +176,7 @@ int ipfs_proquint_resolve_once (char **p, char *name) if (!err) { *p = malloc (strlen(buf) + 1); if (p) { - strcpy(*p, buf); + memcpy(*p, buf, strlen(buf) + 1); } } } diff --git a/path/path.c b/path/path.c index 88c6556..948ac41 100644 --- a/path/path.c +++ b/path/path.c @@ -9,11 +9,14 @@ char* ipfs_path_from_cid (struct Cid *c) { const char prefix[] = "/ipfs/"; char *rpath, *cidstr = CidString(c); + int l; - rpath = malloc(sizeof(prefix) + strlen(cidstr)); + l = sizeof(prefix) + strlen(cidstr); + rpath = malloc(l); if (!rpath) return NULL; - strcpy(rpath, prefix); - strcat(rpath, cidstr); + rpath[--l] = '\0'; + strncpy(rpath, prefix, l); + strncat(rpath, cidstr, l - strlen(rpath)); return rpath; } @@ -48,7 +51,7 @@ char** ipfs_path_split_n (char *p, char *delim, int n) return NULL; } - strcpy(rbuf, p); // keep original + memcpy(rbuf, p, strlen(p) + 1); // keep original for (c = rbuf, i = 0 ; i < n && c ; i++) { r[i] = c; c = strstr(c, delim); @@ -206,10 +209,11 @@ char *ipfs_path_from_segments(char *prefix, char **seg) ret = malloc(retlen + 1); // allocate final string size + null terminator. if (!ret) return NULL; - strcpy(ret, prefix); + ret[retlen] = '\0'; + strncpy(ret, prefix, retlen); for (i = 0 ; seg[i] ; i++) { - strcat(ret, "/"); - strcat(ret, seg[i]); + strncat(ret, "/", retlen - strlen(ret)); + strncat(ret, seg[i], retlen - strlen(ret)); } return ret; } @@ -232,7 +236,7 @@ int ipfs_path_parse_from_cid (char *dst, char *txt) if (!r) { return ErrCidDecode; } - strcpy (dst, r); + memcpy (dst, r, strlen(r) + 1); free (r); return 0; } @@ -252,7 +256,7 @@ int ipfs_path_parse (char *dst, char *txt) } err = ipfs_path_parse_from_cid (dst+plen, txt); if (err == 0) { // only change dst if ipfs_path_parse_from_cid returned success. - // Use memcpy instead of strcpy to avoid overwriting + // Use memcpy instead of strncpy to avoid overwriting // result of ipfs_path_parse_from_cid with a null terminator. memcpy (dst, prefix, plen); } @@ -264,11 +268,21 @@ int ipfs_path_parse (char *dst, char *txt) if (i < 3) return ErrBadPath; if (strcmp (txt, prefix) == 0) { - char buf[strlen(txt+5)]; - strcpy (buf, txt+6); // copy to temp buffer. + char *buf; + i = strlen(txt+6); + buf = malloc(i + 1); + if (!buf) { + return ErrAllocFailed; + } + buf[i] = '\0'; + strncpy (buf, txt+6, i); // copy to temp buffer. c = strchr(buf, '/'); - if (c) *c = '\0'; - return ipfs_path_parse_from_cid(dst, buf); + if (c) { + *c = '\0'; + } + err = ipfs_path_parse_from_cid(dst, buf); + free (buf); + return err; } else if (strcmp (txt, "/ipns/") != 0) { return ErrBadPath; } diff --git a/path/resolver.c b/path/resolver.c index c4b410f..4d17129 100644 --- a/path/resolver.c +++ b/path/resolver.c @@ -87,7 +87,7 @@ int ipfs_path_resolve_path_components(Node ***nd, Context ctx, Resolver *s, char // would retrieve "baz" in ("bar" in ("foo" in nd.Links).Links).Links int ipfs_path_resolve_links(Node ***result, Context ctx, Node *ndd, char **names) { - int err, idx = 0; + int err, idx = 0, l; NodeLink *lnk; Node *nd; @@ -115,9 +115,10 @@ int ipfs_path_resolve_links(Node ***result, Context ctx, Node *ndd, char **names if (ErrPath[ErrNoLink]) { free(ErrPath[ErrNoLink]); } - ErrPath[ErrNoLink] = malloc(strlen(msg) + 1); + l = strlen(msg) + 1; + ErrPath[ErrNoLink] = malloc(l); if (ErrPath[ErrNoLink]) { - strcpy(ErrPath[ErrNoLink], msg); + memcpy(ErrPath[ErrNoLink], msg, l); } free (*result); return ErrNoLink;