Commit graph

329 commits

Author SHA1 Message Date
Marko Mäkelä
ccb7a1e9a1 Merge 10.5 into 10.6 2024-03-27 15:00:56 +02:00
Alexander Barkov
0fc123c595 MDEV-33772 Bad SEPARATOR value in GROUP_CONCAT on character set conversion
Item_func_group_concat::print() did not take into account
that Item_func_group_concat::separator can be of a different character set
than the "String *str" (when the printing is being done to).
Therefore, printing did not work correctly for:
- non-ASCII separators when GROUP_CONCAT is done on 8bit data
  or multi-byte data with mbminlen==1.
- all separators (even including simple ones like comma)
  when GROUP_CONCAT is done on ucs2/utf16/utf32 data (mbminlen>1).

Because of this problem, VIEW definitions did not print correctly to
their FRM files. This later led to a wrong SELECT and SHOW CREATE output.

Fix:

- Adding new String methods:

  bool append_for_single_quote_using_mb_wc(const char *str, size_t length,
                                           CHARSET_INFO *cs);

  bool append_for_single_quote_opt_convert(const char *str,
                                           size_t length,
                                           CHARSET_INFO *cs)

  which perform both escaping and character set conversion at the same time.

- Adding a new String method escaped_wc_for_single_quote(),
  to reuse the code between the old and the new methods.

- Fixing Item_func_group_concat::print() to use the new
  method append_for_single_quote_opt_convert().
2024-03-27 15:22:58 +04:00
Oleksandr Byelkin
b83c379420 Merge branch '10.5' into 10.6 2023-11-08 15:57:05 +01:00
Oleksandr Byelkin
6cfd2ba397 Merge branch '10.4' into 10.5 2023-11-08 12:59:00 +01:00
Alexander Barkov
e2da748c29 MDEV-28835 Assertion `(length % 4) == 0' failed in my_lengthsp_utf32 on INSERT
Problem:

Item_func_date_format::val_str() and make_date_time() did not take into
account that the format string and the result string
(separately or at the same time) can be of a tricky character set
like UCS2, UTF16, UTF32. As a result, DATE_FORMAT() could generate
an ill-formed result which crashed on DBUG_ASSERTs testing well-formedness
in other parts of the code.

Fix:

1. class String changes
   Removing String::append_with_prefill(). It was not compatible with
   tricky character sets. Also it was inconvenient to use and required
   too much duplicate code on the caller side.
   Adding String::append_zerofill() instead. It's compatible with tricky
   character sets and is easier to use.
   Adding helper methods Static_binary_string::q_append_wc() and
   String::append_wc(), to append a single wide character
   (a Unicode code point in my_wc_t).

2. storage/spider changes
   Removing spider_string::append_with_prefill().
   It used String::append_with_prefix() inside, but it was unused itself.

3. Changing tricky charset incompatible code pieces in make_date_time()
   to compatible replacements:

   - Fixing the loop scanning the format string to iterate in terms
     of Unicode code points (using mb_wc()) rather than in terms
     of "char" items.
   - Using append_wc(my_wc_t) instead of append(char) to append
     a single character to the result string.
   - Using append_zerofill() instead of append_with_prefill() to
     append date/time numeric components to the result string.
2023-10-04 08:51:48 +04:00
Oleksandr Byelkin
6bf8483cac Merge branch '10.5' into 10.6 2023-08-01 15:08:52 +02:00
Oleksandr Byelkin
f52954ef42 Merge commit '10.4' into 10.5 2023-07-20 11:54:52 +02:00
Sergei Golubchik
a4817e1520 cleanup: String::strstr() const 2023-07-04 16:37:29 +02:00
Sergei Golubchik
c05ecda61f fix string literal escaping in views
process multibyte characters correctly, don't escape half of the character
2023-06-02 17:51:40 +02:00
Marko Mäkelä
5bada1246d Merge 10.5 into 10.6 2023-04-11 16:15:19 +03:00
Oleksandr Byelkin
ac5a534a4c Merge remote-tracking branch '10.4' into 10.5 2023-03-31 21:32:41 +02:00
Anel Husakovic
560c15c44b MDBF-534: Coverity scan: fix client folder
---------------------------------
File: `mysql`
---------------------------------

- Coverity (RESOURCE_LEAK):
  https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53073025&mergedDefectId=1520090&eventId=53073025-15

  `mysql`: memory allocated by `mysql_fetch_row` is not freed.

- FALSE POSITIVES:
  - Coverity (TAINTED_SCALAR):
    - https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53074559&mergedDefectId=1520403
  - Coverity (COPY_PASTE_ERROR):
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53074521&mergedDefectId=1520300
  - Coverity (STRING_NULL):
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53072524&mergedDefectId=1519374
  - Coverity (CHECKED_RETURN):
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53074932&mergedDefectId=971708

- INTENTIONAL:
  - Coverity (UNINIT):
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53074758&mergedDefectId=1519932
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53073939&mergedDefectId=1519738
  - Coverity(BAD_FREE):
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53073938&mergedDefectId=1519491
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728394&defectInstanceId=53074819&mergedDefectId=1519462

---------------------------------
File: `mysql_plugin`
---------------------------------

- Coverity (FORWARD_NULL):
  https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728420&defectInstanceId=53074485&mergedDefectId=971915

  Dereference after null check when using `fclose`.

- FALSE POSITIVES:
  - Coverity (STRING_OVERFLOW):
    https://scan5.scan.coverity.com/reports.htm#v58936/p10357/fileInstanceId=231728420&defectInstanceId=53075014&mergedDefectId=972410

- Additionally fix typo
2023-02-17 13:43:43 +00:00
Vicențiu Ciorbaru
c115559b66 Extend Binary_string::strstr to also take in a const char pointer
One shouldn't have to instantiate a Binary_string every time a strstr
call is needed.
2023-02-03 16:27:16 +02:00
Sergei Golubchik
900d7bf360 Merge branch '10.5' into 10.6 2022-10-02 22:14:21 +02:00
Sergei Golubchik
3a2116241b Merge branch '10.4' into 10.5 2022-10-02 14:38:13 +02:00
Alexander Barkov
1118e979c2 MDEV-29672 Add MTR tests covering key and key segment flags and types 2022-09-30 11:08:49 +04:00
Norio Akagi
84d26f98c7
MDEV-28315 Fix ASAN stack-buffer-overflow in String::copy_aligned
Starting since this commit 36cdd5c3cd
there is an ASAN stack-buffer-overflow error because we append a NULL
terminator beyond the length of memory allocated.

Reviewed by: Monty and Nayuta Yanagisawa
2022-08-01 20:27:33 +09:00
Marko Mäkelä
d8c6c53a06 Merge 10.5 into 10.6 2021-10-28 09:08:58 +03:00
Marko Mäkelä
a8ded39557 Merge 10.4 into 10.5 2021-10-28 08:48:36 +03:00
Marko Mäkelä
3a79e5fd31 Merge 10.3 into 10.4 2021-10-28 08:28:39 +03:00
Marko Mäkelä
657bcf928e Merge 10.2 into 10.3 2021-10-28 07:50:05 +03:00
Alexander Barkov
2ed148c8d7 MDEV-25402 Assertion `!str || str != Ptr' failed in String::copy
The assert inside String::copy() prevents copying from from "str"
if its own String::Ptr also points to the same memory.

