@@ -29,7 +29,7 @@ namespace Js
2929            }
3030        }
3131
32-         return  Encode (strURI-> GetString (), strURI-> GetLength () , flags, scriptContext);
32+         return  Encode (strURI, flags, scriptContext);
3333    }
3434
3535    unsigned  char  UriHelper::s_uriProps[128 ] =
@@ -126,10 +126,13 @@ namespace Js
126126    }
127127
128128    //  The Encode algorithm described in sec. 15.1.3 of the spec. The input string is
129-     //  'input ' and the Unescaped set is described by the flags 'unescapedFlags'. The
129+     //  'strURI ' and the Unescaped set is described by the flags 'unescapedFlags'. The
130130    //  output is a string var.
131-     Var UriHelper::Encode (__in_ecount(len)  const   char16* input, uint32 len , unsigned char unescapedFlags, ScriptContext* scriptContext )
131+     Var UriHelper::Encode (JavascriptString* strURI , unsigned  char  unescapedFlags, ScriptContext* scriptContext )
132132    {
133+         charcount_t  len = strURI->GetLength ();
134+         __in_ecount (len) const  char16* input = strURI->GetString ();
135+         bool  needsChanges = false ;
133136        BYTE bUTF8[MaxUTF8Len];
134137
135138        //  pass 1 calculate output length and error check
@@ -144,6 +147,8 @@ namespace Js
144147            }
145148            else 
146149            {
150+                 needsChanges = true ;
151+ 
147152                if ( c >= 0xDC00  && c <= 0xDFFF  )
148153                {
149154                    JavascriptError::ThrowURIError (scriptContext, JSERR_URIEncodeError /*  TODO-ERROR: _u("NEED MESSAGE") */  );
@@ -173,6 +178,13 @@ namespace Js
173178            }
174179        }
175180
181+         //  If nothing needs encoding, then avoid extra work
182+         if  (!needsChanges)
183+         {
184+             AssertMsg (scriptContext == strURI->GetScriptContext (), " Should have already marshaled the string in cross site thunk"  );
185+             return  strURI;
186+         }
187+ 
176188        // pass 2 generate the encoded URI
177189
178190        uint32 allocSize = UInt32Math::Add (outputLen, 1 );
@@ -238,7 +250,7 @@ namespace Js
238250        __analysis_assume (outputLen + 1  == allocSize);
239251        outURI[outputLen] = _u (' \0 '  );
240252
241-         return  JavascriptString::NewCopyBuffer  (outURI, outputLen, scriptContext);
253+         return  JavascriptString::NewWithBuffer  (outURI, outputLen, scriptContext);
242254    }
243255
244256    Var UriHelper::DecodeCoreURI (ScriptContext* scriptContext, Arguments& args, unsigned  char  reservedFlags )
@@ -265,14 +277,17 @@ namespace Js
265277            }
266278        }
267279
268-         return  Decode (strURI-> GetString (), strURI-> GetLength () , reservedFlags, scriptContext);
280+         return  Decode (strURI, reservedFlags, scriptContext);
269281    }
270282
271283    //  The Decode algorithm described in sec. 15.1.3 of the spec. The input string is
272-     //  'input ' and the Reserved set is described by the flags 'reservedFlags'. The
284+     //  'strURI ' and the Reserved set is described by the flags 'reservedFlags'. The
273285    //  output is a string var.
274-     Var UriHelper::Decode (__in_ecount(len)  const  char16* input, uint32 len , unsigned char reservedFlags, ScriptContext* scriptContext)
286+     Var UriHelper::Decode (JavascriptString* strURI , unsigned  char  reservedFlags, ScriptContext* scriptContext)
275287    {
288+         charcount_t  len = strURI->GetLength ();
289+         __in_ecount (len) const  char16* input = strURI->GetString ();
290+         bool  needsChanges = false ;
276291        char16 c1;
277292        char16 c;
278293        //  pass 1 calculate output length and error check
@@ -283,6 +298,8 @@ namespace Js
283298
284299            if ( c == ' %'  )
285300            {
301+                 needsChanges = true ;
302+ 
286303                uint32 start = k;
287304                if ( k + 2  >= len )
288305                {
@@ -383,6 +400,13 @@ namespace Js
383400            }
384401        }
385402
403+         //  If nothing needs decoding, then avoid extra work
404+         if  (!needsChanges)
405+         {
406+             AssertMsg (scriptContext == strURI->GetScriptContext (), " Should have already marshaled the string in cross site thunk"  );
407+             return  strURI;
408+         }
409+ 
386410        // pass 2 generate the decoded URI
387411        uint32 allocSize = UInt32Math::Add (outputLen, 1 );
388412        char16* outURI = RecyclerNewArrayLeaf (scriptContext->GetRecycler (), char16, allocSize);
@@ -538,7 +562,7 @@ namespace Js
538562        __analysis_assume (outputLen + 1  == allocSize);
539563        outURI[outputLen] = _u (' \0 '  );
540564
541-         return  JavascriptString::NewCopyBuffer  (outURI, outputLen, scriptContext);
565+         return  JavascriptString::NewWithBuffer  (outURI, outputLen, scriptContext);
542566    }
543567
544568    //  Decodes a two-hexadecimal-digit wide character pair into the byte value it represents
0 commit comments