diff --git a/calc.c b/calc.c index 65299f6..576b6dd 100644 --- a/calc.c +++ b/calc.c @@ -479,7 +479,22 @@ main(int argc, char **argv) program); exit(21); } - strncpy(cmdbuf + cmdlen, cp, cplen+1); + /* + * The next statement could be: + * + * strncpy(cmdbuf + cmdlen, cp, cplen); + * + * however compilers like gcc would issue warnings such as: + * + * specified bound depends on the length of the + * source argument + * + * even though we terminate the string by setting a NUL + * byte following the copy. Therefore we call memcpy() + * instead to avoid such warnings. + */ + memcpy(cmdbuf + cmdlen, cp, cplen); + cmdbuf[newcmdlen] = '\0'; cmdlen = newcmdlen; index++; if (index < maxindex) diff --git a/file.c b/file.c index 1996f4b..fc29f50 100644 --- a/file.c +++ b/file.c @@ -50,6 +50,8 @@ #define READSIZE 1024 /* buffer size for reading */ +#define MIN(a,b) (((a) <= (b)) ? (a) : (b)) + /* * external STDIO functions */ @@ -1414,23 +1416,21 @@ z2filepos(ZVALUE zpos) #if FILEPOS_BITS == FULL_BITS /* ztofull puts the value into native byte order */ pos = ztofull(zpos); - /* on some hosts, FILEPOS is not a scalar */ - memset(&ret, 0, sizeof(FILEPOS)); - memcpy((void *)&ret, (void *)&pos, sizeof(FILEPOS)); + memset(&ret, 0, sizeof(ret)); /* on some hosts, FILEPOS is not a scalar */ + memcpy((void *)&ret, (void *)&pos, MIN(sizeof(ret), sizeof(pos))); return ret; #elif FILEPOS_BITS < FULL_BITS /* ztofull puts the value into native byte order */ pos = ztolong(zpos); - /* on some hosts, FILEPOS is not a scalar */ - memset(&ret, 0, sizeof(FILEPOS)); - memcpy((void *)&ret, (void *)&pos, sizeof(pos)); + memset(&ret, 0, sizeof(ret)); /* on some hosts, FILEPOS is not a scalar */ + memcpy((void *)&ret, (void *)&pos, MIN(sizeof(ret), sizeof(pos))); return ret; #else /* FILEPOS_BITS > FULL_BITS */ if (!zgtmaxfull(zpos)) { /* ztofull puts the value into native byte order */ pos = ztofull(zpos); - memset(&ret, 0, sizeof(FILEPOS)); - memcpy((void *)&ret, (void *)&pos, sizeof(pos)); + memset(&ret, 0, sizeof(ret)); /* on some hosts, FILEPOS is not a scalar */ + memcpy((void *)&ret, (void *)&pos, MIN(sizeof(ret), sizeof(pos))); return ret; } @@ -1439,11 +1439,12 @@ z2filepos(ZVALUE zpos) */ if (zpos.len >= FILEPOS_BITS/BASEB) { /* copy the lower FILEPOS_BITS of the ZVALUE */ - memcpy(&tmp, zpos.v, sizeof(FILEPOS)); + memset(&tmp, 0, sizeof(tmp)); /* on some hosts, FILEPOS is not a scalar */ + memcpy(&tmp, zpos.v, MIN(sizeof(tmp), FILEPOS_LEN); } else { /* copy what bits we can into the temp value */ - memset(&tmp, 0, sizeof(FILEPOS)); - memcpy(&tmp, zpos.v, zpos.len*BASEB/8); + memset(&tmp, 0, sizeof(tmp)); /* on some hosts, FILEPOS is not a scalar */ + memcpy(&tmp, zpos.v, MIN(sizeof(tmp), MIN(zpos.len*BASEB/8, FILEPOS_LEN))); } /* swap into native byte order */ SWAP_HALF_IN_FILEPOS(&ret, &tmp); diff --git a/func.c b/func.c index d29b1f1..56a1879 100644 --- a/func.c +++ b/func.c @@ -268,7 +268,22 @@ f_prompt(VALUE *vp) math_error("Cannot allocate string"); /*NOTREACHED*/ } - strncpy(newcp, cp, len+1); + /* + * The next statement could be:: + * + * strncpy(newcp, cp, len); + * + * however compilers like gcc would issue warnings such as: + * + * specified bound depends on the length of the + * source argument + * + * even though we terminate the string by setting a NUL + * byte following the copy. Therefore we call memcpy() + * instead to avoid such warnings. + */ + memcpy(newcp, cp, len); + newcp[len] = '\0'; result.v_str = makestring(newcp); return result; } @@ -7446,7 +7461,26 @@ f_cmdbuf(void) cmdbuf_len = strlen(cmdbuf); newcp = (char *)malloc(cmdbuf_len+1); - strncpy(newcp, cmdbuf, cmdbuf_len+1); + if (newcp == NULL) { + math_error("Cannot allocate string in cmdbuf"); + /*NOTREACHED*/ + } + /* + * The next statement could be:: + * + * strncpy(newcp, cmdbuf, cmdbuf_len); + * + * however compilers like gcc would issue warnings such as: + * + * specified bound depends on the length of the + * source argument + * + * even though we terminate the string by setting a NUL + * byte following the copy. Therefore we call memcpy() + * instead to avoid such warnings. + */ + memcpy(newcp, cmdbuf, cmdbuf_len); + newcp[cmdbuf_len] = '\0'; result.v_str = makestring(newcp); return result; } @@ -7624,17 +7658,35 @@ f_putenv(int count, VALUE **vals) /* convert putenv("foo","bar") into putenv("foo=bar") */ snprintf_len = vals[0]->v_str->s_len + 1 + - vals[1]->v_str->s_len + 1; + vals[1]->v_str->s_len; putenv_str = (char *)malloc(snprintf_len+1); if (putenv_str == NULL) { math_error("Cannot allocate string in putenv"); /*NOTREACHED*/ } - snprintf(putenv_str, snprintf_len, - "%s=%s", vals[0]->v_str->s_str, - vals[1]->v_str->s_str); - putenv_str[snprintf_len] = '\0'; /* paranoia */ - + /* + * The next statement could be:: + * + * snprintf(putenv_str, snprintf_len, + * "%s=%s", vals[0]->v_str->s_str, + * vals[1]->v_str->s_str); + * + * however compilers like gcc would issue warnings such as: + * + * null destination pointer + * + * even though we check that putenv_str is non-NULL + * above before using it. Therefore we call memcpy() + * twice and make an assignment instead to avoid such warnings. + */ + memcpy(putenv_str, + vals[0]->v_str->s_str, + vals[0]->v_str->s_len); + putenv_str[vals[0]->v_str->s_len] = '='; + memcpy(putenv_str + vals[0]->v_str->s_len + 1, + vals[1]->v_str->s_str, + vals[1]->v_str->s_len); + putenv_str[snprintf_len] = '\0'; } else { /* firewall */ @@ -7658,8 +7710,8 @@ f_putenv(int count, VALUE **vals) math_error("Cannot allocate string in putenv"); /*NOTREACHED*/ } - strncpy(putenv_str, vals[0]->v_str->s_str, - vals[0]->v_str->s_len + 1); + memcpy(putenv_str, vals[0]->v_str->s_str, vals[0]->v_str->s_len); + putenv_str[vals[0]->v_str->s_len] = '\0'; } /* return putenv result */ diff --git a/input.c b/input.c index c024564..8f86cec 100644 --- a/input.c +++ b/input.c @@ -442,7 +442,23 @@ homeexpand(char *name) if (fullpath == NULL) { return NULL; } - strncpy(fullpath, ent->pw_dir, fullpath_len+1); + /* + * The next statement could be: + * + * strncpy(fullpath, ent->pw_dir, fullpath_len); + * + * however compilers like gcc would issue warnings + * such as: + * + * specified bound depends on the length of the + * source argument + * + * even though we terminate the string by setting a NUL + * byte following the copy. Therefore we call memcpy() + * instead to avoid such warnings. + */ + memcpy(fullpath, ent->pw_dir, fullpath_len); + fullpath[fullpath_len] = '\0'; return fullpath; } username = (char *) malloc(after-name + 1 + 1); diff --git a/version.c b/version.c index cd64349..a52a3b5 100644 --- a/version.c +++ b/version.c @@ -131,8 +131,22 @@ version(void) fprintf(stderr, "%s: cannot malloc version string\n", program); exit(70); } - strncpy(stored_version, verbuf, len); - stored_version[len] = '\0'; /* paranoia */ + /* + * The next statement could be: + * + * strncpy(stored_version, verbuf, len); + * + * however compilers like gcc would issue warnings such as: + * + * specified bound depends on the length of the + * source argument + * + * even though we terminate the string by setting a NUL + * byte following the copy. Therefore we call memcpy() + * instead to avoid such warnings. + */ + memcpy(stored_version, verbuf, len); + stored_version[len] = '\0'; /* * return the newly malloced buffer