diff options
| author | albert <[email protected]> | 2022-02-10 16:48:15 +0300 | 
|---|---|---|
| committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:48:15 +0300 | 
| commit | a817f5de12611ec73085eba17f8ec7740a46bdb7 (patch) | |
| tree | b222e5ac2e2e98872661c51ccceee5da0d291e13 /library/cpp/uri/assign.cpp | |
| parent | 9f25ef3232c288ca664ceee6c376cf64e4349a2e (diff) | |
Restoring authorship annotation for <[email protected]>. Commit 2 of 2.
Diffstat (limited to 'library/cpp/uri/assign.cpp')
| -rw-r--r-- | library/cpp/uri/assign.cpp | 160 | 
1 files changed, 80 insertions, 80 deletions
| diff --git a/library/cpp/uri/assign.cpp b/library/cpp/uri/assign.cpp index ff29afc10dd..ae9125c7274 100644 --- a/library/cpp/uri/assign.cpp +++ b/library/cpp/uri/assign.cpp @@ -1,16 +1,16 @@ -#include "uri.h"  -#include "parse.h"  +#include "uri.h" +#include "parse.h" + +#include <contrib/libs/libidn/idna.h> -#include <contrib/libs/libidn/idna.h>  -   #include <library/cpp/charset/recyr.hh> -#include <util/charset/wide.h>  -#include <util/memory/tempbuf.h>  -#include <util/string/cast.h>  -#include <util/system/yassert.h>  +#include <util/charset/wide.h> +#include <util/memory/tempbuf.h> +#include <util/string/cast.h> +#include <util/system/yassert.h>  #include <util/system/sys_alloc.h> -namespace NUri {  +namespace NUri {      TMallocPtr<char> TUri::IDNToAscii(const wchar32* idna) {          // XXX: don't use punycode_encode directly as it doesn't include          // proper stringprep and splitting on dot-equivalent characters @@ -24,21 +24,21 @@ namespace NUri {      TMallocPtr<char> TUri::IDNToAscii(const TStringBuf& host, ECharset enc) {          TTempBuf buf(sizeof(wchar32) * (1 + host.length()));          wchar32* wbuf = reinterpret_cast<wchar32*>(buf.Data()); -  +          const size_t written = NDetail::NBaseOps::Recode(host, wbuf, enc).length();          wbuf[written] = 0; -  +          return IDNToAscii(wbuf);      } -  +      TStringBuf TUri::HostToAscii(TStringBuf host, TMallocPtr<char>& buf, bool hasExtended, bool allowIDN, ECharset enc) {          TStringBuf outhost; // store the result here before returning it, to get RVO -  +          size_t buflen = 0; -  +          if (hasExtended && !allowIDN)              return outhost; // definitely can't convert -  +          // charset-recode: RFC 3986, 3.2.2, requires percent-encoded non-ASCII          // chars in reg-name to be UTF-8 so convert to UTF-8 prior to decoding          const bool recoding = CODES_UTF8 != enc && hasExtended; @@ -50,7 +50,7 @@ namespace NUri {                  return outhost;              host = TStringBuf(buf.Get(), nwr);          } -  +          // percent-decode          if (0 == buflen) {              buflen = host.length(); @@ -64,22 +64,22 @@ namespace NUri {          // check again          if (hasExtended && !allowIDN) -            return outhost;  -  +            return outhost; +          host = out.Str(); -  +          // convert to punycode if needed          if (!hasExtended) {              outhost = host;              return outhost;          } -  +          TMallocPtr<char> puny;          try {              puny = IDNToAscii(host);          } catch (const yexception& /* exc */) {          } -  +          if (!puny) {              // XXX: try user charset unless UTF8 or converted to it              if (CODES_UTF8 == enc || recoding) @@ -92,50 +92,50 @@ namespace NUri {              if (!puny)                  return outhost;          } -  +          buf = puny;          outhost = buf.Get(); -  +          return outhost; -    }  -  +    } +      TStringBuf TUri::HostToAscii(const TStringBuf& host, TMallocPtr<char>& buf, bool allowIDN, ECharset enc) {          // find what we have          long haveFlags = 0;          for (size_t i = 0; i != host.length(); ++i)              haveFlags |= TEncoder::GetFlags(host[i]).FeatFlags; -  +          // interested in encoded characters or (if IDN is allowed) extended ascii          TStringBuf outhost;          const bool haveExtended = haveFlags & FeatureEncodeExtendedASCII; -  +          if (!haveExtended || allowIDN) {              if (!haveExtended && 0 == (haveFlags & FeatureDecodeANY))                  outhost = host;              else                  outhost = HostToAscii(host, buf, haveExtended, allowIDN, enc);          } -  +          return outhost;      } -  +      static inline bool AppendField(TMemoryWriteBuffer& out, TField::EField fld, const TStringBuf& val, long flags) {          if (val.empty())              return false;          if (flags & TFeature::FeaturesAllEncoder)              TUri::ReEncodeField(out, val, fld, flags); -        else  +        else              out << val;          return true; -    }  -  +    } +      TState::EParsed TUri::AssignImpl(const TParser& parser, TScheme::EKind defscheme) {          Clear(); -  +          TState::EParsed ret = parser.State;          if (ParsedBadFormat <= ret)              return ret; -  +          const TSection& scheme = parser.Get(FieldScheme);          const TSchemeInfo& schemeInfo = SetSchemeImpl(parser.Scheme); @@ -154,9 +154,9 @@ namespace NUri {          long flags = parser.Flags.Allow;          if (convertIDN)              flags |= FeatureAllowHostIDN | FeatureCheckHost; -  +          // process non-ASCII host for punycode -  +          TMallocPtr<char> hostptr;          TStringBuf hostascii;       // empty: use host field; non-empty: ascii          bool hostConverted = false; // hostascii is empty or the original @@ -164,13 +164,13 @@ namespace NUri {          if (host.IsSet() && !FldIsSet(FieldHost)) {              const bool allowIDN = (flags & FeatureAllowHostIDN);              const TStringBuf hostbuf = host.Get(); -  +              // if we know we have and allow extended-ASCII chars, no need to check further              if (allowIDN && (host.GetFlagsAllPlaintext() & FeatureEncodeExtendedASCII))                  hostascii = HostToAscii(hostbuf, hostptr, true, true, parser.Enc);              else                  hostascii = HostToAscii(hostbuf, hostptr, allowIDN, parser.Enc); -  +              if (hostascii.empty())                  ret = ParsedBadHost; // exists but cannot be converted              else if (hostbuf.data() != hostascii.data()) { @@ -180,21 +180,21 @@ namespace NUri {                      FldMarkSet(FieldHost); // so that we don't process host below              }          } -  +          // add unprocessed fields -  +          for (int idx = 0; idx < FieldUrlMAX; ++idx) {              const EField fld = EField(idx);              const TSection& section = parser.Get(fld);              if (section.IsSet() && !FldIsSet(fld))                  buflen += 1 + section.EncodedLen(); // includes null -        }  +        }          if (0 == buflen) // no more sections set?              return ret; -  +          // process #! fragments          // https://developers.google.com/webmasters/ajax-crawling/docs/specification -  +          static const TStringBuf escFragPrefix(TStringBuf("_escaped_fragment_="));          bool encHashBangFrag = false; @@ -203,7 +203,7 @@ namespace NUri {          do {              if (FldIsSet(FieldFrag) || FldIsSet(FieldQuery))                  break; -  +              const TSection& frag = parser.Get(FieldFrag);              if (frag.IsSet()) {                  if (0 == (parser.Flags & FeatureHashBangToEscapedFragment)) @@ -232,33 +232,33 @@ namespace NUri {                  buflen -= escFragPrefix.length();              }          } while (false); -  +          // now set all fields prior to validating -  +          Alloc(buflen); -  +          TMemoryWriteBuffer out(Buffer.data(), Buffer.size());          for (int idx = 0; idx < FieldUrlMAX; ++idx) {              const EField fld = EField(idx); -  +              const TSection& section = parser.Get(fld);              if (!section.IsSet() || FldIsSet(fld))                  continue; -  +              if (FieldQuery == fld && encHashBangFrag)                  continue; -  +              if (FieldFrag == fld && qryEscapedFragment.IsInited())                  continue;              char* beg = out.Buf();              TStringBuf val = section.Get();              long careFlags = section.GetFlagsEncode(); -  +              switch (fld) {                  default:                      break; -  +                  case FieldQuery:                      if (qryEscapedFragment.IsInited()) {                          const EField dstfld = FieldFrag; // that's where we will store @@ -273,7 +273,7 @@ namespace NUri {                          val = qryBeforeEscapedFragment;                      }                      break; -  +                  case FieldFrag:                      if (encHashBangFrag) {                          const EField dstfld = FieldQuery; // that's where we will store @@ -289,7 +289,7 @@ namespace NUri {                      }                      break;              } -  +              AppendField(out, fld, val, careFlags);              char* end = out.Buf(); @@ -300,7 +300,7 @@ namespace NUri {                  Y_ASSERT(beg >= out.Beg());                  out.SetPos(end);              } -  +              FldSetNoDirty(fld, TStringBuf(beg, end));              // special character case @@ -309,7 +309,7 @@ namespace NUri {                  const long allowChars = parser.GetFieldFlags(fld) & checkChars;                  if (checkChars != allowChars)                      ret = ParsedBadFormat; -            }  +            }              out << '\0';          } @@ -324,28 +324,28 @@ namespace NUri {          }          Buffer.Resize(out.Len()); -  +          if (GetScheme() == SchemeEmpty && SchemeEmpty != defscheme) {              if (SchemeUnknown == defscheme)                  ret = ParsedBadScheme;              else                  SetSchemeImpl(defscheme);          } -  +          if (0 == (parser.Flags & FeatureAllowEmptyPath))              CheckMissingFields(); -  +          const TStringBuf& port = GetField(FieldPort);          if (!port.empty()) {              if (!TryFromString<ui16>(port, Port))                  ret = ParsedBadPort; -        }  +        }          if (ParsedOK != ret)              return ret; -  +          // run validity checks now that all fields are set -  +          // check the host for DNS compliance          do {              if (0 == (flags & FeatureCheckHost)) @@ -363,28 +363,28 @@ namespace NUri {          } while (false);          return ret; -    }  -  +    } +      TState::EParsed TUri::ParseImpl(const TStringBuf& url, const TParseFlags& flags, ui32 maxlen, TScheme::EKind defscheme, ECharset enc) {          Clear(); -  +          if (url.empty())              return ParsedEmpty;          if (maxlen > 0 && url.length() > maxlen)              return ParsedTooLong; -  +          const TParser parser(flags, url, enc); -  +          return AssignImpl(parser, defscheme);      }      TState::EParsed TUri::Parse(const TStringBuf& url, const TParseFlags& flags, const TStringBuf& url_base, ui32 maxlen, ECharset enc) {          const TParseFlags flags1 = flags.Exclude(FeatureNoRelPath);          TState::EParsed ret = ParseImpl(url, url_base.empty() ? flags : flags1, maxlen, SchemeEmpty, enc); -        if (ParsedOK != ret)  -            return ret;  -  +        if (ParsedOK != ret) +            return ret; +          if (!url_base.empty() && !IsValidAbs()) {              TUri base;              ret = base.ParseImpl(url_base, flags, maxlen, SchemeEmpty, enc); @@ -394,19 +394,19 @@ namespace NUri {          }          Rewrite(); -        return ret;  +        return ret;      } -  +      TState::EParsed TUri::Parse(const TStringBuf& url, const TUri& base, const TParseFlags& flags, ui32 maxlen, ECharset enc) {          const TState::EParsed ret = ParseImpl(url, flags, maxlen, SchemeEmpty, enc); -        if (ParsedOK != ret)  -            return ret;  -  +        if (ParsedOK != ret) +            return ret; +          if (!IsValidAbs())              Merge(base, PathOperationFlag(flags)); -  +          Rewrite(); -        return ret;  +        return ret;      }      TState::EParsed TUri::ParseAbsUri(const TStringBuf& url, const TParseFlags& flags, ui32 maxlen, TScheme::EKind defscheme, ECharset enc) { @@ -414,12 +414,12 @@ namespace NUri {              url, flags | FeatureNoRelPath, maxlen, defscheme, enc);          if (ParsedOK != ret)              return ret; -  +          if (IsNull(FlagHost))              return ParsedBadHost;          Rewrite();          return ParsedOK;      } -  -}  + +} | 
