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 F05F484390; Mon, 11 Jan 2021 12:46:16 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org F05F484390 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1610358377; bh=CzWNRbI8flzVlwPlAuNzUVydbzMsupaqq0eQtSdQcYg=; 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=o2iMRWqwRND6OSJQ15he+NTCZD+MSjAoTxUOfMmOKbvS1dDAMW4+1dxXYb6qpy+wL n+kAaeYPw4WcdZyd/wNt6F5CIjhCnd8N3rkmNh3BUAljijDo2XApVm31gXIviVEsb+ GsNi32+1jxbyRXIIFzY3psxQecJAPL6Jh+DQLKBA= Received: from smtpng3.m.smailru.net (smtpng3.m.smailru.net [94.100.177.149]) (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 B93EC4C883 for ; Mon, 11 Jan 2021 12:45:27 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org B93EC4C883 Received: by smtpng3.m.smailru.net with esmtpa (envelope-from ) id 1kytlO-00039R-OC; Mon, 11 Jan 2021 12:45:27 +0300 To: tarantool-patches@dev.tarantool.org Date: Mon, 11 Jan 2021 12:45:01 +0300 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: 646B95376F6C166E X-77F55803: 4F1203BC0FB41BD9D0E79FBC973162CD9B382B274FF537389656BC690FF7BBE200894C459B0CD1B9CFD5F7C775144AAC066E91BC587AFB16415C8B29C57F0A26F9E87AB62FDAFEE4 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE74C265300876DF183C2099A533E45F2D0395957E7521B51C2CFCAF695D4D8E9FCEA1F7E6F0F101C6778DA827A17800CE7D73594321916E0988F08D7030A58E5AD6BA297DBC24807EAA9D420A4CFB5DD3E48E1CE17ADD1D66EEFFC266EC1BEF102FE0C38FC6E8DE41D8941B15DA834481FA18204E546F3947CDF046C1992EC065EF6B57BC7E64490618DEB871D839B7333395957E7521B51C2DFABB839C843B9C08941B15DA834481F8AA50765F7900637DCE3DBD6F8E38AFD389733CBF5DBD5E9B5C8C57E37DE458BD96E472CDF7238E04AD6D5ED66289B5278DA827A17800CE7DE9D1AAA02C24DE667F23339F89546C5A8DF7F3B2552694A6FED454B719173D6725E5C173C3A84C33D04619F399A958235872C767BF85DA2F004C906525384306FED454B719173D6462275124DF8B9C9DF33B08B2BB81206574AF45C6390F7469DAA53EE0834AAEE X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975CFA107D21112416993A85B0874D9C294163396C75967E68529C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EF31C0090ACECF247D699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D348F343DA43F62289F4F98220729CEABACA4CA9A5684A217CE9FA5A6FCCF0C872FBBC56B557E6BF5A11D7E09C32AA3244C233428757B28F5D390E4A1BE004B5A2B95A9E0DC41E9A4CF83B48618A63566E0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojmz2Dv49v36jwWpESPqOxqg== X-Mailru-Sender: 689FA8AB762F73937240DDB2502DDB706B244A421886CBAE6ED7BF0A93FD8767DD675A873A6B1A573284F99205A65E8EFB559BB5D741EB966AABCD5B59A9F6DF9ABAAAF6BC5F075B67EA787935ED9F1B X-Mras: Ok Subject: [Tarantool-patches] [PATCH v6 2/2] base64: improve decoder performance 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 Nikiforov via Tarantool-patches Reply-To: Sergey Nikiforov Cc: Vladislav Shpilevoy , Alexander Turenko Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" Unnecessary checks were removed from internal loops. Benchmark shows that performance is now ~1.19 times higher (release build, Intel Core I7-9700K, only one thread). --- Branch: https://github.com/tarantool/tarantool/tree/void234/gh-3069-fix-base64-memory-overrun-v6 third_party/base64.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/third_party/base64.c b/third_party/base64.c index 3ecd0843a..74260971b 100644 --- a/third_party/base64.c +++ b/third_party/base64.c @@ -258,10 +258,10 @@ base64_decode_block(const char *in_base64, int in_len, { case step_a: do { - if (in_pos == in_end || out_pos >= out_end) + if (in_pos >= in_end) { state->step = step_a; - state->result = curr_byte; + /* curr_byte is useless now. */ return out_pos - out_bin; } fragment = base64_decode_value(*in_pos++); @@ -269,7 +269,7 @@ base64_decode_block(const char *in_base64, int in_len, curr_byte = (fragment & 0x03f) << 2; case step_b: do { - if (in_pos == in_end || out_pos >= out_end) + if (in_pos >= in_end) { state->step = step_b; state->result = curr_byte; @@ -277,14 +277,19 @@ base64_decode_block(const char *in_base64, int in_len, } fragment = base64_decode_value(*in_pos++); } while (fragment < 0); + if (out_pos >= out_end) + { + /* We are losing some data. */ + state->step = step_b; + state->result = curr_byte; + return out_pos - out_bin; + } curr_byte |= (fragment & 0x030) >> 4; *out_pos++ = curr_byte; curr_byte = (fragment & 0x00f) << 4; - if (out_pos < out_end) - *out_pos = curr_byte; case step_c: do { - if (in_pos == in_end || out_pos >= out_end) + if (in_pos >= in_end) { state->step = step_c; state->result = curr_byte; @@ -292,14 +297,19 @@ base64_decode_block(const char *in_base64, int in_len, } fragment = base64_decode_value(*in_pos++); } while (fragment < 0); + if (out_pos >= out_end) + { + /* We are losing some data. */ + state->step = step_c; + state->result = curr_byte; + return out_pos - out_bin; + } curr_byte |= (fragment & 0x03c) >> 2; *out_pos++ = curr_byte; curr_byte = (fragment & 0x003) << 6; - if (out_pos < out_end) - *out_pos = curr_byte; case step_d: do { - if (in_pos == in_end || out_pos >= out_end) + if (in_pos >= in_end) { state->step = step_d; state->result = curr_byte; @@ -307,6 +317,13 @@ base64_decode_block(const char *in_base64, int in_len, } fragment = base64_decode_value(*in_pos++); } while (fragment < 0); + if (out_pos >= out_end) + { + /* We are losing some data. */ + state->step = step_d; + state->result = curr_byte; + return out_pos - out_bin; + } curr_byte |= (fragment & 0x03f); *out_pos++ = curr_byte; } -- 2.25.1