@@ -44,14 +44,15 @@ void JitConfigValues::MethodSet::initialize(const WCHAR* list, ICorJitHost* host
4444 bool isQuoted = false ; // true while parsing inside a quote "this-is-a-quoted-region"
4545 MethodName currentName; // Buffer used while parsing the current entry
4646
47- currentName.m_next = nullptr ;
48- currentName.m_methodNameStart = -1 ;
49- currentName.m_methodNameLen = -1 ;
50- currentName.m_methodNameWildcardAtEnd = false ;
51- currentName.m_classNameStart = -1 ;
52- currentName.m_classNameLen = -1 ;
53- currentName.m_classNameWildcardAtEnd = false ;
54- currentName.m_numArgs = -1 ;
47+ currentName.m_next = nullptr ;
48+ currentName.m_methodNameStart = -1 ;
49+ currentName.m_methodNameLen = -1 ;
50+ currentName.m_methodNameWildcardAtStart = false ;
51+ currentName.m_methodNameWildcardAtEnd = false ;
52+ currentName.m_classNameStart = -1 ;
53+ currentName.m_classNameLen = -1 ;
54+ currentName.m_classNameWildcardAtEnd = false ;
55+ currentName.m_numArgs = -1 ;
5556
5657 enum State
5758 {
@@ -202,21 +203,31 @@ void JitConfigValues::MethodSet::initialize(const WCHAR* list, ICorJitHost* host
202203 }
203204
204205 // Is the first character a wildcard?
205- if (m_list[currentName.m_methodNameStart ] == WILD_CHAR)
206+ if (m_list[currentName.m_methodNameStart ] == WILD_CHAR && currentName. m_methodNameLen == 1 )
206207 {
207208 // The method name is a full wildcard; mark it as such.
208209 currentName.m_methodNameStart = -1 ;
209210 currentName.m_methodNameLen = -1 ;
210211 }
211- // Is there a wildcard at the end of the method name?
212- //
213- else if (m_list[currentName.m_methodNameStart + currentName.m_methodNameLen - 1 ] == WILD_CHAR)
212+ else
214213 {
215- // i.e. class:foo*, will match any method that starts with "foo"
216-
217- // Remove the trailing WILD_CHAR from method name
218- currentName.m_methodNameLen --; // backup for WILD_CHAR
219- currentName.m_methodNameWildcardAtEnd = true ;
214+ // Is there a wildcard at the start of the method name?
215+ if (m_list[currentName.m_methodNameStart ] == WILD_CHAR)
216+ {
217+ // i.e. class:*foo, will match any method that ends with "foo"
218+ // Remove the leading WILD_CHAR from method name
219+ currentName.m_methodNameStart ++;
220+ currentName.m_methodNameLen --;
221+ currentName.m_methodNameWildcardAtStart = true ;
222+ }
223+ // Is there a wildcard at the end of the method name?
224+ if (m_list[currentName.m_methodNameStart + currentName.m_methodNameLen - 1 ] == WILD_CHAR)
225+ {
226+ // i.e. class:foo*, will match any method that starts with "foo"
227+ // Remove the trailing WILD_CHAR from method name
228+ currentName.m_methodNameLen --; // backup for WILD_CHAR
229+ currentName.m_methodNameWildcardAtEnd = true ;
230+ }
220231 }
221232
222233 // should we expect an ARG_LIST?
@@ -309,11 +320,35 @@ void JitConfigValues::MethodSet::destroy(ICorJitHost* host)
309320 m_names = nullptr ;
310321}
311322
312- static bool matchesName (const char * const name, int nameLen, bool wildcardAtEnd, const char * const s2)
323+ // strstr that is length-limited, this implementation is not intended to be used on hot paths
324+ static size_t strnstr (const char * pSrc, size_t srcSize, const char * needle, size_t needleSize)
325+ {
326+ if (srcSize < needleSize)
327+ {
328+ return -1 ;
329+ }
330+
331+ for (size_t srcPos = 0 ; srcPos <= srcSize - needleSize; srcPos++)
332+ {
333+ if (strncmp (pSrc + srcPos, needle, needleSize) == 0 )
334+ {
335+ return srcPos;
336+ }
337+ }
338+ return -1 ;
339+ }
340+
341+ static bool matchesName (
342+ const char * const name, int nameLen, bool wildcardAtStart, bool wildcardAtEnd, const char * const s2)
313343{
314- // 's2' must start with 'nameLen' characters of 'name'
315- if (strncmp (name, s2, nameLen) != 0 )
344+ if (wildcardAtStart && (int )strnstr (s2, strlen (s2), name, nameLen) == -1 )
345+ {
346+ return false ;
347+ }
348+
349+ if (!wildcardAtStart && strncmp (name, s2, nameLen) != 0 )
316350 {
351+ // 's2' must start with 'nameLen' characters of 'name'
317352 return false ;
318353 }
319354
@@ -346,12 +381,14 @@ bool JitConfigValues::MethodSet::contains(const char* methodName,
346381 if (name->m_methodNameStart != -1 )
347382 {
348383 const char * expectedMethodName = &m_list[name->m_methodNameStart ];
349- if (!matchesName (expectedMethodName, name->m_methodNameLen , name->m_methodNameWildcardAtEnd , methodName))
384+ if (!matchesName (expectedMethodName, name->m_methodNameLen , name->m_methodNameWildcardAtStart ,
385+ name->m_methodNameWildcardAtEnd , methodName))
350386 {
351387 // C++ embeds the class name into the method name; deal with that here.
352388 const char * colon = strchr (methodName, ' :' );
353389 if (colon != nullptr && colon[1 ] == ' :' &&
354- matchesName (expectedMethodName, name->m_methodNameLen , name->m_methodNameWildcardAtEnd , methodName))
390+ matchesName (expectedMethodName, name->m_methodNameLen , name->m_methodNameWildcardAtStart ,
391+ name->m_methodNameWildcardAtEnd , methodName))
355392 {
356393 int classLen = (int )(colon - methodName);
357394 if (name->m_classNameStart == -1 ||
@@ -367,8 +404,7 @@ bool JitConfigValues::MethodSet::contains(const char* methodName,
367404
368405 // If m_classNameStart is valid, check for a mismatch
369406 if (className == nullptr || name->m_classNameStart == -1 ||
370- matchesName (&m_list[name->m_classNameStart ], name->m_classNameLen , name->m_classNameWildcardAtEnd ,
371- className))
407+ matchesName (&m_list[name->m_classNameStart ], name->m_classNameLen , false , false , className))
372408 {
373409 return true ;
374410 }
@@ -379,8 +415,8 @@ bool JitConfigValues::MethodSet::contains(const char* methodName,
379415 if (nsSep != nullptr && nsSep != className)
380416 {
381417 const char * onlyClass = nsSep[-1 ] == ' .' ? nsSep : &nsSep[1 ];
382- if (matchesName (&m_list[name->m_classNameStart ], name->m_classNameLen , name-> m_classNameWildcardAtEnd ,
383- onlyClass))
418+ if (matchesName (&m_list[name->m_classNameStart ], name->m_classNameLen , false ,
419+ name-> m_classNameWildcardAtEnd , onlyClass))
384420 {
385421 return true ;
386422 }
0 commit comments