| File: | rootdir/src/utils/aLinkCreator/src/ed2khash.cpp |
| Warning: | line 114, column 15 Potential leak of memory pointed to by 'tmpCharHash' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | //////////////////////////////////////////////////////////////////////////////// | ||||
| 2 | /// Name: Ed2kHash Class | ||||
| 3 | /// | ||||
| 4 | /// Purpose: aMule ed2k link creator | ||||
| 5 | /// | ||||
| 6 | /// Author: ThePolish <thepolish@vipmail.ru> | ||||
| 7 | /// | ||||
| 8 | /// Copyright (c) 2004-2011 ThePolish ( thepolish@vipmail.ru ) | ||||
| 9 | /// | ||||
| 10 | /// Copyright (c) 2004-2011 Marcelo Roberto Jimenez ( phoenix@amule.org ) | ||||
| 11 | /// | ||||
| 12 | /// This program is free software; you can redistribute it and/or modify | ||||
| 13 | /// it under the terms of the GNU General Public License as published by | ||||
| 14 | /// the Free Software Foundation; either version 2 of the License, or | ||||
| 15 | /// (at your option) any later version. | ||||
| 16 | /// | ||||
| 17 | /// This program is distributed in the hope that it will be useful, | ||||
| 18 | /// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| 19 | /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| 20 | /// GNU General Public License for more details. | ||||
| 21 | /// | ||||
| 22 | /// You should have received a copy of the GNU General Public License | ||||
| 23 | /// along with this program; if not, write to the | ||||
| 24 | /// Free Software Foundation, Inc., | ||||
| 25 | /// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | ||||
| 26 | //////////////////////////////////////////////////////////////////////////////// | ||||
| 27 | |||||
| 28 | |||||
| 29 | #include <wx/ffile.h> | ||||
| 30 | #include <wx/log.h> | ||||
| 31 | #include <wx/regex.h> | ||||
| 32 | |||||
| 33 | #include "ed2khash.h" | ||||
| 34 | |||||
| 35 | |||||
| 36 | /// Constructor | ||||
| 37 | Ed2kHash::Ed2kHash():MD4() | ||||
| 38 | { | ||||
| 39 | m_ed2kArrayOfHashes.Clear(); | ||||
| 40 | m_filename.Clear(); | ||||
| 41 | m_fileSize=0; | ||||
| 42 | } | ||||
| 43 | |||||
| 44 | /// Destructor | ||||
| 45 | Ed2kHash::~Ed2kHash() | ||||
| 46 | {} | ||||
| 47 | |||||
| 48 | /// Set Ed2k hash from a file | ||||
| 49 | // returns false if aborted | ||||
| 50 | bool Ed2kHash::SetED2KHashFromFile(const wxFileName& filename, MD4Hook hook) | ||||
| 51 | { | ||||
| 52 | // Open file and let wxFFile destructor close the file | ||||
| 53 | // Closing it explicitly may crash on Win32 ... | ||||
| 54 | wxFFile file(filename.GetFullPath(), wxT("rbS")L"rbS"); | ||||
| 55 | if (! file.IsOpened()) | ||||
| 56 | { | ||||
| 57 | // This doesn't make much sense to me, but it is what it was before and actually works. | ||||
| 58 | wxLogErrorfor ( bool wxdoif58 = false; !wxdoif58 && wxLog::IsLevelEnabled (wxLOG_Error, wxString::FromAscii(wxLOG_COMPONENT)); wxdoif58 = true ) wxLogger(wxLOG_Error, "ed2khash.cpp", 58, __FUNCTION__ , wxLOG_COMPONENT).Log(_("Unable to open %s")wxGetTranslation(("Unable to open %s")), ((const char*)filename.GetFullPath().mb_str(wxConvISO8859_1wxGet_wxConvISO8859_1()))); | ||||
| 59 | return (false); | ||||
| 60 | } | ||||
| 61 | else | ||||
| 62 | { | ||||
| 63 | unsigned char ret[MD4_HASHLEN_BYTE]; | ||||
| 64 | MD4Context hdc; | ||||
| 65 | |||||
| 66 | size_t read; | ||||
| 67 | size_t partcount; | ||||
| 68 | wxFileOffset totalread; | ||||
| 69 | |||||
| 70 | char *buf = new char[BUFSIZE]; | ||||
| 71 | |||||
| 72 | bool goAhead = true; | ||||
| 73 | |||||
| 74 | #ifdef WANT_STRING_IMPLEMENTATION | ||||
| 75 | |||||
| 76 | wxString tmpHash(wxEmptyString); | ||||
| 77 | #else | ||||
| 78 | |||||
| 79 | unsigned char* tmpCharHash = NULL__null; | ||||
| 80 | #endif | ||||
| 81 | // Clear Ed2k Hash | ||||
| 82 | m_ed2kArrayOfHashes.Clear(); | ||||
| 83 | |||||
| 84 | // Processing each block | ||||
| 85 | totalread=0; | ||||
| 86 | partcount = 0; | ||||
| 87 | while (!file.Eof()) | ||||
| 88 | { | ||||
| 89 | size_t dataread = 0; | ||||
| 90 | MD4Init(&hdc); | ||||
| 91 | while (dataread
| ||||
| 92 | { | ||||
| 93 | if (hook) | ||||
| 94 | { | ||||
| 95 | goAhead = hook((int)((double)(100.0 * totalread) / file.Length())); | ||||
| 96 | } | ||||
| 97 | if (goAhead) | ||||
| 98 | { | ||||
| 99 | if ((dataread + BUFSIZE) > PARTSIZE) | ||||
| 100 | { | ||||
| 101 | read = file.Read(buf, PARTSIZE - dataread); | ||||
| 102 | } | ||||
| 103 | else | ||||
| 104 | { | ||||
| 105 | read = file.Read(buf, BUFSIZE); | ||||
| 106 | } | ||||
| 107 | dataread += read; | ||||
| 108 | totalread += read; | ||||
| 109 | MD4Update(&hdc, reinterpret_cast<unsigned char const *>(buf), | ||||
| 110 | read); | ||||
| 111 | } | ||||
| 112 | else | ||||
| 113 | { | ||||
| 114 | delete [] buf; | ||||
| |||||
| 115 | return (false); | ||||
| 116 | } | ||||
| 117 | |||||
| 118 | } | ||||
| 119 | MD4Final(&hdc, ret); | ||||
| 120 | |||||
| 121 | // Add part-hash | ||||
| 122 | m_ed2kArrayOfHashes.Add(charToHex(reinterpret_cast<const char *>(ret), | ||||
| 123 | MD4_HASHLEN_BYTE)); | ||||
| 124 | |||||
| 125 | partcount++; | ||||
| 126 | |||||
| 127 | #ifdef WANT_STRING_IMPLEMENTATION | ||||
| 128 | // MD4_HASHLEN_BYTE is ABSOLUTELY needed as we dont want NULL | ||||
| 129 | // character to be interpreted as the end of the parthash string | ||||
| 130 | #if wxUSE_UNICODE1 | ||||
| 131 | |||||
| 132 | tmpHash += wxString(reinterpret_cast<const wchar_t *>(ret),MD4_HASHLEN_BYTE); | ||||
| 133 | #else | ||||
| 134 | |||||
| 135 | tmpHash += wxString(reinterpret_cast<const char *>(ret),MD4_HASHLEN_BYTE); | ||||
| 136 | #endif | ||||
| 137 | #else | ||||
| 138 | |||||
| 139 | unsigned char *tmpPtr = (unsigned char*)realloc(tmpCharHash, | ||||
| 140 | sizeof(unsigned char) * (MD4_HASHLEN_BYTE * partcount)); | ||||
| 141 | if (tmpPtr) { | ||||
| 142 | tmpCharHash = tmpPtr; | ||||
| 143 | } else { | ||||
| 144 | delete [] buf; | ||||
| 145 | free(tmpCharHash); | ||||
| 146 | wxLogErrorfor ( bool wxdoif146 = false; !wxdoif146 && wxLog::IsLevelEnabled (wxLOG_Error, wxString::FromAscii(wxLOG_COMPONENT)); wxdoif146 = true ) wxLogger(wxLOG_Error, "ed2khash.cpp", 146, __FUNCTION__ , wxLOG_COMPONENT).Log(_("Out of memory while calculating ed2k hash!")wxGetTranslation(("Out of memory while calculating ed2k hash!" ))); | ||||
| 147 | return (false); | ||||
| 148 | } | ||||
| 149 | memcpy ( tmpCharHash + MD4_HASHLEN_BYTE * (partcount - 1), ret, MD4_HASHLEN_BYTE ); | ||||
| 150 | #endif | ||||
| 151 | |||||
| 152 | } | ||||
| 153 | |||||
| 154 | delete [] buf; | ||||
| 155 | |||||
| 156 | // hash == hash of concatenned parthashes | ||||
| 157 | if (partcount > 1) | ||||
| 158 | { | ||||
| 159 | wxString finalHash; | ||||
| 160 | |||||
| 161 | #ifdef WANT_STRING_IMPLEMENTATION | ||||
| 162 | |||||
| 163 | finalHash=calcMd4FromString(tmpHash); | ||||
| 164 | #else | ||||
| 165 | |||||
| 166 | MD4Init(&hdc); | ||||
| 167 | MD4Update(&hdc, tmpCharHash, MD4_HASHLEN_BYTE * partcount); | ||||
| 168 | MD4Final(&hdc, ret); | ||||
| 169 | |||||
| 170 | finalHash = charToHex(reinterpret_cast<const char *>(ret), | ||||
| 171 | MD4_HASHLEN_BYTE); | ||||
| 172 | #endif | ||||
| 173 | |||||
| 174 | m_ed2kArrayOfHashes.Add(finalHash); | ||||
| 175 | } | ||||
| 176 | |||||
| 177 | #ifndef WANT_STRING_IMPLEMENTATION | ||||
| 178 | free(tmpCharHash); | ||||
| 179 | tmpCharHash=NULL__null; | ||||
| 180 | #endif | ||||
| 181 | |||||
| 182 | m_ed2kArrayOfHashes.Shrink(); | ||||
| 183 | |||||
| 184 | // Set members | ||||
| 185 | m_fileSize = file.Length(); | ||||
| 186 | m_filename = filename.GetFullName(); | ||||
| 187 | |||||
| 188 | return true; | ||||
| 189 | } | ||||
| 190 | } | ||||
| 191 | |||||
| 192 | /// Set Ed2k hash from a file | ||||
| 193 | bool Ed2kHash::SetED2KHashFromFile(const wxString& filename, MD4Hook hook) | ||||
| 194 | { | ||||
| 195 | return SetED2KHashFromFile(wxFileName(filename), hook); | ||||
| |||||
| 196 | } | ||||
| 197 | |||||
| 198 | #define WXLONGLONGFMTSPECL"ll" wxT(wxLongLongFmtSpec)L"ll" | ||||
| 199 | |||||
| 200 | /// Get Ed2k link | ||||
| 201 | wxString Ed2kHash::GetED2KLink(const bool addPartHashes, const wxArrayString* arrayOfUrls) | ||||
| 202 | { | ||||
| 203 | // Constructing ed2k basic link | ||||
| 204 | wxString ed2kLink = wxT("ed2k://|file|")L"ed2k://|file|" + CleanFilename(m_filename) | ||||
| 205 | + wxString::Format(wxT("|%")L"|%" WXLONGLONGFMTSPECL"ll" wxT("u|")L"u|", m_fileSize) | ||||
| 206 | + m_ed2kArrayOfHashes.Last() + wxT("|")L"|"; | ||||
| 207 | |||||
| 208 | |||||
| 209 | // Add optional URLs | ||||
| 210 | if ( arrayOfUrls && !arrayOfUrls->IsEmpty()) | ||||
| 211 | { | ||||
| 212 | size_t i; | ||||
| 213 | for ( i = 0; i < arrayOfUrls->GetCount(); i++ ) | ||||
| 214 | { | ||||
| 215 | ed2kLink += wxT("s=")L"s=" + (*arrayOfUrls)[i] + wxT("|")L"|"; | ||||
| 216 | } | ||||
| 217 | } | ||||
| 218 | |||||
| 219 | // Add Optional part-hashes | ||||
| 220 | if (addPartHashes && m_ed2kArrayOfHashes.GetCount()>1) | ||||
| 221 | { | ||||
| 222 | ed2kLink += wxT("p=")L"p="; | ||||
| 223 | size_t i; | ||||
| 224 | for (i=0;i<(m_ed2kArrayOfHashes.GetCount()-1);++i) | ||||
| 225 | { | ||||
| 226 | ed2kLink += m_ed2kArrayOfHashes[i] + wxT(":")L":"; | ||||
| 227 | } | ||||
| 228 | ed2kLink.RemoveLast(); // Remove last : | ||||
| 229 | ed2kLink += wxT("|")L"|"; | ||||
| 230 | } | ||||
| 231 | |||||
| 232 | // Add last slash | ||||
| 233 | ed2kLink += wxT("/")L"/"; | ||||
| 234 | |||||
| 235 | return ed2kLink; | ||||
| 236 | } | ||||
| 237 | |||||
| 238 | /// Strip all non-alphanumeric characters of a filename string | ||||
| 239 | wxString Ed2kHash::CleanFilename(const wxString& filename) | ||||
| 240 | { | ||||
| 241 | wxString name(filename); | ||||
| 242 | |||||
| 243 | wxRegEx toStrip(wxT("[^[:alnum:]_.-]")L"[^[:alnum:]_.-]"); | ||||
| 244 | toStrip.Replace(&name, wxT("_")L"_"); | ||||
| 245 | |||||
| 246 | return (name); | ||||
| 247 | } | ||||
| 248 | |||||
| 249 | /// Get Ed2k Array of hashes | ||||
| 250 | wxArrayString Ed2kHash::GetED2KHash() | ||||
| 251 | { | ||||
| 252 | return (m_ed2kArrayOfHashes); | ||||
| 253 | } | ||||
| 254 | // File_checked_for_headers |