Control: tags -1 + patch Please find attached a patch, basically only build-tested (I also ran it but I find it difficult to test specifically the affected code).
Description: Port to PCRE2. Bug-Debian: https://bugs.debian.org/1000093 Author: Yavor Doganov <ya...@gnu.org> Forwarded: no Last-Update: 2024-01-09 ---
--- mysql-workbench-8.0.32+dfsg.orig/CMakeLists.txt +++ mysql-workbench-8.0.32+dfsg/CMakeLists.txt @@ -119,7 +119,7 @@ endif(UNIX) -pkg_check_modules(PCRE REQUIRED libpcre libpcrecpp) +pkg_check_modules(PCRE REQUIRED libpcre2-8) pkg_check_modules(CAIRO REQUIRED cairo>=1.5.12) pkg_check_modules(UUID REQUIRED uuid) pkg_check_modules(LIBZIP REQUIRED libzip) --- mysql-workbench-8.0.32+dfsg.orig/library/grt/src/grtpp_shell.cpp +++ mysql-workbench-8.0.32+dfsg/library/grt/src/grtpp_shell.cpp @@ -21,7 +21,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "grtpp_shell.h" using namespace grt; @@ -30,28 +31,34 @@ char *get_value_from_text_ex_opt(const char *txt, int txt_length, const char *regexpr, unsigned int substring_nr, int options_for_exec) { - pcre *pcre_exp; - const char *error_str; - int erroffset; - int o_vector[O_VECTOR_COUNT]; - int rc; - const char *ret_val; + pcre2_code *pcre_exp; + pcre2_match_data *md; + int error; + PCRE2_SIZE erroffset; + PCRE2_SIZE *o_vector; + PCRE2_UCHAR *ret_val; char *value = NULL; if (txt && *txt) { - pcre_exp = pcre_compile(regexpr, PCRE_CASELESS, &error_str, &erroffset, NULL); + pcre_exp = pcre2_compile(reinterpret_cast<PCRE2_SPTR>(regexpr), + PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, + &error, &erroffset, NULL); if (pcre_exp) { - if ((rc = pcre_exec(pcre_exp, NULL, txt, txt_length, 0, options_for_exec, o_vector, O_VECTOR_COUNT)) > 0) { - if (o_vector[substring_nr * 2] != -1) { - pcre_get_substring(txt, o_vector, rc, substring_nr, &ret_val); + md = pcre2_match_data_create(O_VECTOR_COUNT, NULL); + if (pcre2_match(pcre_exp, reinterpret_cast<PCRE2_SPTR>(txt), + txt_length, 0, options_for_exec, md, NULL) > 0) { + o_vector = pcre2_get_ovector_pointer(md); + if ((int)o_vector[substring_nr * 2] > 0) { + pcre2_substring_get_bynumber(md, substring_nr, &ret_val, &erroffset); - value = g_strdup(ret_val); + value = g_strdup(reinterpret_cast<const char *>(ret_val)); - pcre_free_substring((char *)ret_val); + pcre2_substring_free(ret_val); } } - pcre_free(pcre_exp); + pcre2_code_free(pcre_exp); + pcre2_match_data_free(md); } } --- mysql-workbench-8.0.32+dfsg.orig/backend/wbprivate/sqlide/db_sql_editor_history_be.cpp +++ mysql-workbench-8.0.32+dfsg/backend/wbprivate/sqlide/db_sql_editor_history_be.cpp @@ -26,7 +26,6 @@ #include <stdlib.h> #include <boost/foreach.hpp> -#include <pcre.h> #include "db_sql_editor_history_be.h" #include "sqlide/recordset_data_storage.h" --- mysql-workbench-8.0.32+dfsg.orig/backend/wbpublic/grt/grt_string_list_model.cpp +++ mysql-workbench-8.0.32+dfsg/backend/wbpublic/grt/grt_string_list_model.cpp @@ -22,7 +22,8 @@ */ #include "grt_string_list_model.h" -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include "grtpp_util.h" using namespace bec; @@ -266,33 +267,43 @@ } // compile regexp - pcre *patre; + pcre2_code *patre; + pcre2_match_data *md; { - const char *error; - int erroffset; - patre = pcre_compile(regexp.c_str(), PCRE_UTF8 | PCRE_EXTRA, &error, &erroffset, NULL); - if (!patre) + char error[120]; + PCRE2_SIZE erroffset; + int err; + patre = pcre2_compile(reinterpret_cast<PCRE2_SPTR>(regexp.c_str()), + PCRE2_ZERO_TERMINATED, PCRE2_UTF, + &err, &erroffset, NULL); + if (!patre) { + pcre2_get_error_message(err, reinterpret_cast<PCRE2_UCHAR *>(error), + sizeof(error)); throw std::logic_error("error compiling regex " + std::string(error)); + } } // sift items size_t n = 0; + md = pcre2_match_data_create_from_pattern(patre, NULL); for (std::vector<bool>::iterator i = items.begin(); i != items.end(); ++i, ++n) { if (*i) { const Item_handler &item = _items[n]; - int patres[2]; + PCRE2_SIZE *patres; - int substr_count = pcre_exec(patre, NULL, item.val.c_str(), static_cast<int>(item.val.size()), 0, 0, patres, - sizeof(patres) / sizeof(int)); + int substr_count = pcre2_match(patre, reinterpret_cast<PCRE2_SPTR>(item.val.c_str()), + item.val.size(), 0, 0, md, NULL); + patres = pcre2_get_ovector_pointer(md); - if (substr_count > 0 && patres[1] == (int)item.val.size()) + if (substr_count > 0 && patres[1] == item.val.size()) *i = match_means_visible; else *i = !match_means_visible; } } - pcre_free(patre); + pcre2_code_free(patre); + pcre2_match_data_free(md); } std::string GrtStringListModel::terminate_wildcard_symbols(const std::string &str) { --- mysql-workbench-8.0.32+dfsg.orig/backend/wbprivate/sqlide/wb_sql_editor_help.cpp +++ mysql-workbench-8.0.32+dfsg/backend/wbprivate/sqlide/wb_sql_editor_help.cpp @@ -21,7 +21,8 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <pcrecpp.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include <thread> #include <rapidjson/istreamwrapper.h> #include <fstream> @@ -142,9 +143,32 @@ return source; // We cannot use std::regex here atm, as this crashes on macOS. Maybe later... - std::string result = source; - static pcrecpp::RE pattern = "<xref linkend=\"([^\"]+)\" />"; - pattern.GlobalReplace("<a href='http://dev.mysql.com/doc/refman/{0}.{1}/en/\\1.html'>\\1</a>", &result); + pcre2_code *re; + PCRE2_UCHAR *out; + PCRE2_SPTR pattern, subj, repl; + PCRE2_SIZE offset; + int rc; + std::string result; + + pattern = reinterpret_cast<PCRE2_SPTR>("<xref linkend=\"([^\"]+)\" />"); + subj = reinterpret_cast<PCRE2_SPTR>(source.c_str()); + repl = reinterpret_cast<PCRE2_SPTR>("<a href='http://dev.mysql.com/doc/refman/{0}.{1}/en/${1}.html'>${1}</a>"); + re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &rc, &offset, NULL); + offset = 512; + out = (PCRE2_UCHAR *)malloc(offset); + rc = pcre2_substitute(re, subj, PCRE2_ZERO_TERMINATED, 0, + PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_GLOBAL + | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, NULL, NULL, + repl, PCRE2_ZERO_TERMINATED, out, &offset); + if (rc == PCRE2_ERROR_NOMEMORY) { + out = (PCRE2_UCHAR *)realloc(out, offset); + pcre2_substitute(re, subj, PCRE2_ZERO_TERMINATED, 0, + PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_GLOBAL, + NULL, NULL, repl, PCRE2_ZERO_TERMINATED, out, &offset); + } + result = reinterpret_cast<char *>(out); + pcre2_code_free(re); + free(out); result = base::replaceString(result, "{0}", std::to_string(version / 100)); result = base::replaceString(result, "{1}", std::to_string(version % 10)); @@ -158,9 +182,32 @@ if (source.find("<link") == std::string::npos) return source; - std::string result = source; - static pcrecpp::RE pattern = "<link linkend=\"([^\"]+)\">([^<]+)<\\/link>"; - pattern.GlobalReplace("<a href='http://dev.mysql.com/doc/refman/{0}.{1}/en/glossary.html#\\1'>\\2</a>", &result); + pcre2_code *re; + PCRE2_UCHAR *out; + PCRE2_SPTR pattern, subj, repl; + PCRE2_SIZE offset; + int rc; + std::string result; + + pattern = reinterpret_cast<PCRE2_SPTR>("<link linkend=\"([^\"]+)\">([^<]+)<\\/link>"); + subj = reinterpret_cast<PCRE2_SPTR>(source.c_str()); + repl = reinterpret_cast<PCRE2_SPTR>("<a href='http://dev.mysql.com/doc/refman/{0}.{1}/en/glossary.html#${1}'>${2}</a>"); + re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &rc, &offset, NULL); + offset = 512; + out = (PCRE2_UCHAR *)malloc(offset); + rc = pcre2_substitute(re, subj, PCRE2_ZERO_TERMINATED, 0, + PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_GLOBAL + | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, NULL, NULL, + repl, PCRE2_ZERO_TERMINATED, out, &offset); + if (rc == PCRE2_ERROR_NOMEMORY) { + out = (PCRE2_UCHAR *)realloc(out, offset); + pcre2_substitute(re, subj, PCRE2_ZERO_TERMINATED, 0, + PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_GLOBAL, + NULL, NULL, repl, PCRE2_ZERO_TERMINATED, out, &offset); + } + result = reinterpret_cast<char *>(out); + pcre2_code_free(re); + free(out); result = base::replaceString(result, "{0}", std::to_string(version / 100)); result = base::replaceString(result, "{1}", std::to_string(version % 10)); @@ -173,9 +220,33 @@ if (source.find("role=\"stmt\"") == std::string::npos) return source; - std::string result = source; - static pcrecpp::RE pattern = "<literal role=\"stmt\">([^<]+)</literal>"; - pattern.GlobalReplace("<a href='local:\\1'>\\1</a>", &result); + pcre2_code *re; + PCRE2_UCHAR *out; + PCRE2_SPTR pattern, subj, repl; + PCRE2_SIZE offset; + int rc; + std::string result; + + pattern = reinterpret_cast<PCRE2_SPTR>("<literal role=\"stmt\">([^<]+)</literal>"); + subj = reinterpret_cast<PCRE2_SPTR>(source.c_str()); + repl = reinterpret_cast<PCRE2_SPTR>("<a href='local:${1}'>${1}</a>"); + re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &rc, &offset, NULL); + offset = 512; + out = (PCRE2_UCHAR *)malloc(offset); + rc = pcre2_substitute(re, subj, PCRE2_ZERO_TERMINATED, 0, + PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_GLOBAL + | PCRE2_SUBSTITUTE_OVERFLOW_LENGTH, NULL, NULL, + repl, PCRE2_ZERO_TERMINATED, out, &offset); + if (rc == PCRE2_ERROR_NOMEMORY) { + out = (PCRE2_UCHAR *)realloc(out, offset); + pcre2_substitute(re, subj, PCRE2_ZERO_TERMINATED, 0, + PCRE2_SUBSTITUTE_EXTENDED | PCRE2_SUBSTITUTE_GLOBAL, + NULL, NULL, repl, PCRE2_ZERO_TERMINATED, out, &offset); + } + result = reinterpret_cast<char *>(out); + pcre2_code_free(re); + free(out); + return result; } --- mysql-workbench-8.0.32+dfsg.orig/backend/wbprivate/sqlide/wb_sql_editor_tree_controller.cpp +++ mysql-workbench-8.0.32+dfsg/backend/wbprivate/sqlide/wb_sql_editor_tree_controller.cpp @@ -37,7 +37,8 @@ #include "workbench/wb_command_ui.h" #include "workbench/wb_context_ui.h" -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include <boost/signals2/connection.hpp> @@ -902,6 +903,24 @@ std::unique_ptr<sql::ResultSet> rs( stmt->executeQuery(std::string(base::sqlstring("SHOW CREATE TABLE !.!", 0) << schema_name << obj_name))); + pcre2_code *patre; + pcre2_match_data *md; + char errptr[120]; + PCRE2_SIZE erroffs; + int err; + const char *pattern = + "CONSTRAINT\\s*(\\S*)\\s*FOREIGN " + "KEY\\s*\\((\\S*)\\)\\s*REFERENCES\\s*(\\S*)\\s*\\((\\S*)\\)\\s*((\\w*\\s*)*),?$"; + + patre = pcre2_compile(reinterpret_cast<PCRE2_SPTR>(pattern), + PCRE2_ZERO_TERMINATED, 0, &err, &erroffs, NULL); + if (!patre) { + pcre2_get_error_message(err, reinterpret_cast<PCRE2_UCHAR *>(errptr), + sizeof(errptr)); + throw std::logic_error("error compiling regex " + std::string(errptr)); + } + md = pcre2_match_data_create(64, NULL); + while (rs->next()) { std::string statement = rs->getString(2); @@ -910,51 +929,40 @@ std::vector<std::string> def_lines = base::split(statement.substr(def_start, def_end - def_start), "\n"); - const char *errptr; - int erroffs = 0; - const char *pattern = - "CONSTRAINT\\s*(\\S*)\\s*FOREIGN " - "KEY\\s*\\((\\S*)\\)\\s*REFERENCES\\s*(\\S*)\\s*\\((\\S*)\\)\\s*((\\w*\\s*)*),?$"; - int patres[64]; - - pcre *patre = pcre_compile(pattern, 0, &errptr, &erroffs, NULL); - if (!patre) - throw std::logic_error("error compiling regex " + std::string(errptr)); - std::string fk_name; std::string fk_columns; std::string fk_ref_table; std::string fk_ref_columns; std::string fk_rules; - const char *value; + PCRE2_UCHAR *value; for (size_t index = 0; index < def_lines.size(); index++) { - int rc = pcre_exec(patre, NULL, def_lines[index].c_str(), (int)def_lines[index].length(), 0, 0, patres, - sizeof(patres) / sizeof(int)); + int rc = pcre2_match(patre, reinterpret_cast<PCRE2_SPTR>(def_lines[index].c_str()), + def_lines[index].length(), 0, 0, md, NULL); if (rc > 0) { // gets the values timestamp and - pcre_get_substring(def_lines[index].c_str(), patres, rc, 1, &value); - fk_name = value; - pcre_free_substring(value); + pcre2_substring_get_bynumber(md, 1, &value, &erroffs); + fk_name = reinterpret_cast<char *>(value); + pcre2_substring_free(value); fk_name = base::unquote_identifier(fk_name); - pcre_get_substring(def_lines[index].c_str(), patres, rc, 2, &value); - fk_columns = value; - pcre_free_substring(value); - - pcre_get_substring(def_lines[index].c_str(), patres, rc, 3, &value); - fk_ref_table = value; - pcre_free_substring(value); + pcre2_substring_get_bynumber(md, 2, &value, &erroffs); + fk_columns = reinterpret_cast<char *>(value); + pcre2_substring_free(value); + + pcre2_substring_get_bynumber(md, 3, &value, &erroffs); + fk_ref_table = reinterpret_cast<char *>(value); + pcre2_substring_free(value); fk_ref_table = base::unquote_identifier(fk_ref_table); - pcre_get_substring(def_lines[index].c_str(), patres, rc, 4, &value); - fk_ref_columns = value; - pcre_free_substring(value); - - pcre_get_substring(def_lines[index].c_str(), patres, rc, 5, &value); - fk_rules = value; - pcre_free_substring(value); + pcre2_substring_get_bynumber(md, 4, &value, &erroffs); + fk_ref_columns = reinterpret_cast<char *>(value); + pcre2_substring_free(value); + + pcre2_substring_get_bynumber(md, 5, &value, &erroffs); + fk_rules = reinterpret_cast<char *>(value); + pcre2_substring_free(value); // Parses the list fields std::vector<std::string> fk_column_list = base::split(fk_columns, ","); @@ -1015,6 +1023,8 @@ } } } + pcre2_match_data_free(md); + pcre2_code_free(patre); // Searches for the target node... mforms::TreeNodeRef node = _schema_tree->get_node_for_object(schema_name, type, obj_name); --- mysql-workbench-8.0.32+dfsg.orig/tools/genwrap/genwrap.cpp +++ mysql-workbench-8.0.32+dfsg/tools/genwrap/genwrap.cpp @@ -23,7 +23,8 @@ #include <glib.h> #include <string.h> -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include <algorithm> #include "base/log.h" @@ -81,24 +82,35 @@ exit(1); } - const char *errs; - int erro; - pcre *pat = pcre_compile("^\\s*DECLARE_REGISTER_INTERFACE\\(\\s*(\\w+)Impl\\s*,", 0, &errs, &erro, NULL); + pcre2_code *pat; + pcre2_match_data *md; + PCRE2_SPTR p; + PCRE2_UCHAR errs[120]; + PCRE2_SIZE erro; + int err; + p = reinterpret_cast<PCRE2_SPTR>("^\\s*DECLARE_REGISTER_INTERFACE\\(\\s*(\\w+)Impl\\s*,"); + pat = pcre2_compile(p, PCRE2_ZERO_TERMINATED, 0, &err, &erro, NULL); if (!pat) { fclose(f); + pcre2_get_error_message(err, errs, sizeof(errs)); fprintf(stderr, "ERROR compiling internal regex pattern (%s)\n", errs); exit(1); } + md = pcre2_match_data_create(6, NULL); while (fgets(line, sizeof(line), f)) { - int vec[6]; - - if (pcre_exec(pat, NULL, line, static_cast<int>(strlen(line)), 0, 0, vec, 6) == 2) { + if (pcre2_match(pat, reinterpret_cast<PCRE2_SPTR>(line), strlen(line), + 0, 0, md, NULL) == 2) { char buf[1024]; - pcre_copy_substring(line, vec, 2, 1, buf, sizeof(buf)); + erro = sizeof(buf); + pcre2_substring_copy_bynumber(md, 1, + reinterpret_cast<PCRE2_UCHAR *>(buf), + &erro); interfaces.push_back(buf); } } + pcre2_code_free(pat); + pcre2_match_data_free(md); fclose(f); do_generate_interface_classes(outfile, interfaces); --- mysql-workbench-8.0.32+dfsg.orig/modules/db.mysql/src/module_db_mysql.cpp +++ mysql-workbench-8.0.32+dfsg/modules/db.mysql/src/module_db_mysql.cpp @@ -22,7 +22,8 @@ */ #ifndef _MSC_VER -#include <pcre.h> +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> #include <stdio.h> #endif @@ -1483,33 +1484,42 @@ // views void ActionGenerateSQL::create_view(db_mysql_ViewRef view) { - const char* errptr; - int erroffs; + pcre2_match_data *md; + int errptr; + PCRE2_SIZE erroffs; bool or_replace_present = false; - int patres[3]; + PCRE2_SIZE *patres; std::string view_def; view_def.append(view->sqlDefinition().c_str()); - pcre* patre = - pcre_compile("^\\s*CREATE\\s+OR\\s+REPLACE\\s+", PCRE_CASELESS | PCRE_MULTILINE, &errptr, &erroffs, NULL); - if (patre && (pcre_exec(patre, NULL, view_def.c_str(), (int)view_def.length(), 0, 0, patres, - sizeof(patres) / sizeof(int)) > 0)) { + pcre2_code* patre = + pcre2_compile(reinterpret_cast<PCRE2_SPTR>("^\\s*CREATE\\s+OR\\s+REPLACE\\s+"), + PCRE2_ZERO_TERMINATED, PCRE2_CASELESS | PCRE2_MULTILINE, + &errptr, &erroffs, NULL); + md = pcre2_match_data_create(3, NULL); + if (patre && (pcre2_match(patre, reinterpret_cast<PCRE2_SPTR>(view_def.c_str()), + view_def.length(), 0, 0, md, NULL) > 0)) { or_replace_present = true; } if (patre) - pcre_free(patre); + pcre2_code_free(patre); if (!or_replace_present) { - patre = pcre_compile("^\\s*CREATE\\s+", PCRE_CASELESS | PCRE_MULTILINE, &errptr, &erroffs, NULL); - if (patre && (pcre_exec(patre, NULL, view_def.c_str(), (int)view_def.length(), 0, 0, patres, - sizeof(patres) / sizeof(int)) > 0)) + patre = pcre2_compile(reinterpret_cast<PCRE2_SPTR>("^\\s*CREATE\\s+"), + PCRE2_ZERO_TERMINATED, + PCRE2_CASELESS | PCRE2_MULTILINE, &errptr, &erroffs, NULL); + if (patre && (pcre2_match(patre, reinterpret_cast<PCRE2_SPTR>(view_def.c_str()), + view_def.length(), 0, 0, md, NULL) > 0)) { + patres = pcre2_get_ovector_pointer(md); view_def.insert(patres[1], " OR REPLACE "); + } if (patre) - pcre_free(patre); + pcre2_code_free(patre); } + pcre2_match_data_free(md); if (_omitSchemas) { SqlFacade* parser = SqlFacade::instance_for_rdbms_name("Mysql");