The idea of the assert is that copy() performs memory reallocation,
and this reallocation can free (and thus invalidate) the memory pointed by Ptr,
which can lead to further copying from a freed memory.

The assert was incomplete: copy() can free the memory pointed by its Ptr
only if String::alloced is true!

If the String is not alloced, it is still safe to copy even from
the location pointed by Ptr.

This scenario demonstrates a safe copy():
  const char *tmp= "123";
  String str1(tmp, 3);
  String str2(tmp, 3);
  // This statement is safe:
  str2.copy(str1->ptr(), str1->length(), str1->charset(), cs_to, &errors);

Inside the copy() the parameter "str" is equal to String::Ptr in this example.
But it's still ok to reallocate the memory for str2, because str2
was a constant before the copy() call. Thus reallocation does not
make the memory pointed by str1->ptr() invalid.

Adjusting the assert condition to allow copying for constant strings.
2021-10-27 10:50:15 +04:00
Sergei Golubchik
3648b333c7 cleanup: formatting
also avoid an oxymoron of using `MYSQL_PLUGIN_IMPORT` under
`#ifdef MYSQL_SERVER`, and empty_clex_str is so trivial that a plugin
can define it if needed.
2021-06-11 13:02:55 +02:00
Monty
e45b54b75d Removed Static_binary_string
This did not server any real purpose and also made it too difficult to add
asserts for string memory overrwrites.

Moved all functionallity from Static_binary_string to Binary_string.

Other things:
- Added asserts to q_xxx and qs_xxx functions to check for memory overruns
- Fixed wrong test in String_buffer::set_buffer_if_not_allocated().
  The idea is to reuse allocated buffers (to avoid extra allocs), which
  the code did not do.
