samwoo68 / google-gdata

Automatically exported from code.google.com/p/google-gdata
0 stars 0 forks source link

OAuth signature encoding issue with international charachters. #615

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
If you requested url contains a query string which has Hebrew characters for 
example http://someurl.com/index.html?query=משה
1.OAuthUtil.GenerateHeader(request.RequestUri, ConsumerKey, ConsumerSecret, 
null, null, request.Method); will not generate the correct header signature the 
reason is because there is a bug in the OAuthBase.EncodingPerRFC3986 which will 
encode the query=משה as UTF16 string and since uri is encoded as UTF8 it 
would cause mismatch from requested url and signature.
You also duplicate this behavior by running this test case which simulates what 
happens to the query parameter in the GenerateSignatureBase method.

            var urlEncodedUtf8 = System.Web.HttpUtility.UrlEncode("משה").ToUpper();
            var decoded = Utilities.UrlDecodedValue(urlEncodedUtf8);
            var googleEncoded = OAuthBase.EncodingPerRFC3986(decoded);
            Assert.AreEqual(urlEncodedUtf8, googleEncoded);

3.

I also have a fix that resolves this issue by correctly decoding the string as 
UTF8 first.

        public static string EncodingPerRFC3986(string value) {
            if (string.IsNullOrEmpty(value)) {
                return string.Empty;
            }

            StringBuilder result = new StringBuilder();

            foreach (char symbol in value) {
                if (unreservedChars.IndexOf(symbol) != -1) {
                    result.Append(symbol);
                } else
                {
                    result.Append(PercentEncode(symbol.ToString()));
                    //result.Append('%' + String.Format("{0:X2}", (int)symbol));
                }
            }

            return result.ToString();
        }

        public static string PercentEncode(string value)
        {
            var bytes = Encoding.UTF8.GetBytes(value);
            var sb = new StringBuilder();
            foreach (var b in bytes)
            {
                // [DC]: Support proper encoding of special characters (\n\r\t\b)
                if ((b > 7 && b < 11) || b == 13)
                {
                    sb.Append(string.Format("%0{0:X}", b));
                }
                else
                {
                    sb.Append(string.Format("%{0:X}", b));
                }
            }
            return sb.ToString();
        }

Original issue reported on code.google.com by mercury2...@gmail.com on 15 Aug 2012 at 1:23

GoogleCodeExporter commented 9 years ago
Thanks for the patch, I committed it in rev. 1210:

http://code.google.com/p/google-gdata/source/detail?r=1210

Original comment by ccherub...@google.com on 17 Aug 2012 at 6:42