Skip to content

Commit

Permalink
Reduce cap length of cnames generated from long function argument lis…
Browse files Browse the repository at this point in the history
…ts (GH-6104)

Because max_prefix was much less than max_len, it was actually just making the names longer.

Closes #6052
  • Loading branch information
da-woods committed Mar 28, 2024
1 parent a419781 commit dd8b2b2
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
10 changes: 7 additions & 3 deletions Cython/Compiler/PyrexTypes.py
Expand Up @@ -3490,8 +3490,12 @@ def create_to_py_utility_code(self, env):
def arg_name_part(arg):
return "%s%s" % (len(arg.name), punycodify_name(arg.name)) if arg.name else "0"
arg_names = [ arg_name_part(arg) for arg in self.args ]
arg_names = "_".join(arg_names)
arg_names = cap_length("_".join(arg_names))
safe_typename = type_identifier(self, pyrex=True)
# Note that the length here is slightly bigger than twice the default cap in
# "cap_length" (since the length is capped in both arg_names and the type_identifier)
# but since this is significantly shorter than compilers should be able to handle,
# that is acceptable.
to_py_function = "__Pyx_CFunc_%s_to_py_%s" % (safe_typename, arg_names)

for arg in self.args:
Expand Down Expand Up @@ -5486,8 +5490,8 @@ def type_identifier_from_declaration(decl, scope = None):
_type_identifier_cache[key] = safe
return safe

def cap_length(s, max_prefix=63, max_len=1024):
if len(s) <= max_prefix:
def cap_length(s, max_len=63):
if len(s) <= max_len:
return s
hash_prefix = hashlib.sha256(s.encode('ascii')).hexdigest()[:6]
return '%s__%s__etc' % (hash_prefix, s[:max_len-17])
Expand Down
6 changes: 4 additions & 2 deletions Cython/Compiler/Tests/TestTypes.py
Expand Up @@ -59,9 +59,9 @@ def test_type_identifier_for_declaration(self):
("const &&&std::vector", "const__fwref__refstd__in_vector"),
("const &&std::vector", "const__fwrefstd__in_vector"),
("void (*func)(int x, float y)",
"975d51__void__lParen__ptrfunc__rParen__lParenint__space_x__comma_float__space_y__rParen__etc"),
"975d51__void__lParen__ptrfunc__rParen__lParenint__spac__etc"),
("float ** (*func)(int x, int[:] y)",
"31883a__float__ptr__ptr__lParen__ptrfunc__rParen__lParenint__space_x__comma_int__lArr__D__rArry__rParen__etc"),
"31883a__float__ptr__ptr__lParen__ptrfunc__rParen__lPar__etc"),
]
self._test_escape(function_name, test_data)

Expand All @@ -71,3 +71,5 @@ def _test_escape(self, func_name, test_data=TEST_DATA):
escaped_value = escape(declaration)
self.assertEqual(escaped_value, expected, "%s('%s') == '%s' != '%s'" % (
func_name, declaration, escaped_value, expected))
# test that the length has been successfully capped
self.assertLessEqual(len(escaped_value), 64)

0 comments on commit dd8b2b2

Please sign in to comment.