2021-05-19 22:54:12 +02:00
Monty
eb73245e30 Ensure that we do not allocate strings bigger than 4G in String objects.
This is needed as we are using uint32 for allocated and current length.
2021-05-19 22:54:12 +02:00
Monty
81d9bed3a4 MDEV-20017 Implement TO_CHAR() Oracle compatible function
TO_CHAR(expr, fmt)
- expr: required parameter, data/time/timestamp type expression
- fmt: optional parameter, format string, supports
  YYYY/YYY/YY/RRRR/RR/MM/MON/MONTH/MI/DD/DY/HH/HH12/HH24/SS and special
  characters. The default value is "YYYY-MM-DD HH24:MI:SS"

In Oracle, TO_CHAR() can also be used to convert numbers to strings, but
this is not supported. This will gave an error in this patch.

Other things:
- If format strings is a constant, it's evaluated only once and if there
  is any errors in it, they are given at once and the statement will abort.

Original author: woqutech
Lots of optimizations and cleanups done as part of review
2021-05-19 22:54:12 +02:00
Monty
949d10bea2 Don't reset StringBuffers in loops when not needed
- Moved out creating StringBuffers in loops and instead create them
  outside and just reset the buffer if it was not allocated (to avoid
  a possible malloc/free for every entry)

Other things related to set_buffer_if_not_allocated()
- Changed Valuebuffer to not call set_buffer_if_not_allocated() when
  it is created.
- Fixed geometry functions to reset string length before calling
  String::reserve().  This is because one should not access length()
  of an undefined.
- Added Item_func_conv_charset::save_in_field() as the item is using
  str_value to store cached values, which conflicts with
  Item::save_str_in_field().
- Changed Item_proc_string to not store the string value in sql_string
  as this clashes with Item::save_str_in_field().
- Locally store value of full_name_cstring() in analyse::end_of_records()
  as Item::save_str_in_field() may overwrite it.
- Marked some strings as set_thread_specific()
- Added String::free_buffer() to be used internally in String functions
  to just free the buffer but not reset other String values.
- Fixed uses_buffer_owned_by() to check for allocated length instead of
  strlength, which could be marked MEM_UNDEFINED().
2021-05-19 22:54:11 +02:00
Monty
36cdd5c3cd Optimize usage of c_ptr(), c_ptr_quick() and String::alloc()
The problem was that when one used String::alloc() to allocate a string,
the String ensures that there is space for an extra NULL byte in the
buffer and if not, reallocates the string. This is a problem with the
String::set_int() that calls alloc(21), which forces extra
malloc/free calls to happen.

- We do not anymore re-allocate String if alloc() is called with the
  Allocated_length. This reduces number of malloc() allocations,
  especially one big re-allocation in Protocol::send_result_Set_metadata()
  for almost every query that produced a result to the connnected client.
- Avoid extra mallocs when using LONGLONG_BUFFER_SIZE
  This can now be done as alloc() doesn't increase buffers if new length is
  not bigger than old one.
- c_ptr() is redesigned to be safer (but a bit longer) than before.
- Remove wrong usage of c_ptr_quick()
  c_ptr_quick() was used in many cases to get the pointer to the used
  buffer, even when it didn't need to be \0 terminated. In this case
  ptr() is a better substitute.
  Another problem with c_ptr_quick() is that it did not guarantee that
  the string would be \0 terminated.
- item_val_str(), an API function not used currently by the server,
  now always returns a null terminated string (before it didn't always
  do that).
- Ensure that all String allocations uses STRING_PSI_MEMORY_KEY. The old
  mixed usage of performance keys caused assert's when String buffers
  where shrunk.
- Binary_string::shrink() is simplifed
- Fixed bug in String(const char *str, size_t len, CHARSET_INFO *cs) that
  used Binary_string((char *) str, len) instead of Binary_string(str,len).
- Changed argument to String() creations and String.set() functions to use
  'const char*' instead of 'char*'. This ensures that Alloced_length is
  not set, which gives safety against someone trying to change the
  original string. This also would allow us to use !Alloced_length in
  c_ptr() if needed.
- Changed string_ptr_cmp() to use memcmp() instead of c_ptr() to avoid
  a possible malloc during string comparision.
2021-05-19 22:27:27 +02:00
Marko Mäkelä
133b4b46fe Merge 10.4 into 10.5 2020-11-03 16:24:47 +02:00
Marko Mäkelä
533a13af06 Merge 10.3 into 10.4 2020-11-03 14:49:17 +02:00
Marko Mäkelä
c7f322c91f Merge 10.2 into 10.3 2020-11-02 15:48:47 +02:00
Marko Mäkelä
8036d0a359 MDEV-22387: Do not violate __attribute__((nonnull))
This follows up commit
commit 94a520ddbe and
commit 7c5519c12d.

