diff --git a/src/Player.cc b/src/Player.cc index 414e2253..137b9853 100644 --- a/src/Player.cc +++ b/src/Player.cc @@ -160,7 +160,7 @@ PlayerDispDataBBPreview PlayerDispDataBB::to_preview() const { pre.proportion_x = this->proportion_x; pre.proportion_y = this->proportion_y; memset(pre.name, 0, sizeof(pre.name)); - char16ncpy(pre.name, this->name, 16); + strcpy_z(pre.name, this->name, 16); pre.play_time = this->play_time; return pre; } @@ -192,7 +192,7 @@ void PlayerDispDataBB::apply_preview(const PlayerDispDataBBPreview& pre) { this->proportion_x = pre.proportion_x; this->proportion_y = pre.proportion_y; memset(this->name, 0, sizeof(this->name)); - char16ncpy(this->name, pre.name, 0x10); + strcpy_z(this->name, pre.name, 0x10); this->play_time = 0; } @@ -244,11 +244,11 @@ void Player::import(const PSOPlayerDataBB& bb) { // note: we don't copy the inventory and disp here because we already have // it (we sent the player data to the client in the first place) memset(this->info_board, 0, sizeof(this->info_board)); - char16ncpy(this->info_board, bb.info_board, 0xAC); + strcpy_z(this->info_board, bb.info_board, 0xAC); memcpy(&this->blocked, bb.blocked, sizeof(uint32_t) * 30); memset(this->auto_reply, 0, sizeof(this->auto_reply)); if (bb.auto_reply_enabled) { - char16ncpy(this->auto_reply, bb.auto_reply, 0xAC); + strcpy_z(this->auto_reply, bb.auto_reply, 0xAC); } else { this->auto_reply[0] = 0; } @@ -264,11 +264,11 @@ PlayerBB Player::export_bb_player_data() const { bb.bank = this->bank; bb.serial_number = this->serial_number; memset(bb.name, 0, sizeof(bb.name)); - char16ncpy(bb.name, this->disp.name, 24); + strcpy_z(bb.name, this->disp.name, 24); memset(bb.team_name, 0, sizeof(bb.team_name)); - char16ncpy(bb.team_name, this->team_name, 16); + strcpy_z(bb.team_name, this->team_name, 16); memset(bb.guild_card_desc, 0, sizeof(bb.guild_card_desc)); - char16ncpy(bb.guild_card_desc, this->guild_card_desc, 0x58); + strcpy_z(bb.guild_card_desc, this->guild_card_desc, 0x58); bb.reserved1 = 0; bb.reserved2 = 0; bb.section_id = this->disp.section_id; @@ -277,9 +277,9 @@ PlayerBB Player::export_bb_player_data() const { memcpy(bb.symbol_chats, this->symbol_chats, 0x04E0); memcpy(bb.shortcuts, this->shortcuts, 0x0A40); memset(bb.auto_reply, 0, sizeof(bb.auto_reply)); - char16ncpy(bb.auto_reply, this->auto_reply, 0xAC); + strcpy_z(bb.auto_reply, this->auto_reply, 0xAC); memset(bb.info_board, 0, sizeof(bb.info_board)); - char16ncpy(bb.info_board, this->info_board, 0xAC); + strcpy_z(bb.info_board, this->info_board, 0xAC); memset(bb.unknown5, 0, 0x1C); memcpy(bb.challenge_data, this->challenge_data, 0x0140); memcpy(bb.tech_menu_config, this->tech_menu_config, 0x0028); @@ -323,7 +323,7 @@ void Player::load_account_data(const string& filename) { memcpy(&this->shortcuts, &account.shortcuts, 0x0A40); memcpy(&this->symbol_chats, &account.symbol_chats, 0x04E0); memset(this->team_name, 0, sizeof(this->team_name)); - char16ncpy(this->team_name, account.team_name, 16); + strcpy_z(this->team_name, account.team_name, 16); } void Player::save_account_data(const string& filename) const { @@ -337,7 +337,7 @@ void Player::save_account_data(const string& filename) const { memcpy(&account.shortcuts, &this->shortcuts, 0x0A40); memcpy(&account.symbol_chats, &this->symbol_chats, 0x04E0); memset(account.team_name, 0, sizeof(account.team_name)); - char16ncpy(account.team_name, this->team_name, 16); + strcpy_z(account.team_name, this->team_name, 16); save_file(filename, &account, sizeof(account)); } @@ -350,14 +350,14 @@ void Player::load_player_data(const string& filename) { } memset(this->auto_reply, 0, sizeof(this->auto_reply)); - char16ncpy(this->auto_reply, player.auto_reply, 0xAC); + strcpy_z(this->auto_reply, player.auto_reply, 0xAC); this->bank = player.bank; memcpy(&this->challenge_data, &player.challenge_data, 0x0140); this->disp = player.disp; memset(this->guild_card_desc, 0, sizeof(this->guild_card_desc)); - char16ncpy(this->guild_card_desc, player.guild_card_desc, 0x58); + strcpy_z(this->guild_card_desc, player.guild_card_desc, 0x58); memset(this->info_board, 0, sizeof(this->info_board)); - char16ncpy(this->info_board, player.info_board, 0xAC); + strcpy_z(this->info_board, player.info_board, 0xAC); this->inventory = player.inventory; memcpy(&this->quest_data1, &player.quest_data1, 0x0208); memcpy(&this->quest_data2, &player.quest_data2, 0x0058); @@ -370,14 +370,14 @@ void Player::save_player_data(const string& filename) const { strncpy(player.signature, PLAYER_FILE_SIGNATURE, sizeof(player.signature)); player.preview = this->disp.to_preview(); memset(player.auto_reply, 0, sizeof(player.auto_reply)); - char16ncpy(player.auto_reply, this->auto_reply, 0xAC); + strcpy_z(player.auto_reply, this->auto_reply, 0xAC); player.bank = this->bank; memcpy(&player.challenge_data, &this->challenge_data, 0x0140); player.disp = this->disp; memset(player.guild_card_desc, 0, sizeof(player.guild_card_desc)); - char16ncpy(player.guild_card_desc,this->guild_card_desc, 0x58); + strcpy_z(player.guild_card_desc,this->guild_card_desc, 0x58); memset(player.info_board, 0, sizeof(player.info_board)); - char16ncpy(player.info_board, this->info_board, 0xAC); + strcpy_z(player.info_board, this->info_board, 0xAC); player.inventory = this->inventory; memcpy(&player.quest_data1, &this->quest_data1, 0x0208); memcpy(&player.quest_data2, &this->quest_data2, 0x0058); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index ba00d4fd..781f4cb5 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -775,7 +775,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, if (data.size() > sizeof(C_MenuSelection)) { if (uses_unicode) { size_t max_chars = (data.size() - sizeof(C_MenuSelection)) / sizeof(char16_t); - char16ncpy(password, cmd.password.pcbb, + strcpy_z(password, cmd.password.pcbb, min(max_chars, countof(password))); } else { size_t max_chars = (data.size() - sizeof(C_MenuSelection)) / sizeof(char); @@ -1501,8 +1501,8 @@ shared_ptr create_game_generic(shared_ptr s, } shared_ptr game(new Lobby()); - char16ncpy(game->name, name, countof(game->name)); - char16ncpy(game->password, password, countof(game->name)); + strcpy_z(game->name, name, countof(game->name)); + strcpy_z(game->password, password, countof(game->name)); game->version = c->version; game->section_id = c->override_section_id >= 0 ? c->override_section_id : c->player.disp.section_id; diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 54809309..8bc90088 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -638,11 +638,11 @@ void send_guild_card_bb(shared_ptr c, shared_ptr source) { cmd.reserved2 = 1; cmd.serial_number = source->license->serial_number; - char16ncpy(cmd.name, source->player.disp.name, countof(cmd.name)); + strcpy_z(cmd.name, source->player.disp.name, countof(cmd.name)); remove_language_marker_inplace(cmd.name); - char16ncpy(cmd.team_name, source->player.team_name, countof(cmd.team_name)); + strcpy_z(cmd.team_name, source->player.team_name, countof(cmd.team_name)); remove_language_marker_inplace(cmd.team_name); - char16ncpy(cmd.desc, source->player.guild_card_desc, countof(cmd.desc)); + strcpy_z(cmd.desc, source->player.guild_card_desc, countof(cmd.desc)); cmd.section_id = source->player.disp.section_id; cmd.char_class = source->player.disp.char_class; diff --git a/src/ServerState.cc b/src/ServerState.cc index ffe70f55..41e2a1ce 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -33,7 +33,7 @@ ServerState::ServerState() (is_ep3_only ? LobbyFlag::EPISODE_3 : 0); l->block = x + 1; l->type = x; - char16ncpy(l->name, lobby_name.c_str(), 0x24); + strcpy_z(l->name, lobby_name.c_str(), 0x24); l->max_clients = 12; this->add_lobby(l); diff --git a/src/Text.cc b/src/Text.cc index 3c005d71..fcb1b52c 100644 --- a/src/Text.cc +++ b/src/Text.cc @@ -30,16 +30,6 @@ int char16ncmp(const char16_t* s1, const char16_t* s2, size_t count) { return 0; } -void char16ncpy(char16_t* dest, const char16_t* src, size_t count) { - size_t x; - for (x = 0; x < count && src[x] != 0; x++) { - dest[x] = src[x]; - } - if (x < count) { - dest[x] = 0; - } -} - size_t char16len(const char16_t* s) { size_t x; for (x = 0; s[x] != 0; x++); @@ -209,7 +199,7 @@ void remove_language_marker_inplace(char* a) { void remove_language_marker_inplace(char16_t* a) { if ((a[0] == '\t') && (a[1] != 'C')) { - char16ncpy(a, &a[2], char16len(a) - 2); + strcpy_z(a, &a[2], char16len(a) - 2); } } diff --git a/src/Text.hh b/src/Text.hh index d7cc99d0..be8a90c1 100644 --- a/src/Text.hh +++ b/src/Text.hh @@ -15,7 +15,6 @@ int char16ncmp(const char16_t* s1, const char16_t* s2, size_t count); -void char16ncpy(char16_t* dest, const char16_t* src, size_t count); size_t char16len(const char16_t* s); void encode_sjis(char* dest, const char16_t* source, size_t dest_count); @@ -27,6 +26,19 @@ std::u16string decode_sjis(const std::string& source); +// Like strncpy, but *always* null-terminates the string, even if it has to +// truncate it. +template +void strcpy_z(T* dest, const T* src, size_t count) { + size_t x; + for (x = 0; x < count - 1 && src[x] != 0; x++) { + dest[x] = src[x]; + } + dest[x] = 0; +} + + + template void strncpy_t(DestT*, const SrcT*, size_t) { static_assert(always_false::v, @@ -35,7 +47,7 @@ void strncpy_t(DestT*, const SrcT*, size_t) { template <> inline void strncpy_t(char* dest, const char* src, size_t count) { - strncpy(dest, src, count); + strcpy_z(dest, src, count); } template <> @@ -50,7 +62,7 @@ inline void strncpy_t(char16_t* dest, const char* src, size_t co template <> inline void strncpy_t(char16_t* dest, const char16_t* src, size_t count) { - char16ncpy(dest, src, count); + strcpy_z(dest, src, count); }