author | Michael Krelin <hacker@klever.net> | 2008-03-02 20:23:40 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2008-03-02 20:23:40 (UTC) |
commit | da3f84153be2a93da7ffc49af33b29b9725fac38 (patch) (side-by-side diff) | |
tree | bcacc4c38a53b70c679fa69fbf2577da2802a197 | |
parent | f47e336b569739bdde8e9add96ff2c46f97257fb (diff) | |
download | libopkele-da3f84153be2a93da7ffc49af33b29b9725fac38.zip libopkele-da3f84153be2a93da7ffc49af33b29b9725fac38.tar.gz libopkele-da3f84153be2a93da7ffc49af33b29b9725fac38.tar.bz2 |
made util::url_encode refrain from encoding unreserved chars
as per rfc 3986
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | lib/util.cc | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/lib/util.cc b/lib/util.cc index 29e6738..a6e08e2 100644 --- a/lib/util.cc +++ b/lib/util.cc @@ -1,29 +1,28 @@ #include <errno.h> #include <cassert> #include <cctype> #include <cstring> #include <vector> #include <string> #include <stack> #include <algorithm> #include <openssl/bio.h> #include <openssl/evp.h> #include <openssl/sha.h> #include <openssl/hmac.h> -#include <curl/curl.h> #include <opkele/util.h> #include <opkele/exception.h> #include <opkele/data.h> #include <opkele/debug.h> #include <config.h> #ifdef HAVE_DEMANGLE # include <cxxabi.h> #endif namespace opkele { using namespace std; namespace util { /* @@ -143,38 +142,66 @@ namespace opkele { &fraction ) != 7 ) ) throw failed_conversion(OPKELE_CP_ "failed to sscanf()"); tm_t.tm_mon--; tm_t.tm_year-=1900; time_t rv = mktime(&tm_t); if(rv==(time_t)-1) throw failed_conversion(OPKELE_CP_ "failed to mktime()"); return rv-timezone; } /* * */ + static inline bool isrfc3986unreserved(int c) { + if(c<'-') return false; + if(c<='.') return true; + if(c<'0') return false; if(c<='9') return true; + if(c<'A') return false; if(c<='Z') return true; + if(c<'_') return false; + if(c=='_') return true; + if(c<'a') return false; if(c<='z') return true; + if(c=='~') return true; + return false; + } + + struct __url_encoder : public unary_function<char,void> { + public: + string& rv; + + __url_encoder(string& r) : rv(r) { } + + result_type operator()(argument_type c) { + if(isrfc3986unreserved(c)) + rv += c; + else{ + char tmp[4]; + snprintf(tmp,sizeof(tmp),"%%%02X", + (c&0xff)); + rv += tmp; + } + } + }; + string url_encode(const string& str) { - char * t = curl_escape(str.c_str(),str.length()); - if(!t) - throw failed_conversion(OPKELE_CP_ "failed to curl_escape()"); - string rv(t); - curl_free(t); + string rv; + for_each(str.begin(),str.end(), + __url_encoder(rv)); return rv; } string attr_escape(const string& str) { static const char *unsafechars = "<>&\n\"'"; string rv; string::size_type p=0; while(true) { string::size_type us = str.find_first_of(unsafechars,p); if(us==string::npos) { if(p!=str.length()) rv.append(str,p,str.length()-p); return rv; } rv.append(str,p,us-p); rv += "&#"; |