From c21aa27e623ba9b8e5b3cabbae1f3593154e433f Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Tue, 31 May 2016 14:49:52 +0200 Subject: [PATCH] URL encoding/decoding added API level changed to 13 --- MSIBuild/Makefile | 10 +- build/wxExtend.props | 2 +- build/wxExtend.vcxproj | 2 + build/wxExtend.vcxproj.filters | 6 + include/wxex/common.h | 8 +- include/wxex/hex.h | 4 + include/wxex/url.h | 221 +++++++++++++++++++++++++++++++++ include/wxex/xml.h | 3 +- src/stdafx.h | 1 + src/url.cpp | 134 ++++++++++++++++++++ 10 files changed, 380 insertions(+), 11 deletions(-) create mode 100644 include/wxex/url.h create mode 100644 src/url.cpp diff --git a/MSIBuild/Makefile b/MSIBuild/Makefile index 3a92362..5f41e88 100644 --- a/MSIBuild/Makefile +++ b/MSIBuild/Makefile @@ -79,22 +79,22 @@ s$(MSIBUILD_LENGTH_ID) s$(MSIBUILD_LENGTH_ID) l255 i4 S$(MSIBUILD_LENGTH_ID) S20 File File !IF "$(PLAT)" == "Win32" !IF "$(CFG)" == "Release" -filewxExtend.dll.Win32 compwxExtend.dll.Win32 WXEXTE~2.DLL|wxExtend12u_vc100.dll 0 0 1536 1 +filewxExtend.dll.Win32 compwxExtend.dll.Win32 WXEXTE~2.DLL|wxExtend13u_vc100.dll 0 0 1536 1 !ENDIF !IF "$(CFG)" == "Debug" -filewxExtend.dll.Win32 compwxExtend.dll.Win32 WXEXTE~4.DLL|wxExtend12ud_vc100.dll 0 0 1536 1 +filewxExtend.dll.Win32 compwxExtend.dll.Win32 WXEXTE~4.DLL|wxExtend13ud_vc100.dll 0 0 1536 1 !ENDIF !ENDIF !IF "$(PLAT)" == "x64" !IF "$(CFG)" == "Release" -filewxExtend.dll.x64 compwxExtend.dll.x64 WXEXTE~6.DLL|wxExtend12u_vc100_x64.dll 0 0 1536 1 +filewxExtend.dll.x64 compwxExtend.dll.x64 WXEXTE~6.DLL|wxExtend13u_vc100_x64.dll 0 0 1536 1 !ENDIF !IF "$(CFG)" == "Debug" -filewxExtend.dll.x64 compwxExtend.dll.x64 WXEXTE~8.DLL|wxExtend12ud_vc100_x64.dll 0 0 1536 1 +filewxExtend.dll.x64 compwxExtend.dll.x64 WXEXTE~8.DLL|wxExtend13ud_vc100_x64.dll 0 0 1536 1 !ENDIF !ENDIF !IF "$(LANG)" == "Sl" -filewxExtend.mo.sl_SI compwxExtend.mo.sl_SI WXEXTE~1.MO|wxExtend12.mo 0 1060 0 1 +filewxExtend.mo.sl_SI compwxExtend.mo.sl_SI WXEXTE~1.MO|wxExtend13.mo 0 1060 0 1 !ENDIF < - 12 + 13 ..\..\..\output\$(Platform).$(Configuration)\ diff --git a/build/wxExtend.vcxproj b/build/wxExtend.vcxproj index 258afee..ee46a19 100644 --- a/build/wxExtend.vcxproj +++ b/build/wxExtend.vcxproj @@ -29,6 +29,7 @@ Create Create + @@ -40,6 +41,7 @@ + diff --git a/build/wxExtend.vcxproj.filters b/build/wxExtend.vcxproj.filters index d843440..3c471d8 100644 --- a/build/wxExtend.vcxproj.filters +++ b/build/wxExtend.vcxproj.filters @@ -43,6 +43,9 @@ Source Files + + Source Files + @@ -75,6 +78,9 @@ Header Files + + Header Files + diff --git a/include/wxex/common.h b/include/wxex/common.h index d4335c0..8fa76bb 100644 --- a/include/wxex/common.h +++ b/include/wxex/common.h @@ -23,17 +23,17 @@ /// /// wxExtend Version /// -#define wxEXTEND_VERSION 0x01020000 +#define wxEXTEND_VERSION 0x01030000 #define wxEXTEND_VERSION_MAJ 1 -#define wxEXTEND_VERSION_MIN 2 +#define wxEXTEND_VERSION_MIN 3 #define wxEXTEND_VERSION_REV 0 #define wxEXTEND_VERSION_BUILD 0 -#define wxEXTEND_VERSION_STR "1.2" +#define wxEXTEND_VERSION_STR "1.3" #define wxEXTEND_BUILD_YEAR_STR "2016" -#define wxExtendVersion "12" +#define wxExtendVersion "13" #if !defined(RC_INVOKED) && !defined(MIDL_PASS) diff --git a/include/wxex/hex.h b/include/wxex/hex.h index fe5549f..15ccb40 100644 --- a/include/wxex/hex.h +++ b/include/wxex/hex.h @@ -19,6 +19,8 @@ #pragma once +#include "common.h" + #include "wx/string.h" #include "wx/buffer.h" @@ -32,6 +34,7 @@ /// of a buffer of given length /// /// \param[in] len Length of the buffer +/// /// \returns Maximum encoded representation size (in characters) /// inline size_t wxHexEncodedSize(size_t len) @@ -110,6 +113,7 @@ enum wxHexDecodeMode /// length /// /// \param[in] len Length of the hex encoded string +/// /// \returns Maximum decoded representation size (in bytes) /// inline size_t wxHexDecodedSize(size_t len) diff --git a/include/wxex/url.h b/include/wxex/url.h new file mode 100644 index 0000000..9aedc1a --- /dev/null +++ b/include/wxex/url.h @@ -0,0 +1,221 @@ +/* + Copyright 2015-2016 Amebis + + This file is part of wxExtend. + + wxExtend is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + wxExtend is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with wxExtend. If not, see . +*/ + +#pragma once + +#include "common.h" + +#include "wx/string.h" +#include "wx/buffer.h" + + +/// +/// Return if given character should be protected for URL encoding +/// +/// \param[in] chr ASCII character +/// +/// \returns +/// - \c true if character should be protected +/// - \c false otherwise +/// +inline bool wxURLIsProtected(char chr) +{ + switch (chr) { + case ' ': + case '!': + case '*': + case '\'': + case '(': + case ')': + case ';': + case ':': + case '@': + case '&': + case '=': + case '+': + case '$': + case ',': + case '/': + case '?': + case '#': + case '[': + case ']': return true; + } + + return chr < 0x20; +} + + +/// +/// Return the size needed for the buffer containing the encoded representation +/// of a string of given length +/// +/// \param[in] src Source string to encode +/// \param[in] srcLen Length of \p src string (in bytes) +/// +/// \returns Maximum encoded representation size (in characters) +/// +inline size_t wxURLEncodedSize(size_t len) +{ + return len*3; +} + + +/// +/// Raw URL encoding function which encodes the contents of a string of the +/// specified length into the buffer of the specified size +/// +/// \param[out] dst Destination buffer to receive URL encoded data +/// \param[in] dstLen Length of \p dst buffer (in characters) +/// \param[in] src Source string to encode +/// \param[in] srcLen Length of \p src string (in bytes) +/// +/// \returns The length of the encoded data or wxCONV_FAILED if the buffer is not +/// large enough; to determine the needed size you can either allocate a buffer +/// of \c{wxURLEncodedSize(srcLen)} size or call the function with NULL string in +/// which case the required size will be returned +/// +size_t WXEXTEND_API wxURLEncode(char *dst, size_t dstLen, const char *src, size_t srcLen); + + +/// +/// URL encoding function which encodes the contents of a string of the +/// specified length into the wxString +/// +/// \param[in] src Source string to encode +/// \param[in] srcLen Length of \p src string (in bytes) +/// +/// \returns The URL encoded string +/// +inline wxString wxURLEncode(const char *src, size_t srcLen) +{ + const size_t dstLen = wxURLEncodedSize(srcLen); + wxCharBuffer dst(dstLen); + dst.shrink(wxURLEncode(dst.data(), dstLen, src, srcLen)); + + return dst; +} + + +/// +/// URL encoding function which encodes the contents of a string into the wxString +/// +/// \param[in] str Source string to encode +/// +/// \returns The URL encoded string +/// +inline wxString wxURLEncode(const wxString& str) +{ + return wxURLEncode(str.GetData(), str.Length()); +} + + +/// +/// URL encoding function which encodes the contents of a buffer into the wxString +/// +/// \param[in] buf Source buffer to encode +/// +/// \returns The URL encoded string +/// +inline wxString wxURLEncode(const wxMemoryBuffer& buf) +{ + return wxURLEncode((const char*)buf.GetData(), buf.GetDataLen()); +} + + +// ---------------------------------------------------------------------------- +// Decoding Functions +// ---------------------------------------------------------------------------- + +/// +/// Return the buffer size necessary for decoding a URL string of the given +/// length +/// +/// \param[in] len Length of the URL encoded string +/// +/// \returns Maximum decoded representation size (in bytes) +/// +inline size_t wxURLDecodedSize(size_t len) +{ + return len; +} + +/// +/// Raw decoding function which decodes the contents of the string of specified +/// length (or zero terminated by default) into the provided buffer of the given +/// size +/// +/// \param[out] dst Destination buffer to receive decoded data +/// \param[in] dstLen Length of \p dst buffer (in bytes) +/// \param[in] src Source buffer to decode +/// \param[in] srcLen Length of \p src buffer (in characters) or wxNO_LEN for zero terminated strings +/// +/// \returns The length of the decoded data or wxCONV_FAILED if the buffer is not +/// large enough; to determine the needed size you can either allocate a buffer +/// of \c{wxURLDecodedSize(srcLen)} size or call the function with NULL string in +/// which case the required size will be returned +/// +size_t WXEXTEND_API wxURLDecode(char *dst, size_t dstLen, const char *src, size_t srcLen = wxNO_LEN); + + +/// +/// Decoding function which decodes the contents of the string into the provided buffer of the given size +/// +/// \param[out] dst Destination buffer to receive decoded data +/// \param[in] dstLen Length of \p dst buffer (in bytes) +/// \param[in] src Source string to decode +/// +/// \returns The length of the decoded data or wxCONV_FAILED if the buffer is not +/// large enough; to determine the needed size you can either allocate a buffer +/// of \c{wxURLDecodedSize(srcLen)} size or call the function with NULL string in +/// which case the required size will be returned +/// +inline size_t wxURLDecode(char *dst, size_t dstLen, const wxString& src) +{ + // don't use str.length() here as the ASCII buffer is shorter than it is for + // strings with embedded NULs + return wxURLDecode(dst, dstLen, src.ToAscii(), wxNO_LEN); +} + + +/// +/// Decoding function which decodes the contents of the string of specified +/// length (or zero terminated by default) into the buffer +/// +/// \param[in] src Source buffer to decode +/// \param[in] srcLen Length of \p src buffer (in characters) or wxNO_LEN for zero terminated strings +/// +/// \returns Destination buffer with decoded data or an empty buffer if an error occured during decoding +/// +wxMemoryBuffer WXEXTEND_API wxURLDecode(const char *src, size_t srcLen = wxNO_LEN); + + +/// +/// Decoding function which decodes the contents of the string into the buffer +/// +/// \param[in] src Source string to decode +/// +/// \returns Destination buffer with decoded data or an empty buffer if an error occured during decoding +/// +inline wxMemoryBuffer wxURLDecode(const wxString& src) +{ + // don't use str.length() here as the ASCII buffer is shorter than it for + // strings with embedded NULs + return wxURLDecode(src.ToAscii(), wxNO_LEN); +} diff --git a/include/wxex/xml.h b/include/wxex/xml.h index 10d03f4..7322e21 100644 --- a/include/wxex/xml.h +++ b/include/wxex/xml.h @@ -19,9 +19,10 @@ #pragma once -#include "crypto.h" #include "common.h" +#include "crypto.h" + #include #include diff --git a/src/stdafx.h b/src/stdafx.h index e823ab8..18cfab5 100644 --- a/src/stdafx.h +++ b/src/stdafx.h @@ -27,6 +27,7 @@ #include "../include/wxex/comutils.h" #include "../include/wxex/crypto.h" #include "../include/wxex/hex.h" +#include "../include/wxex/url.h" #include "../include/wxex/valhex.h" #include "../include/wxex/xml.h" diff --git a/src/url.cpp b/src/url.cpp new file mode 100644 index 0000000..a71a230 --- /dev/null +++ b/src/url.cpp @@ -0,0 +1,134 @@ +/* + Copyright 2015-2016 Amebis + + This file is part of wxExtend. + + wxExtend is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + wxExtend is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with wxExtend. If not, see . +*/ + +#include "stdafx.h" + + +size_t WXEXTEND_API wxURLEncode(char *dst, size_t dstLen, const char *src, size_t srcLen) +{ + wxCHECK_MSG(src, wxCONV_FAILED, wxT("NULL input buffer")); + + static const char bhex[] = "0123456789ABCDEF"; + + size_t encLen = 0; + + for (size_t i = 0; i < srcLen && src[i]; i++) { + if (wxURLIsProtected(src[i])) { + encLen += 3; + if ( dst ) + { + if ( encLen > dstLen ) + return wxCONV_FAILED; + + *dst++ = '%'; + *dst++ = bhex[((unsigned char)src[i]) >> 4]; + *dst++ = bhex[((unsigned char)src[i]) & 0x0f]; + } + } else { + encLen ++; + if ( dst ) + { + if ( encLen > dstLen ) + return wxCONV_FAILED; + + *dst++ = src[i]; + } + } + } + + // Zero terminate. + if ( dst && encLen < dstLen ) + *dst++ = 0; + + return encLen; +} + + +size_t WXEXTEND_API wxURLDecode(char *dst, size_t dstLen, const char *src, size_t srcLen) +{ + wxCHECK_MSG(src, wxCONV_FAILED, wxT("NULL input buffer")); + + static const char bhex[] = "0123456789ABCDEF"; + + size_t i, decLen = 0; + + for (i = 0 ; i < srcLen && src[i];) { + decLen ++; + if (src[i] == '%') { + // Decode % escaped hex value to character. + char c = 0; + size_t j = i + 1; + for (size_t j_max = i + 3; j < j_max && j < srcLen; j++) { + char x = src[j]; + c <<= 4; + if ('0' <= x && x <= '9') c += x - '0'; + else if ('A' <= x && x <= 'F') c += x - 'A' + 10; + else if ('a' <= x && x <= 'f') c += x - 'a' + 10; + else break; + } + + if (c) { + if ( dst ) + { + if ( decLen > dstLen ) + return wxCONV_FAILED; + + *dst++ = c; + } + + i = j; + continue; + } + } + + if ( dst ) + { + if ( decLen > dstLen ) + return wxCONV_FAILED; + + *dst++ = src[i]; + } + i++; + } + + // Zero terminate. + if ( dst && decLen < dstLen ) + *dst++ = 0; + + return decLen; +} + + +wxMemoryBuffer WXEXTEND_API wxURLDecode(const char *src, size_t srcLen) +{ + wxMemoryBuffer buf; + wxCHECK_MSG( src, buf, wxT("NULL input buffer") ); + + if ( srcLen == wxNO_LEN ) + srcLen = strlen(src); + + size_t len = wxURLDecodedSize(srcLen); + len = wxURLDecode((char*)buf.GetWriteBuf(len), len, src, srcLen); + if ( len == wxCONV_FAILED ) + len = 0; + + buf.SetDataLen(len); + + return buf; +}