author | Michael Krelin <hacker@klever.net> | 2007-12-30 19:04:48 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2008-01-04 18:22:27 (UTC) |
commit | 4b75ac58aa9baaf611df8ef694fd585529823c66 (patch) (side-by-side diff) | |
tree | e337b2419bf5825b4b774a4284f7de64e2a179e0 | |
parent | 9020dcc4b8187a9dd31c62dbe89041772b0f5473 (diff) | |
download | libopkele-4b75ac58aa9baaf611df8ef694fd585529823c66.zip libopkele-4b75ac58aa9baaf611df8ef694fd585529823c66.tar.gz libopkele-4b75ac58aa9baaf611df8ef694fd585529823c66.tar.bz2 |
fix to rfc normalization
It kept prepending a '/' to the trailing segment even if the segment was past
[?#]
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | lib/util.cc | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/lib/util.cc b/lib/util.cc index ee75d29..a9b9bed 100644 --- a/lib/util.cc +++ b/lib/util.cc @@ -212,104 +212,105 @@ namespace opkele { rv.append(uri,colon+1,ul-colon-1); return rv; } rv += "//"; string::size_type interesting = uri.find_first_of(":/#?",colon+3); if(interesting==string::npos) { transform( uri.begin()+colon+3,uri.begin()+ul, back_inserter(rv), ::tolower ); rv += '/'; return rv; } transform( uri.begin()+colon+3,uri.begin()+interesting, back_inserter(rv), ::tolower ); bool qf = false; char ic = uri[interesting]; if(ic==':') { string::size_type ni = uri.find_first_of("/#?%",interesting+1); const char *nptr = uri.data()+interesting+1; char *eptr = 0; long port = strtol(nptr,&eptr,10); if( (port>0) && (port<65535) && port!=(s?443:80) ) { char tmp[8]; snprintf(tmp,sizeof(tmp),":%ld",port); rv += tmp; } if(ni==string::npos) { rv += '/'; return rv; } interesting = ni; }else if(ic!='/') { rv += '/'; rv += ic; qf = true; ++interesting; } string::size_type n = interesting; char tmp[3] = { 0,0,0 }; stack<string::size_type> psegs; psegs.push(rv.length()); string pseg; for(;n<ul;) { string::size_type unsafe = uri.find_first_of(qf?"%":"%/?#",n); if(unsafe==string::npos) { pseg.append(uri,n,ul-n-1); n = ul-1; }else{ pseg.append(uri,n,unsafe-n); n = unsafe; } char c = uri[n++]; if(c=='%') { if((n+1)>=ul) throw bad_input(OPKELE_CP_ "Unexpected end of URI encountered while parsing percent-encoded character"); tmp[0] = uri[n++]; tmp[1] = uri[n++]; if(!( isxdigit(tmp[0]) && isxdigit(tmp[1]) )) throw bad_input(OPKELE_CP_ "Invalid percent-encoded character in URI being normalized"); int cc = strtol(tmp,0,16); if( isalpha(cc) || isdigit(cc) || strchr("._~-",cc) ) pseg += cc; else{ pseg += '%'; pseg += toupper(tmp[0]); pseg += toupper(tmp[1]); } }else if(qf) { rv += pseg; rv += c; pseg.clear(); }else if(n>=ul || strchr("?/#",c)) { if(pseg.empty() || pseg==".") { }else if(pseg=="..") { if(psegs.size()>1) { rv.resize(psegs.top()); psegs.pop(); } }else{ psegs.push(rv.length()); if(c!='/') { pseg += c; qf = true; } rv += '/'; rv += pseg; } if(c=='/' && (n>=ul || strchr("?#",uri[n])) ) { rv += '/'; if(n<ul) qf = true; }else if(strchr("?#",c)) { if(psegs.size()==1 && psegs.top()==rv.length()) rv += '/'; if(pseg.empty()) rv += c; qf = true; } pseg.clear(); }else{ pseg += c; } } if(!pseg.empty()) { - rv += '/'; rv += pseg; + if(!qf) rv += '/'; + rv += pseg; } return rv; } } } |