After these changes, the default test suites on a
cmake -DWITH_UBSAN=ON build no longer fail due to passing
null pointers as parameters that are declared to never be null,
but plenty of other runtime errors remain.
2020-11-02 14:19:21 +02:00
Vicențiu Ciorbaru
85c686e2d1 cleanup: Static_binary_string need not take non-const double parameter
Convert the parameter to const as the function won't modify the pointer
value.
2020-10-28 11:38:14 +02:00
Sujatha
25ede13611 Merge branch '10.4' into 10.5 2020-09-29 16:59:36 +05:30
Sujatha
ce845b7a2f Merge branch '10.3' into 10.4 2020-09-28 17:55:39 +05:30
Sujatha
6cbbd6bd96 Merge branch '10.2' into 10.3 2020-09-28 17:27:42 +05:30
Marko Mäkelä
7c5519c12d MDEV-22387: Do not violate __attribute__((nonnull))
Passing a null pointer to a nonnull argument is not only undefined
behaviour, but it also grants the compiler the permission to optimize
away further checks whether the pointer is null. GCC -O2 at least
starting with version 8 may do that, potentially causing SIGSEGV.
2020-09-23 12:47:49 +03:00
Marko Mäkelä
1c58748196 Merge 10.4 into 10.5 2020-08-10 21:38:55 +03:00
Alexander Barkov
fe555b9c5f MDEV-23415 Server crash or Assertion `dec_length <= str_length' failed in Item_func_format::val_str_ascii
Problem:

The crash happened in FORMAT(double, dec>=31, 'de_DE').

The patch for MDEV-23118 (commit 0041dacc1b)
did not take into account that String::set_real() has a limit of 31
(FLOATING_POINT_DECIMALS) fractional digits. So for the range of 31..38
digits, set_real() switches to use:
- my_fcvt() - decimal point notation, e.g. 1.9999999999
- my_gcvt() - scientific notation,    e.g. 1e22

my_gcvt() returned a shorter string than Item_func_format::val_str_ascii()
expected to get after the my_fcvt() call, so it crashed on assert.

Solution:

We cannot extend set_real() to use the my_fcvt() mode for the range of
31..38 fractional digits, because set_real() is used in a lot of places
and such a change will break everything.

Introducing String::set_fcvt() which always prints using my_fcvt()
for the whole range of decimals 0..38, supported by the FORMAT() function.
2020-08-08 09:44:31 +04:00
Alexander Barkov
cfe5ee90c8 MDEV-22043 Special character leads to assertion in my_wc_to_printable_generic on 10.5.2 (debug)
The code did not take into account that:
- U+005C (backslash) can occupy more than mbminlen characters (e.g. in sjis)
- Some character sets do not have a code for U+005C (e.g. swe7)

Adding a new function my_wc_to_printable into MY_CHARSET_HANDLER to
cover all special cases easier.
2020-05-09 16:01:30 +04:00
Sergei Golubchik
7c58e97bf6 perfschema memory related instrumentation changes 2020-03-10 19:24:22 +01:00
Alexander Barkov
f1e13fdc8d MDEV-21581 Helper functions and methods for CHARSET_INFO 2020-01-28 12:29:23 +04:00
Alexander Barkov
d30dbaa20d A cleanup for MDEV-8844: Fixing compilation failure on Windows
Fixing lossy type conversions:
- from int64 to int
- from size_t to uint
2019-12-07 19:12:04 +04:00
Alexander Barkov
3c6065a270 MDEV-8844 Unreadable control characters printed as is in warnings 2019-12-06 18:51:05 +04:00
Varun Gupta
4d5382504d MDEV-20349: Assertion `to_len >= 8' failed in convert_to_printable
Use convert_to_printable function to write only non-empty ranges to the optimizer trace
2019-08-16 16:49:12 +05:30
Varun Gupta
8b576616b4 MDEV-19776: Assertion `to_len >= 8' failed in convert_to_printable with optimizer trace enabled
Introduced the convert_to_printable_required_length to return the correct length(taking into
consideration of dots in the case of error messages).
2019-06-20 12:03:32 +05:30
Varun
a0cb7551a4 MDEV-18880: Optimizer trace prints date in hexadecimal
Introduced a print_key_value function to makes sure that the trace prints data in readable format
for readable characters and the rest of the characters are printed as hexadecimal.
2019-06-11 15:44:58 +05:30
Oleksandr Byelkin
c07325f932 Merge branch '10.3' into 10.4 2019-05-19 20:55:37 +02:00
Marko Mäkelä
be85d3e61b Merge 10.2 into 10.3 2019-05-14 17:18:46 +03:00
Marko Mäkelä
26a14ee130 Merge 10.1 into 10.2 2019-05-13 17:54:04 +03:00