Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal error when using null characters in call argument names #14786

Open
HertzDevil opened this issue Jul 6, 2024 · 0 comments
Open

Internal error when using null characters in call argument names #14786

HertzDevil opened this issue Jul 6, 2024 · 0 comments

Comments

@HertzDevil
Copy link
Contributor

HertzDevil commented Jul 6, 2024

The following:

def foo(**opts)
end

foo("\u{0}": 1)
foo("\u{0}": true)

leads to an internal error:

Missing hash key: {#<LLVM::Module:0x1047c2120 @context=#<LLVM::Context:0x1047c2150 @unwrap=Pointer(Void)@0x12d609d60, @dispose_on_finalize=true, @disposed=false, @builders=[#<LLVM::Builder:0x105e94680 @disposed=false, @unwrap=Pointer(Void)@0x12d60bc50>]>, @unwrap=Pointer(Void)@0x12d60b300, @owned=false>, "*foo:\u0000<Bool>:Nil"} (KeyError)
  from src/hash.cr:1195:9 in '[]'
  from src/compiler/crystal/codegen/fun.cr:6:29 in 'typed_fun?'
  from src/compiler/crystal/codegen/fun.cr:24:12 in 'target_def_fun'
  from src/compiler/crystal/codegen/call.cr:435:12 in 'codegen_call'
  from src/compiler/crystal/codegen/call.cr:35:7 in 'visit'
  from src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from src/compiler/crystal/codegen/codegen.cr:2403:7 in 'accept'
  from src/compiler/crystal/codegen/codegen.cr:733:9 in 'visit'
  from src/compiler/crystal/syntax/visitor.cr:27:12 in 'accept'
  from src/compiler/crystal/codegen/codegen.cr:2403:7 in 'accept'
  from src/compiler/crystal/codegen/codegen.cr:76:7 in 'codegen'
  from src/compiler/crystal/codegen/codegen.cr:72:5 in 'codegen:debug:frame_pointers:single_module'
  from src/compiler/crystal/progress_tracker.cr:22:7 in 'codegen'
  from src/compiler/crystal/compiler.cr:211:16 in 'compile'
  from src/compiler/crystal/command.cr:359:3 in 'compile'
  from src/compiler/crystal/command.cr:239:5 in 'run_command'
  from src/compiler/crystal/command.cr:112:7 in 'run'
  from src/compiler/crystal/command.cr:55:5 in 'run'
  from src/compiler/crystal/command.cr:54:3 in 'run'
  from src/compiler/crystal.cr:11:1 in '__crystal_main'
  from src/crystal/main.cr:118:5 in 'main_user_code'
  from src/crystal/main.cr:104:7 in 'main'
  from src/crystal/main.cr:130:3 in 'main'

The exception is raised here:

def typed_fun?(mod : LLVM::Module, name : String) : LLVMTypedFunction?
if func = mod.functions[name]?
LLVMTypedFunction.new(@fun_types[{mod, name}], func)
end
end

Here mod.functions is an LLVM::FunctionCollection, whose #[]? calls LLVMGetNamedFunction. This function takes a null-terminated string as an argument, without a way to specify the string size. Normally, when name is *foo:\u0000<Bool>:Nil, then this lookup should fail and #typed_fun? should return nil, but since there is a null byte, the name passed to LLVM becomes *foo:, which corresponds to a previous LLVM function created for *foo:\u0000<Int32>:Nil (this uses LLVMAddFunction, which also takes a null-terminated string only). Hence this triggers a KeyError when looking up @fun_types, which does respect embedded null bytes.

Windows does not have this issue, because all non-alphanumeric characters get automatically mangled by Crystal.safe_mangling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant