From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 0C8D3386F825 for ; Thu, 12 Nov 2020 22:34:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 0C8D3386F825 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-511-g2DT5Yu6NAOc3VTM7a4KDQ-1; Thu, 12 Nov 2020 17:34:39 -0500 X-MC-Unique: g2DT5Yu6NAOc3VTM7a4KDQ-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C80DC107464A; Thu, 12 Nov 2020 22:34:38 +0000 (UTC) Received: from t470.redhat.com (ovpn-112-135.phx2.redhat.com [10.3.112.135]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5B09019C59; Thu, 12 Nov 2020 22:34:38 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org, jit@gcc.gnu.org Subject: [committed] jit: fix string escaping Date: Thu, 12 Nov 2020 17:34:32 -0500 Message-Id: <20201112223432.3590712-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: jit@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Jit mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Nov 2020 22:34:43 -0000 This patch fixes a bug in recording::string::make_debug_string in which '\t' and '\n' were "escaped" by simply prepending a '\', thus emitting '\' then '\n', rather than '\' then 'n'. It also removes a hack that determined if a string is to be escaped by checking for a leading '"', by instead adding a flag. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to master as fec573408310139e1ffc42741fbe46b4f2947592. gcc/jit/ChangeLog: * jit-recording.c (recording::context::new_string): Add "escaped" param and use it when creating the new recording::string instance. (recording::string::string): Add "escaped" param and use it to initialize m_escaped. (recording::string::make_debug_string): Replace check that first char is double-quote with use of m_escaped. Fix escaping of '\t' and '\n'. Set "escaped" on the result. * jit-recording.h (recording::context::new_string): Add "escaped" param. (recording::string::string): Add "escaped" param. (recording::string::m_escaped): New field. gcc/testsuite/ChangeLog: * jit.dg/test-debug-strings.c (create_code): Add tests of string literal escaping. --- gcc/jit/jit-recording.c | 39 ++++++++++++++++------- gcc/jit/jit-recording.h | 9 ++++-- gcc/testsuite/jit.dg/test-debug-strings.c | 20 ++++++++++++ 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c index 3cbeba0f371..3a84c1fc5c0 100644 --- a/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -724,12 +724,12 @@ recording::context::disassociate_from_playback () This creates a fresh copy of the given 0-terminated buffer. */ recording::string * -recording::context::new_string (const char *text) +recording::context::new_string (const char *text, bool escaped) { if (!text) return NULL; - recording::string *result = new string (this, text); + recording::string *result = new string (this, text, escaped); record (result); return result; } @@ -1954,8 +1954,9 @@ recording::memento::write_to_dump (dump &d) /* Constructor for gcc::jit::recording::string::string, allocating a copy of the given text using new char[]. */ -recording::string::string (context *ctxt, const char *text) - : memento (ctxt) +recording::string::string (context *ctxt, const char *text, bool escaped) +: memento (ctxt), + m_escaped (escaped) { m_len = strlen (text); m_buffer = new char[m_len + 1]; @@ -2005,9 +2006,9 @@ recording::string::from_printf (context *ctxt, const char *fmt, ...) recording::string * recording::string::make_debug_string () { - /* Hack to avoid infinite recursion into strings when logging all - mementos: don't re-escape strings: */ - if (m_buffer[0] == '"') + /* Avoid infinite recursion into strings when logging all mementos: + don't re-escape strings: */ + if (m_escaped) return this; /* Wrap in quotes and do escaping etc */ @@ -2024,15 +2025,31 @@ recording::string::make_debug_string () for (size_t i = 0; i < m_len ; i++) { char ch = m_buffer[i]; - if (ch == '\t' || ch == '\n' || ch == '\\' || ch == '"') - APPEND('\\'); - APPEND(ch); + switch (ch) + { + default: + APPEND(ch); + break; + case '\t': + APPEND('\\'); + APPEND('t'); + break; + case '\n': + APPEND('\\'); + APPEND('n'); + break; + case '\\': + case '"': + APPEND('\\'); + APPEND(ch); + break; + } } APPEND('"'); /* closing quote */ #undef APPEND tmp[len] = '\0'; /* nil termintator */ - string *result = m_ctxt->new_string (tmp); + string *result = m_ctxt->new_string (tmp, true); delete[] tmp; return result; diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 30e37aff387..9a43a7bf33a 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -74,7 +74,7 @@ public: void disassociate_from_playback (); string * - new_string (const char *text); + new_string (const char *text, bool escaped = false); location * new_location (const char *filename, @@ -414,7 +414,7 @@ private: class string : public memento { public: - string (context *ctxt, const char *text); + string (context *ctxt, const char *text, bool escaped); ~string (); const char *c_str () { return m_buffer; } @@ -431,6 +431,11 @@ private: private: size_t m_len; char *m_buffer; + + /* Flag to track if this string is the result of string::make_debug_string, + to avoid infinite recursion when logging all mementos: don't re-escape + such strings. */ + bool m_escaped; }; class location : public memento diff --git a/gcc/testsuite/jit.dg/test-debug-strings.c b/gcc/testsuite/jit.dg/test-debug-strings.c index e515a176257..03ef3370d94 100644 --- a/gcc/testsuite/jit.dg/test-debug-strings.c +++ b/gcc/testsuite/jit.dg/test-debug-strings.c @@ -178,6 +178,26 @@ create_code (gcc_jit_context *ctxt, void *user_data) "((struct node *)ptr->next)->next"); } + /* Check string literal escaping. */ + { + CHECK_RVALUE_DEBUG_STRING + (gcc_jit_context_new_string_literal (ctxt, ""), + "\"\""); + CHECK_RVALUE_DEBUG_STRING + (gcc_jit_context_new_string_literal (ctxt, "foo"), + "\"foo\""); + CHECK_RVALUE_DEBUG_STRING + (gcc_jit_context_new_string_literal (ctxt, "\""), + "\"\\\"\""); + CHECK_RVALUE_DEBUG_STRING + (gcc_jit_context_new_string_literal (ctxt, "line 1\nline 2\n"), + "\"line 1\\nline 2\\n\""); + CHECK_RVALUE_DEBUG_STRING + (gcc_jit_context_new_string_literal (ctxt, "foo\tbar"), + "\"foo\\tbar\""); + } + +#undef CHECK_RVALUE_DEBUG_STRING #undef CHECK_LVALUE_DEBUG_STRING } -- 2.26.2