// // Copyright (c) 2019-2024 Ruben Perez Hidalgo (rubenperez038 at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #ifndef BOOST_MYSQL_ESCAPE_STRING_HPP #define BOOST_MYSQL_ESCAPE_STRING_HPP #include #include #include #include #include namespace boost { namespace mysql { struct format_options; /** * \brief (EXPERIMENTAL) Identifies the context which a string is being escaped for. */ enum class quoting_context : char { /// The string is surrounded by double quotes. double_quote = '"', /// The string is surrounded by single quotes. single_quote = '\'', /// The string is surrounded by backticks. backtick = '`', }; /** * \brief (EXPERIMENTAL) Escapes a string, making it safe for query composition. * \details * Given a string `input`, computes a string with special characters * escaped, and places it in `output`. This function is a low-level building * block for composing client-side queries with runtime string values without * incurring in SQL injection vulnerabilities. * If you can, prefer using higher-level functions like \ref format_sql. * \n * Escaping rules are different depending on the context a string is * being used in. `quot_ctx` identifies where the string will appear in * a query. Possible values are: \n * \li \ref quoting_context::double_quote : the string is surrounded by * double quotes. For example: * \code "SELECT * FROM employee WHERE company = \"\"" \endcode * \li \ref quoting_context::single_quote : the string is surrounded by * single quotes. For example: * \code "SELECT * FROM employee WHERE company = ''" \endcode * \li \ref quoting_context::backtick : the string is surrounded by * backticks. This may happen when escaping identifiers. For example: * \code "SELECT `` FROM employee" \endcode * \n * By default, MySQL treats backslash characters as escapes in string values * (for instance, the string `"\n"` is treated as a newline). This behavior is * enabled by default, but can be disabled by enabling the * `NO_BACKSLASH_ESCAPES` * SQL mode. When enabled, backslashes no longer have a special meaning, which changes * the escaping rules. `opts.backslash_escapes` should be set to `true` if backslashes represent * escapes (i.e. `NO_BACKSLASH_ESCAPES` is not enabled), and `false` otherwise. * \n * MySQL can be configured to treat double-quoted strings as identifiers instead of values. * This is enabled by activating the * `ANSI_QUOTES` or * `ANSI` SQL modes. * Servers don't report whether this mode is enabled to clients. * This SQL mode is not directly supported by this function. * \n * `opts.charset` should identify the connection's character set (as given by the * `character_set_client` session variable). The character set is used to iterate * over the input string. It must be an ASCII-compatible character set (like \ref utf8mb4_charset). * All character sets allowed by `character_set_client` satisfy this requirement. * \n * You can use \ref any_connection::format_opts to retrieve an `opts` value suitable for your connection. * \n * \par Exception safety * Basic guarantee. Memory allocations may throw. * * \par Complexity * Linear in `input.size()`. * * \par Errors * \ref client_errc::invalid_encoding if `input` contains a string * that is not valid according to `opts.charset`. */ template BOOST_ATTRIBUTE_NODISCARD error_code escape_string(string_view input, const format_options& opts, quoting_context quot_ctx, OutputString& output) { output.clear(); return detail::escape_string( input, opts, static_cast(quot_ctx), detail::output_string_ref::create(output) ); } } // namespace mysql } // namespace boost #endif