diff -Naurp -X /home/ibr/tmp/root/prg/dontdiff.ibr gnokii.orig/common/gsm-encoding.c gnokii/common/gsm-encoding.c --- gnokii.orig/common/gsm-encoding.c 2007-01-06 21:49:37.000000000 +0100 +++ gnokii/common/gsm-encoding.c 2007-02-24 22:00:33.000000000 +0100 @@ -32,6 +32,7 @@ */ +#include #include #include #include @@ -399,19 +400,21 @@ void char_ascii_decode(unsigned char* de return; } -unsigned int char_ascii_encode(unsigned char* dest, const unsigned char* src, unsigned int len) +size_t char_ascii_encode(char *dest, size_t dest_len, + const char *src, size_t len) { - int i, j; + size_t i, j, extra = 0; - for (i = 0, j = 0; j < len; i++, j++) { + for (i = 0, j = 0; i < dest_len && j < len; i++, j++) { if (char_def_alphabet_ext(src[j])) { dest[i++] = GN_CHAR_ESCAPE; dest[i] = char_def_alphabet_ext_encode(src[j]); + extra++; } else { dest[i] = char_def_alphabet_encode(src[j]); } } - return i; + return len + extra; } /* null terminates the string */ @@ -429,28 +432,26 @@ void char_hex_decode(unsigned char* dest return; } -void char_hex_encode(unsigned char* dest, const unsigned char* src, int len) +size_t char_hex_encode(char *dest, size_t dest_len, + const char *src, size_t len) { - int i; + int i, n = dest_len / 2 >= len ? len : dest_len / 2; - for (i = 0; i < (len / 2); i++) { + for (i = 0; i < n; i++) sprintf(dest + i * 2, "%x", char_def_alphabet_encode(src[i])); - } - return; + return len * 2; } -int char_uni_alphabet_encode(unsigned char const *value, wchar_t *dest, MBSTATE *mbs) +size_t char_uni_alphabet_encode(const char *value, size_t n, wchar_t *dest, + MBSTATE *mbs) { int length; - switch (length = char_mbtowc(dest, value, MB_CUR_MAX, mbs)) { - case -1: - dprintf("Error calling mctowb!\n"); - *dest = '?'; - length = 1; - default: - return length; - } + if (n > MB_CUR_MAX) + n = MB_CUR_MAX; + length = char_mbtowc(dest, value, n, mbs); + assert(length != -1); + return length; } int char_uni_alphabet_decode(wchar_t value, unsigned char *dest, MBSTATE *mbs) @@ -499,28 +500,23 @@ void char_ucs2_decode(unsigned char* des /* * This function should convert "ABC" to "004100420043" */ -void char_ucs2_encode(unsigned char* dest, const unsigned char* src, int len) +size_t char_ucs2_encode(char *dest, size_t dest_len, + const char *src, size_t len) { wchar_t wc; - int i_len = 0, o_len, length; + int i, o_len, length; MBSTATE mbs; MBSTATE_ENC_CLEAR(mbs); - for (o_len = 0; i_len < len ; o_len++) { - switch (length = char_uni_alphabet_encode(src + i_len, &wc, &mbs)) { - case -1: - i_len++; - break; - case 0: - /* return at the end of the string */ - return; - default: - i_len += length; - break; - } - sprintf(dest + (o_len << 2), "%04lx", wc); + for (i = 0, o_len = 0; i < len && o_len < dest_len / 4; o_len++) { + length = char_uni_alphabet_encode(src + i, len - i, &wc, &mbs); + if (!length) + return i * 4; + i += length; + /* XXX: We should probably check wchar_t size. */ + sprintf(dest + (o_len << 2), "%04x", wc); } - return; + return len * 4; } /* null terminates the string */ @@ -548,7 +544,9 @@ unsigned int char_unicode_encode(unsigne MBSTATE_ENC_CLEAR(mbs); while (offset < len) { - switch (length = char_uni_alphabet_encode(src + offset, &wc, &mbs)) { + length = char_uni_alphabet_encode(src + offset, len - offset, + &wc, &mbs); + switch (length) { case -1: dest[pos++] = wc >> 8 & 0xFF; dest[pos++] = wc & 0xFF; diff -Naurp -X /home/ibr/tmp/root/prg/dontdiff.ibr gnokii.orig/common/phones/atgen.c gnokii/common/phones/atgen.c --- gnokii.orig/common/phones/atgen.c 2007-01-09 21:42:04.000000000 +0100 +++ gnokii/common/phones/atgen.c 2007-02-24 22:26:08.000000000 +0100 @@ -36,6 +36,7 @@ */ +#include #include #include #include @@ -271,26 +272,29 @@ static gn_error Functions(gn_operation o } /* Functions to encode and decode strings */ -int at_encode(int charset, char *dst, char *src, int len) +size_t at_encode(at_charset charset, char *dst, size_t dst_len, + const char *src, size_t len) { + size_t ret; + switch (charset) { case AT_CHAR_GSM: - len = char_ascii_encode(dst, src, len); + ret = char_ascii_encode(dst, dst_len, src, len); break; case AT_CHAR_HEXGSM: - len *= 2; - char_hex_encode(dst, src, len); + ret = char_hex_encode(dst, dst_len, src, len); break; case AT_CHAR_UCS2: - len *= 4; - char_ucs2_encode(dst, src, len); + ret = char_ucs2_encode(dst, dst_len, src, len); break; default: - memcpy(dst, src, len); + memcpy(dst, src, dst_len >= len ? len : dst_len); + ret = len; break; } - dst[len] = '\0'; - return len; + if (ret < dst_len) + dst[ret] = '\0'; + return ++ret; } void at_decode(int charset, char *dst, char *src, int len) @@ -805,29 +809,37 @@ static gn_error AT_ReadPhonebook(gn_data static gn_error AT_WritePhonebook(gn_data *data, struct gn_statemachine *state) { at_driver_instance *drvinst = AT_DRVINST(state); - int len, ofs; - char req[256], *tmp; + int len; + char pnumber[128], name[256], req[256]; gn_error ret; ret = at_memory_type_set(data->phonebook_entry->memory_type, state); if (ret) return ret; - if (data->phonebook_entry->empty) { + if (data->phonebook_entry->empty) return AT_DeletePhonebook(data, state); - } else { - ret = state->driver.functions(GN_OP_AT_SetCharset, data, state); - if (ret) - return ret; - ofs = sprintf(req, "AT+CPBW=%d,\"%s\",%s,\"", - data->phonebook_entry->location+drvinst->memoryoffset, - data->phonebook_entry->number, - data->phonebook_entry->number[0] == '+' ? "145" : "129"); - len = strlen(data->phonebook_entry->name); - tmp = req + ofs; - len = at_encode(drvinst->charset, tmp, data->phonebook_entry->name, len); - tmp[len++] = '"'; tmp[len++] = '\r'; - len += ofs; - } + + ret = state->driver.functions(GN_OP_AT_SetCharset, data, state); + if (ret) + return ret; + + len = at_encode(drvinst->charset, pnumber, sizeof pnumber, + data->phonebook_entry->number, + strlen(data->phonebook_entry->number)); + assert(len <= sizeof pnumber); + + len = at_encode(drvinst->charset, name, sizeof name, + data->phonebook_entry->name, + strlen(data->phonebook_entry->name)); + assert(len <= sizeof name); + + len = snprintf(req, sizeof req, "AT+CPBW=%d,\"%s\",%s,\"%s\"\r", + data->phonebook_entry->location+drvinst->memoryoffset, + pnumber, + data->phonebook_entry->number[0] == '+' ? "145" : "129", + name); + assert(len <= sizeof req); + if (sm_message_send(len, GN_OP_WritePhonebook, req, state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_WritePhonebook, data, state); diff -Naurp -X /home/ibr/tmp/root/prg/dontdiff.ibr gnokii.orig/common/phones/atsoer.c gnokii/common/phones/atsoer.c --- gnokii.orig/common/phones/atsoer.c 2005-04-20 22:52:45.000000000 +0200 +++ gnokii/common/phones/atsoer.c 2007-02-24 21:58:47.000000000 +0100 @@ -30,6 +30,7 @@ */ +#include #include #include #include @@ -54,9 +55,11 @@ static gn_error se_at_memory_type_set(gn int len; char memtype[10]; - len = at_encode(drvinst->charset, memtype, memorynames[mt], strlen(memorynames[mt])); + len = at_encode(drvinst->charset, memtype, sizeof memtype, + memorynames[mt], strlen(memorynames[mt])); + assert(len <= sizeof memtype); sprintf(req, "AT+CPBS=\"%s\"\r", memtype); - ret = sm_message_send(11 + len, GN_OP_Init, req, state); + ret = sm_message_send(11 + len - 1, GN_OP_Init, req, state); if (ret) return GN_ERR_NOTREADY; gn_data_clear(&data); @@ -149,32 +152,37 @@ static gn_error AT_ReadPhonebook(gn_data static gn_error AT_WritePhonebook(gn_data *data, struct gn_statemachine *state) { at_driver_instance *drvinst = AT_DRVINST(state); - int len, ofs; - char req[256], *tmp; + int len; + char pnumber[128], name[256], req[256]; gn_error ret; ret = se_at_memory_type_set(data->phonebook_entry->memory_type, state); if (ret) return ret; - if (data->phonebook_entry->empty) { + if (data->phonebook_entry->empty) return state->driver.functions(GN_OP_DeletePhonebook, data, state); - } else { - char pnumber[128]; - ret = state->driver.functions(GN_OP_AT_SetCharset, data, state); - if (ret) - return ret; - at_encode(drvinst->charset, pnumber, data->phonebook_entry->number, strlen(data->phonebook_entry->number)); - ofs = sprintf(req, "AT+CPBW=%d,\"%s\",%s,\"", - data->phonebook_entry->location+drvinst->memoryoffset, - pnumber, - data->phonebook_entry->number[0] == '+' ? "145" : "129"); - len = strlen(data->phonebook_entry->name); - tmp = req + ofs; - len = at_encode(drvinst->charset, tmp, data->phonebook_entry->name, len); - tmp[len++] = '"'; tmp[len++] = '\r'; - len += ofs; - } + ret = state->driver.functions(GN_OP_AT_SetCharset, data, state); + if (ret) + return ret; + + len = at_encode(drvinst->charset, pnumber, sizeof pnumber, + data->phonebook_entry->number, + strlen(data->phonebook_entry->number)); + assert(len <= sizeof pnumber); + + len = at_encode(drvinst->charset, name, sizeof name, + data->phonebook_entry->name, + strlen(data->phonebook_entry->name)); + assert(len <= sizeof name); + + len = snprintf(req, sizeof req, "AT+CPBW=%d,\"%s\",%s,\"%s\"\r", + data->phonebook_entry->location+drvinst->memoryoffset, + pnumber, + data->phonebook_entry->number[0] == '+' ? "145" : "129", + name); + assert(len <= sizeof req); + if (sm_message_send(len, GN_OP_WritePhonebook, req, state)) return GN_ERR_NOTREADY; return sm_block_no_retry(GN_OP_WritePhonebook, data, state); diff -Naurp -X /home/ibr/tmp/root/prg/dontdiff.ibr gnokii.orig/common/phones/nokia.c gnokii/common/phones/nokia.c --- gnokii.orig/common/phones/nokia.c 2006-05-08 19:44:07.000000000 +0200 +++ gnokii/common/phones/nokia.c 2007-02-19 00:06:29.000000000 +0100 @@ -135,7 +135,7 @@ size_t pnok_string_encode(unsigned char MBSTATE_ENC_CLEAR(mbs); for (i = 0, j = 0; i < max && src[j]; i++, j += n) { - n = char_uni_alphabet_encode(src + j, &wch, &mbs); + n = char_uni_alphabet_encode(src + j, max - j, &wch, &mbs); dest[i] = pnok_uni_to_nokia(wch); } return i; diff -Naurp -X /home/ibr/tmp/root/prg/dontdiff.ibr gnokii.orig/include/gnokii-internal.h gnokii/include/gnokii-internal.h --- gnokii.orig/include/gnokii-internal.h 2006-08-06 22:42:21.000000000 +0200 +++ gnokii/include/gnokii-internal.h 2007-02-18 22:45:57.000000000 +0100 @@ -85,18 +85,22 @@ unsigned int char_unicode_decode(unsigne unsigned int char_unicode_encode(unsigned char* dest, const unsigned char* src, int len); void char_ascii_decode(unsigned char* dest, const unsigned char* src, int len); -unsigned int char_ascii_encode(unsigned char* dest, const unsigned char* src, unsigned int len); +size_t char_ascii_encode(char *dest, size_t dest_len, + const char *src, size_t len); void char_hex_decode(unsigned char* dest, const unsigned char* src, int len); -void char_hex_encode(unsigned char* dest, const unsigned char* src, int len); +size_t char_hex_encode(char *dest, size_t dest_len, + const char *src, size_t len); void char_ucs2_decode(unsigned char* dest, const unsigned char* src, int len); -void char_ucs2_encode(unsigned char* dest, const unsigned char* src, int len); +size_t char_ucs2_encode(char *dest, size_t dest_len, + const char *src, size_t len); unsigned char char_def_alphabet_encode(unsigned char value); unsigned char char_def_alphabet_decode(unsigned char value); -int char_uni_alphabet_encode(unsigned char const *value, wchar_t *dest, MBSTATE *mbs); +size_t char_uni_alphabet_encode(const char *value, size_t n, wchar_t *dest, + MBSTATE *mbs); int char_uni_alphabet_decode(wchar_t value, unsigned char *dest, MBSTATE *mbs); extern char *char_bcd_number_get(u8 *number); diff -Naurp -X /home/ibr/tmp/root/prg/dontdiff.ibr gnokii.orig/include/phones/atgen.h gnokii/include/phones/atgen.h --- gnokii.orig/include/phones/atgen.h 2006-01-22 21:31:11.000000000 +0100 +++ gnokii/include/phones/atgen.h 2007-02-18 22:45:57.000000000 +0100 @@ -103,7 +103,8 @@ char *findcrlf(unsigned char *str, int t char *strip_quotes(char *s); void at_decode(int charset, char *dst, char *src, int len); -int at_encode(int charset, char *dst, char *src, int len); +size_t at_encode(at_charset charset, char *dst, size_t dst_len, + const char *src, size_t len); extern char *memorynames[];