From: Steven S. <ste...@gm...> - 2007-12-18 03:11:18
|
Credit goes to Stanislav Maslovski. Here's his original argument for it: Consider a client operating in active mode. In order to get a filelist NmdcHub::connectToMe() first places the triplet (( peerNick, myNick, hubUrl )) on the list of expected connections. Internally, nicks are stored in utf-8. Note that peerNick in this triplet gets stored also in utf-8. Next, NmdcHub::connectToMe() sends "$ConnectToMe " + toAcp(peerNick) + .... So far so good. Now the peer connects. ConnectionManager::accept() creates new UserConnection, sets flags, etc. but because it does not know anything about peer's encoding (the new connection can be from an arbitrary user from arbitrary hub) it leaves it with the default (which is Text::systemCharset). Now peer sends $MyNick peerNick_in_acp UserConnection::on() receives this, blindly translates peerNick_in_acp to utf-8 from the encoding associated with the connection (which is Text::systemCharset at the moment). If peer's encoding was different we get an obvious result: the connection is rejected in ConnectionManager::on(MyNick) because the translation fails and the peer is not found in the list of expected connections. Here goes an example session (text below contains russian chars): NmdcHub::connect Трельник NmdcHub::connectToMe Трельник BufferedSocket::accept() 0x86d2a00 BufferedSocket::run() start 0x86d2a00 ConnectionManager::onMyNick 0x86974e0, ________ Unknown incoming connection from ________ BufferedSocket::run() end 0x86d2a00 In this example, the system locale was ru_RU.UTF-8, but the hub charset was CP1251. If someone thinks that setting locale to CP1251 will solve the problem, then it is not so, because there always will be hubs with different encodings and we want linuxdcpp operate _simultaneously_ on all of them. The attached patch solves this in the following way. First, the peer nick is stored on the list of expected connections in ACP, not in uft-8. This is not a problem, because the stored nick is just a key and is not used for any other purpose. Next, when UserConnection::on() receives $MyNick it is passed further untranslated. Peer's nick gets translated to utf-8 later inside ConnectionManager::on(MyNick) when it becomes possible to determine and set the correct encoding. This all can be seen directly from the patch, of course. Perhaps, a better way of doing things could be to separate incomming connection checking from ConnectionManager::on(MyNick) and put it in UserConnection::on() or do something similar. |