From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 9D0B36EFDA; Wed, 18 May 2022 12:01:09 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 9D0B36EFDA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1652864469; bh=CIU+Fl7edqOlcRlHKI2J/5JXNHv69kK66zSRCxh0NMM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=t0XxXW1Tf2sL1Qr9OavnDNh6EOLL/OUgJgQnorCEXnBD0/TkuWqwiBj4v5Rb8OLYV rxv7JJXtxL3Tvdyd85qdGW/5cjHasoc3snXU4U1VamJYNDNEH88K9HT9EkqiZie6Ze DsEm4yVuxJdBMxggLcWnm8jOjpxP2x4ZVKFw7FR0= Received: from smtpng1.i.mail.ru (smtpng1.i.mail.ru [94.100.181.251]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id BE6356EFDA for ; Wed, 18 May 2022 12:00:37 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org BE6356EFDA Received: by smtpng1.m.smailru.net with esmtpa (envelope-from ) id 1nrFXo-0002l1-M9; Wed, 18 May 2022 12:00:37 +0300 To: Sergey Ostanevich , Igor Munkin Date: Wed, 18 May 2022 11:58:16 +0300 Message-Id: <52271fcc9139dbf02d98b384a50cc13d1a02abb6.1652863494.git.skaplun@tarantool.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-4EC0790: 10 X-7564579A: EEAE043A70213CC8 X-77F55803: 4F1203BC0FB41BD9F33B3806BF114D159E7BD6746107077164F3C96AD71A0548182A05F5380850404C228DA9ACA6FE27A94EA6EC7B6E50CC528F7D26936C89B625C8381AB7BBF0E1A74E375901266623 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE78E8764B5BC580342EA1F7E6F0F101C67BD4B6F7A4D31EC0BCC500DACC3FED6E28638F802B75D45FF8AA50765F7900637B997C8222C70C3D98638F802B75D45FF36EB9D2243A4F8B5A6FCA7DBDB1FC311F39EFFDF887939037866D6147AF826D8723B7FBCB52AAD6C19F9F939238E72F1117882F4460429724CE54428C33FAD305F5C1EE8F4F765FCEA77C8EAE1CE44B0A471835C12D1D9774AD6D5ED66289B52BA9C0B312567BB23117882F44604297287769387670735201E561CDFBCA1751FBDFBBEFFF4125B51D2E47CDBA5A96583BA9C0B312567BB231DD303D21008E29813377AFFFEAFD269A417C69337E82CC2E827F84554CEF50127C277FBC8AE2E8BA83251EDC214901ED5E8D9A59859A8B6D75B66E98413B381089D37D7C0E48F6C5571747095F342E88FB05168BE4CE3AF X-8FC586DF: 6EFBBC1D9D64D975 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975CC912BAED7AAC53FBA0C259B5339BB641AC3A359CDDE91DA89C2B6934AE262D3EE7EAB7254005DCED1C39E39C5FB3188C4EAF44D9B582CE87C8A4C02DF684249C42578FD4EBC74EEF699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D342B94C1DAF75C4D22F67CC93D730F898E081D6D1805EC75896AA91E63177C587EFC79FDA3862DD5D01D7E09C32AA3244C973153AE2117F5571F736657562EC0FF5595C85A795C7BAE927AC6DF5659F194 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojtNJAk7CcUJ0o1z6q4bI2xA== X-Mailru-Sender: 689FA8AB762F739339CABD9B3CA9A7D695D38D58A549CADD2BC81ABAA9F021BD0FBE9A32752B8C9C2AA642CC12EC09F1FB559BB5D741EB962F61BD320559CF1EFD657A8799238ED55FEEDEB644C299C0ED14614B50AE0675 X-Mras: Ok Subject: [Tarantool-patches] [PATCH luajit 1/2] Fix io.close(). X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Sergey Kaplun via Tarantool-patches Reply-To: Sergey Kaplun Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Mike Pall Reported by farmboy0. When `io.close()` is called without arguments on already closed default output `iof->fp` is already NULL. So, the forward call to `fclose()` leads to SEGFAULT. This patch adds the corresponding check by using `io_stdfile()` instead `IOSTDF_IOF()`. Also, this patch refactors several internal functions by changing the argument type from `FILE *` to `IOFileUD *`. Sergey Kaplun: * added the description and the test for the problem --- src/lib_io.c | 20 +++++++++-------- .../lj-735-io-close-on-closed-file.test.lua | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 test/tarantool-tests/lj-735-io-close-on-closed-file.test.lua diff --git a/src/lib_io.c b/src/lib_io.c index 9763ed46..d9028938 100644 --- a/src/lib_io.c +++ b/src/lib_io.c @@ -60,12 +60,12 @@ static IOFileUD *io_tofile(lua_State *L) return iof; } -static FILE *io_stdfile(lua_State *L, ptrdiff_t id) +static IOFileUD *io_stdfile(lua_State *L, ptrdiff_t id) { IOFileUD *iof = IOSTDF_IOF(L, id); if (iof->fp == NULL) lj_err_caller(L, LJ_ERR_IOSTDCL); - return iof->fp; + return iof; } static IOFileUD *io_file_new(lua_State *L) @@ -189,8 +189,9 @@ static int io_file_readlen(lua_State *L, FILE *fp, MSize m) } } -static int io_file_read(lua_State *L, FILE *fp, int start) +static int io_file_read(lua_State *L, IOFileUD *iof, int start) { + FILE *fp = iof->fp; int ok, n, nargs = (int)(L->top - L->base) - start; clearerr(fp); if (nargs == 0) { @@ -226,8 +227,9 @@ static int io_file_read(lua_State *L, FILE *fp, int start) return n - start; } -static int io_file_write(lua_State *L, FILE *fp, int start) +static int io_file_write(lua_State *L, IOFileUD *iof, int start) { + FILE *fp = iof->fp; cTValue *tv; int status = 1; for (tv = L->base+start; tv < L->top; tv++) { @@ -261,7 +263,7 @@ static int io_file_iter(lua_State *L) memcpy(L->top, &fn->c.upvalue[1], n*sizeof(TValue)); L->top += n; } - n = io_file_read(L, iof->fp, 0); + n = io_file_read(L, iof, 0); if (ferror(iof->fp)) lj_err_callermsg(L, strVdata(L->top-2)); if (tvisnil(L->base) && (iof->type & IOFILE_FLAG_CLOSE)) { @@ -287,18 +289,18 @@ static int io_file_lines(lua_State *L) LJLIB_CF(io_method_close) { IOFileUD *iof = L->base < L->top ? io_tofile(L) : - IOSTDF_IOF(L, GCROOT_IO_OUTPUT); + io_stdfile(L, GCROOT_IO_OUTPUT); return io_file_close(L, iof); } LJLIB_CF(io_method_read) { - return io_file_read(L, io_tofile(L)->fp, 1); + return io_file_read(L, io_tofile(L), 1); } LJLIB_CF(io_method_write) LJLIB_REC(io_write 0) { - return io_file_write(L, io_tofile(L)->fp, 1); + return io_file_write(L, io_tofile(L), 1); } LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0) @@ -452,7 +454,7 @@ LJLIB_CF(io_write) LJLIB_REC(io_write GCROOT_IO_OUTPUT) LJLIB_CF(io_flush) LJLIB_REC(io_flush GCROOT_IO_OUTPUT) { - return luaL_fileresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)) == 0, NULL); + return luaL_fileresult(L, fflush(io_stdfile(L, GCROOT_IO_OUTPUT)->fp) == 0, NULL); } static int io_std_getset(lua_State *L, ptrdiff_t id, const char *mode) diff --git a/test/tarantool-tests/lj-735-io-close-on-closed-file.test.lua b/test/tarantool-tests/lj-735-io-close-on-closed-file.test.lua new file mode 100644 index 00000000..795dad6c --- /dev/null +++ b/test/tarantool-tests/lj-735-io-close-on-closed-file.test.lua @@ -0,0 +1,22 @@ +local tap = require('tap') + +local test = tap.test('lj-735-io-close-on-closed-file') +test:plan(1) + +local TEST_FILE = 'lj-735-io-close-on-closed-file.tmp' + +local oldstdout = io.output() +io.output(TEST_FILE) + +local status, err = io.close() +assert(status, err) + +status = pcall(io.close) + +io.output(oldstdout) + +test:ok(not status, 'close already closed file') + +assert(os.remove(TEST_FILE)) + +os.exit(test:check() and 0 or 1) -- 2.34.1