From bf667e7e9c45b0b0c3787c1023c3b0f6de284cd8 Mon Sep 17 00:00:00 2001 From: erin_yueh Date: Wed, 13 Feb 2008 03:48:28 +0000 Subject: gsmd: add strlcpy, strlcat functions (Paulius Zaleckas) git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@4060 99fdad57-331a-0410-800a-d7fa5415bdb3 --- src/gsmd/Makefile.am | 2 +- src/gsmd/atcmd.c | 2 +- src/gsmd/ext_response.c | 6 +--- src/gsmd/gsmd.c | 2 +- src/gsmd/operator_cache.c | 2 +- src/gsmd/strl.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ src/gsmd/usock.c | 43 +++++++++++++----------- src/gsmd/vendor_ti.c | 4 +-- src/gsmd/vendor_tihtc.c | 4 +-- 9 files changed, 118 insertions(+), 33 deletions(-) create mode 100644 src/gsmd/strl.c (limited to 'src') diff --git a/src/gsmd/Makefile.am b/src/gsmd/Makefile.am index cd83b83..01d6a8d 100644 --- a/src/gsmd/Makefile.am +++ b/src/gsmd/Makefile.am @@ -18,7 +18,7 @@ sbin_PROGRAMS = gsmd gsmd_CFLAGS = -D PLUGINDIR=\"$(plugindir)\" gsmd_SOURCES = gsmd.c atcmd.c select.c machine.c vendor.c unsolicited.c log.c \ usock.c talloc.c timer.c operator_cache.c ext_response.c \ - sms_cb.c sms_pdu.c + sms_cb.c sms_pdu.c strl.c gsmd_LDADD = -ldl gsmd_LDFLAGS = -Wl,--export-dynamic diff --git a/src/gsmd/atcmd.c b/src/gsmd/atcmd.c index 8d71268..51c1722 100644 --- a/src/gsmd/atcmd.c +++ b/src/gsmd/atcmd.c @@ -619,7 +619,7 @@ struct gsmd_atcmd *atcmd_fill(const char *cmd, int rlen, atcmd->cb = cb; atcmd->resp = NULL; atcmd->timeout = NULL; - strncpy(atcmd->buf, cmd, buflen-1); + strlcpy(atcmd->buf, cmd, buflen); if (!ct) atcmd->create_timer_func = discard_timer; diff --git a/src/gsmd/ext_response.c b/src/gsmd/ext_response.c index e8b2ab3..0736b6e 100644 --- a/src/gsmd/ext_response.c +++ b/src/gsmd/ext_response.c @@ -122,12 +122,8 @@ struct gsm_extrsp *extrsp_parse(const void *ctx, const char *input) break; case TOKEN_STRING: if (*cur == '"') { - int len = strlen(buf); - if (len > sizeof(cur_token->u.string)-1) - len = sizeof(cur_token->u.string)-1; - /* end of string token */ - strncpy(cur_token->u.string, buf, len); + strlcpy(cur_token->u.string, buf, GSM_EXTRSP_MAX_STRBUF); er->num_tokens++; state = TOKEN_STRING_LASTQUOTE; } else { diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c index c11e59f..af6c4a3 100644 --- a/src/gsmd/gsmd.c +++ b/src/gsmd/gsmd.c @@ -152,7 +152,7 @@ static int gsmd_get_imsi_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) struct gsmd *g = ctx; DEBUGP("imsi : %s\n", resp); - strcpy(g->imsi, resp); + strlcpy(g->imsi, resp, sizeof(g->imsi)); return 0; } diff --git a/src/gsmd/operator_cache.c b/src/gsmd/operator_cache.c index e680706..e37310c 100644 --- a/src/gsmd/operator_cache.c +++ b/src/gsmd/operator_cache.c @@ -82,7 +82,7 @@ int gsmd_opname_add(struct gsmd *g, const char *numeric_bcd_string, strncpy(mcc, numeric_bcd_string, 3); strncpy(mnc, numeric_bcd_string+3, 2); - strncpy(op->alnum_long, alnum_long, sizeof(op->alnum_long-1)); + strlcpy(op->alnum_long, alnum_long, sizeof(op->alnum_long)); op->numeric.mcc = atoi(mcc); op->numeric.mnc = atoi(mnc); diff --git a/src/gsmd/strl.c b/src/gsmd/strl.c new file mode 100644 index 0000000..cf20ef0 --- /dev/null +++ b/src/gsmd/strl.c @@ -0,0 +1,86 @@ +/* safe strcpy and strcat versions + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright (C) 2008 by Paulius Zaleckas, JSC Teltonika + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include "gsmd.h" +#include + +/** + * strlcpy - Copy a %NUL terminated string into a sized buffer + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @size: size of destination buffer + * + * Compatible with *BSD: the result is always a valid + * NUL-terminated string that fits in the buffer (unless, + * of course, the buffer size is zero). It does not pad + * out the result like strncpy() does. + */ +size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len; + if (ret >= size) { + len = size - 1; + DEBUGP("\"%s\" was truncated by %i characters\n", src, + ret - len); + } + else + len = ret; + memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} + +/** + * strlcat - Append a length-limited, %NUL-terminated string to another + * @dest: The string to be appended to + * @src: The string to append to it + * @count: The size of the destination buffer. + */ +size_t strlcat(char *dest, const char *src, size_t count) +{ + size_t dsize = strlen(dest); + size_t len = strlen(src); + size_t res = dsize + len; + + /* This would be a bug */ + if (dsize >= count) { + DEBUGP("Length of destination string > provided buffer size!\n"); + return 0; + } + + dest += dsize; + count -= dsize; + if (len >= count) { + len = count - 1; + DEBUGP("\"%s\" was truncated by %i characters\n", src, + res - len); + } + memcpy(dest, src, len); + dest[len] = 0; + return res; +} + diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 0faef65..c9f549d 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -160,7 +160,7 @@ static int voicecall_get_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) gcs.stat = er->tokens[2].u.numeric; gcs.mode = er->tokens[3].u.numeric; gcs.mpty = er->tokens[4].u.numeric; - strcpy(gcs.number, er->tokens[5].u.string); + strlcpy(gcs.number, er->tokens[5].u.string, GSMD_ADDR_MAXLEN+1); gcs.type = er->tokens[6].u.numeric; } else if ( er->num_tokens == 8 && @@ -186,9 +186,9 @@ static int voicecall_get_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) gcs.stat = er->tokens[2].u.numeric; gcs.mode = er->tokens[3].u.numeric; gcs.mpty = er->tokens[4].u.numeric; - strcpy(gcs.number, er->tokens[5].u.string); + strlcpy(gcs.number, er->tokens[5].u.string, GSMD_ADDR_MAXLEN+1); gcs.type = er->tokens[6].u.numeric; - strncpy(gcs.alpha, er->tokens[7].u.string, 8+1); + strlcpy(gcs.alpha, er->tokens[7].u.string, GSMD_ALPHA_MAXLEN+1); } else { DEBUGP("Invalid Input : Parse error\n"); @@ -257,7 +257,7 @@ static int voicecall_fwd_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) gcfs.status = er->tokens[0].u.numeric; gcfs.classx = er->tokens[1].u.numeric; - strcpy(gcfs.addr.number, er->tokens[2].u.string); + strlcpy(gcfs.addr.number, er->tokens[2].u.string, GSMD_ADDR_MAXLEN+1); gcfs.addr.type = er->tokens[3].u.numeric; } else if ( er->num_tokens == 7 && @@ -271,7 +271,7 @@ static int voicecall_fwd_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) gcfs.status = er->tokens[0].u.numeric; gcfs.classx = er->tokens[1].u.numeric; - strcpy(gcfs.addr.number, er->tokens[2].u.string); + strlcpy(gcfs.addr.number, er->tokens[2].u.string, GSMD_ADDR_MAXLEN+1); gcfs.addr.type = er->tokens[3].u.numeric; gcfs.time = er->tokens[6].u.numeric; } @@ -560,18 +560,18 @@ static int usock_rcv_pin(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, if (!cmd) return -ENOMEM; - strncat(cmd->buf, gp->pin, sizeof(gp->pin)); + strlcat(cmd->buf, gp->pin, cmd->buflen); switch (gp->type) { case GSMD_PIN_SIM_PUK: case GSMD_PIN_SIM_PUK2: - strcat(cmd->buf, "\",\""); - strncat(cmd->buf, gp->newpin, sizeof(gp->newpin)); + strlcat(cmd->buf, "\",\"", cmd->buflen); + strlcat(cmd->buf, gp->newpin, cmd->buflen); break; default: break; } - strcat(cmd->buf, "\""); + strlcat(cmd->buf, "\"", cmd->buflen); break; case GSMD_PIN_GET_STATUS: cmd = atcmd_fill("AT+CPIN?", 8 + 1, &get_cpin_cb, gu, 0, NULL); @@ -718,7 +718,7 @@ static int network_vmail_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) er->tokens[1].type == GSMD_ECMD_RTT_STRING && er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC) { vmail.enable = er->tokens[0].u.numeric; - strcpy(vmail.addr.number, er->tokens[1].u.string); + strlcpy(vmail.addr.number, er->tokens[1].u.string, GSMD_ADDR_MAXLEN+1); vmail.addr.type = er->tokens[2].u.numeric; } rc = gsmd_ucmd_submit(gu, GSMD_MSG_NETWORK, GSMD_NETWORK_VMAIL_GET, @@ -824,7 +824,7 @@ static int network_oper_n_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) er->tokens[2].type == GSMD_ECMD_RTT_STRING ) { - strcpy(buf, er->tokens[2].u.string); + strlcpy(buf, er->tokens[2].u.string, sizeof(buf)); } else { DEBUGP("Invalid Input : Parse error\n"); @@ -896,9 +896,12 @@ static int network_opers_parse(const char *str, struct gsmd_msg_oper **out) */ out2->stat = er->tokens[0].u.numeric; - strcpy(out2->opname_longalpha, er->tokens[1].u.string); - strcpy(out2->opname_shortalpha, er->tokens[2].u.string); - strcpy(out2->opname_num, er->tokens[3].u.string); + strlcpy(out2->opname_longalpha, er->tokens[1].u.string, + sizeof(out2->opname_longalpha)); + strlcpy(out2->opname_shortalpha, er->tokens[2].u.string, + sizeof(out2->opname_shortalpha)); + strlcpy(out2->opname_num, er->tokens[3].u.string, + sizeof(out2->opname_num)); } else { DEBUGP("Invalid Input : Parse error\n"); @@ -1131,9 +1134,9 @@ static int phonebook_find_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) */ gps.pb.index = er->tokens[0].u.numeric; - strcpy(gps.pb.numb, er->tokens[1].u.string); + strlcpy(gps.pb.numb, er->tokens[1].u.string, GSMD_PB_NUMB_MAXLEN+1); gps.pb.type = er->tokens[2].u.numeric; - strcpy(gps.pb.text, er->tokens[3].u.string); + strlcpy(gps.pb.text, er->tokens[3].u.string, GSMD_PB_TEXT_MAXLEN+1); } else { DEBUGP("Invalid Input : Parse error\n"); @@ -1180,9 +1183,9 @@ static int phonebook_read_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) */ gp.index = er->tokens[0].u.numeric; - strcpy(gp.numb, er->tokens[1].u.string); + strlcpy(gp.numb, er->tokens[1].u.string, GSMD_PB_NUMB_MAXLEN+1); gp.type = er->tokens[2].u.numeric; - strcpy(gp.text, er->tokens[3].u.string); + strlcpy(gp.text, er->tokens[3].u.string, GSMD_PB_TEXT_MAXLEN+1); } else { DEBUGP("Invalid Input : Parse error\n"); @@ -1231,9 +1234,9 @@ static int phonebook_readrg_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) */ gps.pb.index = er->tokens[0].u.numeric; - strcpy(gps.pb.numb, er->tokens[1].u.string); + strlcpy(gps.pb.numb, er->tokens[1].u.string, GSMD_PB_NUMB_MAXLEN+1); gps.pb.type = er->tokens[2].u.numeric; - strcpy(gps.pb.text, er->tokens[3].u.string); + strlcpy(gps.pb.text, er->tokens[3].u.string, GSMD_PB_TEXT_MAXLEN+1); } else { DEBUGP("Invalid Input : Parse error\n"); diff --git a/src/gsmd/vendor_ti.c b/src/gsmd/vendor_ti.c index 219f23e..5c27c23 100644 --- a/src/gsmd/vendor_ti.c +++ b/src/gsmd/vendor_ti.c @@ -68,7 +68,7 @@ static int cpri_parse(const char *buf, int len, const char *param, struct gsmd * char *tok1, *tok2; char tx_buf[20]; - strcpy(tx_buf, buf); + strlcpy(tx_buf, buf, sizeof(tx_buf)); tok1 = strtok(tx_buf, ","); if (!tok1) return -EIO; @@ -122,7 +122,7 @@ static int cpi_parse(const char *buf, int len, const char *param, struct gsmd *g sizeof(*aux)); char tx_buf[64]; - strcpy(tx_buf, buf); + strlcpy(tx_buf, buf, sizeof(tx_buf)); DEBUGP("entering cpi_parse param=`%s'\n", param); if (!ucmd) return -EINVAL; diff --git a/src/gsmd/vendor_tihtc.c b/src/gsmd/vendor_tihtc.c index b7c284c..cf2a3c2 100644 --- a/src/gsmd/vendor_tihtc.c +++ b/src/gsmd/vendor_tihtc.c @@ -85,7 +85,7 @@ static int cpri_parse(const char *buf, int len, const char *param, struct gsmd * char *tok1, *tok2; char tx_buf[20]; - strcpy(tx_buf, buf); + strlcpy(tx_buf, buf, sizeof(tx_buf)); tok1 = strtok(tx_buf, ","); if (!tok1) return -EIO; @@ -132,7 +132,7 @@ static int cpi_parse(const char *buf, int len, const char *param, struct gsmd *g sizeof(*aux)); char tx_buf[64]; - strcpy(tx_buf, buf); + strlcpy(tx_buf, buf, sizeof(tx_buf)); DEBUGP("entering cpi_parse param=`%s'\n", param); if (!ucmd) return -EINVAL; -- cgit v1.2.3