static int parse_utf_16(char **processed, char **unprocessed) { unsigned int cp, lead, trail; char *processed_ptr = *processed; char *unprocessed_ptr = *unprocessed; unprocessed_ptr++; /* skips u */ if (!is_utf((const unsigned char*)unprocessed_ptr) || sscanf(unprocessed_ptr, "%4x", &cp) == EOF) return ERROR; if (cp < 0x80) { *processed_ptr = cp; /* 0xxxxxxx */ } else if (cp < 0x800) { *processed_ptr++ = ((cp >> 6) & 0x1F) | 0xC0; /* 110xxxxx */ *processed_ptr = ((cp ) & 0x3F) | 0x80; /* 10xxxxxx */ } else if (cp < 0xD800 || cp > 0xDFFF) {
/* Returns contents of a string inside double quotes and parses escaped characters inside. Example: "\u006Corem ipsum" -> lorem ipsum */ static const char * get_processed_string(const char **string) { const char *string_start = *string; char *output, *processed_ptr, *unprocessed_ptr, current_char; unsigned int utf_val; skip_quotes(string); if (**string == '\0') { return NULL; } output = parson_strndup(string_start + 1, *string - string_start - 2); if (!output) { return NULL; } processed_ptr = unprocessed_ptr = output; while (*unprocessed_ptr) { current_char = *unprocessed_ptr; if (current_char == '\\') { unprocessed_ptr++; current_char = *unprocessed_ptr; switch (current_char) { case '\"': case '\\': case '/': break; case 'b': current_char = '\b'; break; case 'f': current_char = '\f'; break; case 'n': current_char = '\n'; break; case 'r': current_char = '\r'; break; case 't': current_char = '\t'; break; case 'u': unprocessed_ptr++; if (!is_utf((const unsigned char*)unprocessed_ptr) || sscanf(unprocessed_ptr, "%4x", &utf_val) == EOF) { parson_free(output); return NULL; } if (utf_val < 0x80) { current_char = utf_val; } else if (utf_val < 0x800) { *processed_ptr++ = (utf_val >> 6) | 0xC0; current_char = ((utf_val | 0x80) & 0xBF); } else { *processed_ptr++ = (utf_val >> 12) | 0xE0; *processed_ptr++ = (((utf_val >> 6) | 0x80) & 0xBF); current_char = ((utf_val | 0x80) & 0xBF); } unprocessed_ptr += 3; break; default: parson_free(output); return NULL; break; }
static const char * parse_escaped_characters(const char *string) { char *output_string = (char*)parson_malloc(strlen(string) + 1); char *output_string_ptr = output_string; const char *string_ptr = string; char current_char; unsigned int utf_val; void *reallocated_ptr; if (!output_string) { return NULL; } while (*string_ptr) { current_char = *string_ptr; if (current_char == '\\') { string_ptr++; current_char = *string_ptr; switch (current_char) { case '\"': case '\\': case '/': break; case 'b': current_char = '\b'; break; case 'f': current_char = '\f'; break; case 'n': current_char = '\n'; break; case 'r': current_char = '\r'; break; case 't': current_char = '\t'; break; case 'u': string_ptr++; if (!is_utf(string_ptr) || sscanf(string_ptr, "%4x", &utf_val) == EOF) { parson_free(output_string); return NULL; } if (utf_val < 0x80) { current_char = utf_val; } else if (utf_val < 0x800) { *output_string_ptr++ = (utf_val >> 6) | 0xC0; current_char = ((utf_val | 0x80) & 0xBF); } else { *output_string_ptr++ = (utf_val >> 12) | 0xE0; *output_string_ptr++ = (((utf_val >> 6) | 0x80) & 0xBF); current_char = ((utf_val | 0x80) & 0xBF); } string_ptr += 3; break; default: parson_free(output_string); return NULL; break; }
// // 日本語文字コードの判定 // // 各コードの判定でtrueの間は文字数分繰り返されるので // 速度の求められる繰り返し処理などで使わない事 // int MISC::judge_char_code( const std::string& str ) { int code = CHARCODE_UNKNOWN; if( str.empty() ) return code; size_t read_byte = 0; // JISの判定 if( is_jis( str.c_str(), read_byte ) ) code = CHARCODE_JIS; // JISの判定で最後まで進んでいたら制御文字かアスキー else if( read_byte == str.length() ) code = CHARCODE_ASCII; // UTF-8の範囲 else if( is_utf( str.c_str(), read_byte ) ) code = CHARCODE_UTF; // EUC-JPの範囲 else if( is_euc( str.c_str(), read_byte ) ) code = CHARCODE_EUC_JP; // Shift_JISの範囲 else if( is_sjis( str.c_str(), read_byte ) ) code = CHARCODE_SJIS; return code; }
// used when requesting a regular file transfer int CAimProto::aim_send_file(HANDLE hServerConn, unsigned short &seqno, unsigned long ip, unsigned short port, bool force_proxy, file_transfer *ft) { char msg_frag[2048]; unsigned short frag_offset = 0; aim_writeshort(0, frag_offset, msg_frag); // request type aim_writegeneric(8, ft->icbm_cookie, frag_offset, msg_frag); // icbm cookie aim_writegeneric(AIM_CAPS_LENGTH, AIM_CAP_FILE_TRANSFER, frag_offset, msg_frag); // uuid aim_writetlvshort(0x0a, ++ft->req_num, frag_offset, msg_frag); // request number aim_writetlvlong(0x02, ip, frag_offset, msg_frag); // ip aim_writetlvlong(0x16, ~ip, frag_offset, msg_frag); // ip check aim_writetlvshort(0x05, port, frag_offset, msg_frag); // port aim_writetlvshort(0x17, ~port, frag_offset, msg_frag); // port ip check if (force_proxy) aim_writetlv(0x10, 0, 0, frag_offset, msg_frag); // request proxy transfer else aim_writetlvlong(0x03, m_internal_ip, frag_offset, msg_frag); // ip if (ft->req_num == 1) { if (ft->message) { aimString dscr(ft->message); const char* charset = dscr.isUnicode() ? "unicode-2-0" : "us-ascii"; const unsigned short charset_len = (unsigned short)mir_strlen(charset); const char* desc_msg = dscr.getBuf(); const unsigned short desc_len = dscr.getSize(); aim_writetlv(0x0e, 2, "en", frag_offset, msg_frag); // language used by the data aim_writetlv(0x0d, charset_len, charset, frag_offset, msg_frag);// charset used by the data aim_writetlv(0x0c, desc_len, desc_msg, frag_offset, msg_frag); // invitaion text } aim_writetlv(0x0f, 0, 0, frag_offset, msg_frag); // request host check const char* fname = get_fname(ft->file); const unsigned short fnlen = (unsigned short)mir_strlen(fname); char* fblock = (char*)alloca(9 + fnlen); *(unsigned short*)&fblock[0] = _htons(ft->pfts.totalFiles > 1 ? 2 : 1); // single file transfer *(unsigned short*)&fblock[2] = _htons(ft->pfts.totalFiles); // number of files *(unsigned long*)&fblock[4] = _htonl(ft->pfts.totalBytes); // total bytes in files memcpy(&fblock[8], fname, fnlen + 1); const char* enc = is_utf(fname) ? "utf-8" : "us-ascii"; aim_writetlv(0x2711, 9 + fnlen, fblock, frag_offset, msg_frag); // extra data, file names, size aim_writetlv(0x2712, 8, enc, frag_offset, msg_frag); // character set used by data // aim_writetlvlong64(0x2713,ft->pfts.totalBytes,frag_offset,msg_frag); // file length debugLogA("Attempting to Send a file to a buddy."); } else { aim_writetlvshort(0x14, 0x0a, frag_offset, msg_frag); // Counter proposal reason } unsigned short offset = 0; unsigned short sn_length = (unsigned short)mir_strlen(ft->sn); char* buf = (char*)alloca(SNAC_SIZE + TLV_HEADER_SIZE * 2 + 12 + frag_offset + sn_length); aim_writesnac(0x04, 0x06, offset, buf); // msg to host aim_writegeneric(8, ft->icbm_cookie, offset, buf); // icbm cookie aim_writeshort(2, offset, buf); // icbm channel aim_writechar((unsigned char)sn_length, offset, buf); // screen name length aim_writegeneric(sn_length, ft->sn, offset, buf); // screen name aim_writetlv(0x05, frag_offset, msg_frag, offset, buf); // icbm tags aim_writetlv(0x03, 0, 0, offset, buf); // request ack char cip[20]; long_ip_to_char_ip(ip, cip); debugLogA("IP for Buddy to connect to: %s:%u", cip, port); return aim_sendflap(hServerConn, 0x02, offset, buf, seqno) == 0; }