@@ -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