diff --git a/include/common.h b/include/common.h index 68a78fad7..058345778 100644 --- a/include/common.h +++ b/include/common.h @@ -226,6 +226,7 @@ static char *StsMalloc(size_t size, char *file, long line) #endif #define safestrdup(x,y) do { if (x) MyFree(x); if (!y) x = NULL; else x = strdup(y); } while(0) +#define safestrldup(x,y,sz) do { if (x) MyFree(x); if (!y) x = NULL; else x = strldup(y,sz); } while(0) #define safefree(x) do { if (x) MyFree(x); x = NULL; } while(0) extern struct SLink *find_user_link( /* struct SLink *, struct Client * */ ); diff --git a/include/h.h b/include/h.h index ad2619d74..0cde80510 100644 --- a/include/h.h +++ b/include/h.h @@ -409,15 +409,15 @@ extern MODVAR long SNO_SPAMF; extern MODVAR long SNO_OPER; #ifndef HAVE_STRLCPY -size_t strlcpy(char *dst, const char *src, size_t size); +extern size_t strlcpy(char *dst, const char *src, size_t size); #endif #ifndef HAVE_STRLCAT -size_t strlcat(char *dst, const char *src, size_t size); +extern size_t strlcat(char *dst, const char *src, size_t size); #endif #ifndef HAVE_STRLNCAT -size_t strlncat(char *dst, const char *src, size_t size, size_t n); +extern size_t strlncat(char *dst, const char *src, size_t size, size_t n); #endif - +extern char *strldup(const char *src, size_t n); extern int dopacket(aClient *, char *, int); diff --git a/src/modules/m_pass.c b/src/modules/m_pass.c index 3e796126e..1be308c42 100644 --- a/src/modules/m_pass.c +++ b/src/modules/m_pass.c @@ -114,7 +114,7 @@ ConfigItem_ban *bconf; CMD_FUNC(m_pass) { char *password = parc > 1 ? parv[1] : NULL; - int PassLen = 0; + if (BadPtr(password)) { sendto_one(cptr, err_str(ERR_NEEDMOREPARAMS), @@ -128,13 +128,8 @@ CMD_FUNC(m_pass) return 0; } - PassLen = strlen(password); - if (cptr->local->passwd) - MyFree(cptr->local->passwd); - if (PassLen > (PASSWDLEN)) - PassLen = PASSWDLEN; - cptr->local->passwd = MyMallocEx(PassLen + 1); - strlcpy(cptr->local->passwd, password, PassLen + 1); + /* Store the password */ + safestrldup(cptr->local->passwd, password, PASSWDLEN+1); /* note: the original non-truncated password is supplied as 2nd parameter. */ RunHookReturnInt2(HOOKTYPE_LOCAL_PASS, sptr, password, !=0); diff --git a/src/modules/m_topic.c b/src/modules/m_topic.c index 559f7e815..dfb1268d3 100644 --- a/src/modules/m_topic.c +++ b/src/modules/m_topic.c @@ -80,8 +80,6 @@ CMD_FUNC(m_topic) aChannel *chptr = NullChn; char *topic = NULL, *name, *tnick = NULL; TS ttime = 0; -int topiClen = 0; -int nicKlen = 0; int i = 0; Hook *h; int ismember; /* cache: IsMember() */ @@ -176,29 +174,11 @@ long flags = 0; /* cache: membership flags */ * some services do this in their topic enforcement -- codemastr */ { - /* setting a topic */ - topiClen = strlen(topic); - nicKlen = strlen(tnick); - - if (chptr->topic) - MyFree(chptr->topic); - - if (topiClen > (TOPICLEN)) - topiClen = TOPICLEN; - - if (nicKlen > (NICKLEN+USERLEN+HOSTLEN+5)) - nicKlen = (NICKLEN+USERLEN+HOSTLEN+5); - - chptr->topic = MyMallocEx(topiClen + 1); - strlcpy(chptr->topic, topic, topiClen + 1); - - if (chptr->topic_nick) - MyFree(chptr->topic_nick); - - chptr->topic_nick = MyMallocEx(nicKlen + 1); - strlcpy(chptr->topic_nick, tnick, nicKlen + 1); - + /* Set the topic */ + safestrldup(chptr->topic, topic, TOPICLEN+1); + safestrldup(chptr->topic_nick, tnick, NICKLEN+USERLEN+HOSTLEN+5); chptr->topic_time = ttime; + RunHook4(HOOKTYPE_TOPIC, cptr, sptr, chptr, topic); sendto_server(cptr, PROTO_SID, 0, ":%s TOPIC %s %s %lu :%s", ID(sptr), chptr->chname, chptr->topic_nick, @@ -279,36 +259,17 @@ long flags = 0; /* cache: membership flags */ } RunHook4(HOOKTYPE_LOCAL_TOPIC, cptr, sptr, chptr, topic); } - /* setting a topic */ - topiClen = strlen(topic); -#ifndef TOPIC_NICK_IS_NUHOST - nicKlen = strlen(sptr->name); -#else + +#ifdef TOPIC_NICK_IS_NUHOST if (IsPerson(sptr)) tnick = make_nick_user_host(sptr->name, sptr->user->username, GetHost(sptr)); else tnick = sptr->name; - nicKlen = strlen(tnick); #endif - if (chptr->topic) - MyFree(chptr->topic); + /* Set the topic */ + safestrldup(chptr->topic, topic, TOPICLEN+1); + safestrldup(chptr->topic_nick, tnick, NICKLEN+USERLEN+HOSTLEN+5); - if (topiClen > (TOPICLEN)) - topiClen = TOPICLEN; - if (nicKlen > (NICKLEN+USERLEN+HOSTLEN+5)) - nicKlen = NICKLEN+USERLEN+HOSTLEN+5; - chptr->topic = MyMallocEx(topiClen + 1); - strlcpy(chptr->topic, topic, topiClen + 1); - - if (chptr->topic_nick) - MyFree(chptr->topic_nick); - - chptr->topic_nick = MyMallocEx(nicKlen + 1); -#ifndef TOPIC_NICK_IS_NUHOST - strlcpy(chptr->topic_nick, sptr->name, nicKlen + 1); -#else - strlcpy(chptr->topic_nick, tnick, nicKlen + 1); -#endif RunHook4(HOOKTYPE_TOPIC, cptr, sptr, chptr, topic); if (ttime && IsServer(cptr)) chptr->topic_time = ttime; diff --git a/src/scache.c b/src/scache.c index c196aff19..0f0f73879 100644 --- a/src/scache.c +++ b/src/scache.c @@ -89,14 +89,14 @@ char *find_or_add(char *name) if ((ptr = scache_hash[hash_index])) { newptr = scache_hash[hash_index] = MyMallocEx(sizeof(SCACHE)); - strlcpy(newptr->name, name, HOSTLEN); + strlcpy(newptr->name, name, sizeof(newptr->name)); newptr->next = ptr; return (newptr->name); } else { ptr = scache_hash[hash_index] = MyMallocEx(sizeof(SCACHE)); - strlcpy(ptr->name, name, HOSTLEN); + strlcpy(ptr->name, name, sizeof(newptr->name)); ptr->next = (SCACHE *) NULL; return (ptr->name); } diff --git a/src/support.c b/src/support.c index d68209d2e..25d15531f 100644 --- a/src/support.c +++ b/src/support.c @@ -1269,6 +1269,36 @@ strlncat(char *dst, const char *src, size_t size, size_t n) } #endif +/* strldup(str,max) copies a string and ensures the new buffer + * is at most 'max' size, including nul byte. The syntax is pretty + * much identical to strlcpy() except that the buffer is newly + * allocated. + * If you wonder why not use strndup() instead? + * I feel that mixing code with strlcpy() and strndup() would be + * rather confusing since strlcpy() assumes buffer size including + * the nul byte and strndup() assumes without the nul byte and + * will write one character extra. Hence this strldup(). -- Syzop + */ +// WAS: #define strldup(buf, sz) (sz > 0 ? strndup(buf, sz-1) : NULL) +char *strldup(const char *src, size_t max) +{ + char *ptr; + int n; + + if ((max == 0) || !src) + return NULL; + + n = strlen(src); + if (n > max-1) + n = max-1; + + ptr = MyMallocEx(n+1); + memcpy(ptr, src, n); + ptr[n] = '\0'; + + return ptr; +} + static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; diff --git a/src/url.c b/src/url.c index 6db9d00d1..79e9c4884 100644 --- a/src/url.c +++ b/src/url.c @@ -97,12 +97,7 @@ char *url_getfilename(const char *url) if (!*c) return strdup(start); else - { - char *file = MyMallocEx(c-start+1); - strlcpy(file, start, c-start+1); - return file; - } - return strdup("-"); + return strldup(start, c-start+1); } return strdup("-");