Skip to content

Conversation

@FunkyAss
Copy link
Contributor

The commit messages are quite verbose, so I don't have much to say here.

Both the bugs can be reproduced from 93f3d0c (the actual HEAD). For your convenience:

A couple of thoughts about the actual codebase (not directly related to the patches, but working on them "inspired" me):

  1. calling luaL_error as return luaL_error will not fix any error or unintended behaviour, but could make some of them easier to spot;
  2. it's plenty of luaL_error. A lua script with proper error checking will probably be full of pcalls (with their overhead) and maybe string manipulation functions (for checking error messages);

FunkyAss added 2 commits May 23, 2014 11:52
Performing a request defining custom callbacks, then performing another
request without callbacks (i.e. using libcurl default callbacks) causes
a segmentation fault:
    -- assume the easy handle is properly set up
    easy:perform{writefunction = function(chunk) io.write(chunk) end}
    -- the answer is written to stdout --
    easy:perform()
    -- segmentation fault (in fwrite () from libc)

The above segmentation fault happens because the data pointer, set with
CURLOPT_WRITEDATA (CURLOPT_FILE) in curl_easy_setopt, for the write
function (fwrite for default callbacks) is not properly cleaned up and
the lua_State from the previous callback is passed.

Similar faults will show up with CURLOPT_WRITEHEADER and
CURLOPT_READDATA (CURLOPT_INFILE).

In order to properly restore the default callback behaviours:
    - the "write function" data pointer must be set back to stdout;
    - the "header function" data pointer must be set to NULL;
    - the "read function" data pointer must be set to stdin;
About the values for data pointers: despite the libcurl documentation
says nothing about their default values, reading libcurl source code
leads to stdout, stdin and NULL (actually 0x0).

Signed-off-by: Davide "FunkyAss" Del Zompo <davide.delzompo@gmail.com>
Performing a request with custom callbacks that returns anything but
CURLE_OK, then performing a request with default callbacks causes lua to
call a nil value:
    -- assume the easy handle is properly set up
    easy:setopt_url("http://mispelled-domain/")
    -- curl_perform will return CURLE_COULDNT_RESOLVE_HOST
    pcall(easy.perform, easy,
        {writefunction = function(chunk) return end}
    )
    -- a totally legit url
    easy:setopt_url("http://example.com")
    easy:perform()
    -- lua: attempt to call a nil value

When curl_easy_perform returns anything but CURLE_OK, l_easy_perform
calls luaL_error, which ends doing a longjump. The callbacks cleanup
never happens, leaving the lua-curl "callback handlers"
(l_easy_writefunction, readfuntion, headerfunction) registered.
The subsequent request doesn't register any callback, so an empty table
is pushed on the stack and the callback handler will call a nil value.

Signed-off-by: Davide "FunkyAss" Del Zompo <davide.delzompo@gmail.com>
@msva
Copy link
Contributor

msva commented May 24, 2014

Thanks for report!
--[[ we definitely should add test-units ]]--

I've also checked that bugs both against HEAD and some 2013-year commits and that bugs persists as well.

Although, segfault-bug sometimes leading to normal lua error (under LuaJIT) and all the time (i.e. no segfaults for me) under C-Lua 5.1.5

$ luajit ../test1.lua
luajit: ../test1.lua:12: Failed writing body (0 != 899)
stack traceback:
        [C]: in function 'perform'
        ../test1.lua:12: in main chunk
        [C]: at 0x7f0f31123010
$ luajit ../test1.lua
[1]    18488 segmentation fault  luajit ../test1.lua
$ luajit ../test1.lua
[1]    18511 segmentation fault  luajit ../test1.lua
$ luajit ../test1.lua
[1]    18533 segmentation fault  luajit ../test1.lua
$ luajit ../test1.lua
luajit: ../test1.lua:12: Failed writing body (0 != 899)
stack traceback:
        [C]: in function 'perform'
        ../test1.lua:12: in main chunk
        [C]: at 0x7fa419465010
$ luajit ../test1.lua
luajit: ../test1.lua:12: Failed writing body (0 != 899)
stack traceback:
        [C]: in function 'perform'
        ../test1.lua:12: in main chunk
        [C]: at 0x7f28cbfef010
$ luajit ../test1.lua
luajit: ../test1.lua:12: Failed writing body (0 != 899)
stack traceback:
        [C]: in function 'perform'
        ../test1.lua:12: in main chunk
        [C]: at 0x7fc16432f010
$ luajit ../test1.lua
luajit: ../test1.lua:12: Failed writing body (0 != 899)
stack traceback:
        [C]: in function 'perform'
        ../test1.lua:12: in main chunk
        [C]: at 0x7f9a6d83b010
$ luajit ../test1.lua
[1]    18633 segmentation fault  luajit ../test1.lua
$ luajit ../test1.lua
[1]    18660 segmentation fault  luajit ../test1.lua

msva added a commit that referenced this pull request May 24, 2014
Fix segmentation fault and attempt to call nil in callbacks
@msva msva merged commit 4a95a93 into Lua-cURL:master May 24, 2014
@FunkyAss FunkyAss deleted the fix-callback branch May 24, 2014 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants