Skip to content

Commit 8e1cedc

Browse files
committed
MDEV-35738 mariadb build -fsanitize=pointer-compare
invalid pointer pairs are when the length/memory of one string are intermixed with another. For comp_err, the end null pointer was compared to soffset within my_strtoll10. As we didn't need the end position a NULL arg option was compatble. For uca-dump, Address Sanitizer raises invalid pointer pair because argv options (opt) don't have an obvious correlation of having a start at opt_X.length, even though the lstrncmp makes this true. The DBUG_ASSERTS of strmov (added MDEV-11752) where incompatible with pointer-compare. Replaced strmov with static inline version in m_string.h using memmove that allows overlaps, and being inline allows the uneeded parts of the implementation to be optimized away.
1 parent 7efbb0d commit 8e1cedc

5 files changed

Lines changed: 28 additions & 60 deletions

File tree

extra/comp_err.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ static uint parse_input_file(const char *file_name, struct errors **top_error,
623623

624624
static uint parse_error_offset(char *str)
625625
{
626-
char *soffset, *end;
626+
char *soffset;
627627
int error;
628628
uint ioffset;
629629

@@ -651,8 +651,7 @@ static uint parse_error_offset(char *str)
651651
}
652652
DBUG_PRINT("info", ("str: %s", str));
653653

654-
end= 0;
655-
ioffset= (uint) my_strtoll10(soffset, &end, &error);
654+
ioffset= (uint) my_strtoll10(soffset, NULL, &error);
656655
my_free(soffset);
657656
DBUG_RETURN(ioffset);
658657
}

include/m_string.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,22 @@
6565
extern "C" {
6666
#endif
6767

68-
#ifdef DBUG_OFF
6968
#if defined(HAVE_STPCPY) && defined(__GNUC__) && !defined(__INTEL_COMPILER)
7069
#define strmov(A,B) __builtin_stpcpy((A),(B))
7170
#elif defined(HAVE_STPCPY)
7271
#define strmov(A,B) stpcpy((A),(B))
73-
#endif
74-
#endif
72+
#else
73+
static inline char *strmov(char *dst, const char *src) __attribute__((nonnull(1,2)))
74+
{
75+
size_t l;
76+
DBUG_ASSERT(dst != NULL);
77+
DBUG_ASSERT(src != NULL);
78+
79+
l= strlen(src);
80+
memmove(dst, src, l + 1);
81+
return dst + l;
82+
}
83+
#endif /* strmov */
7584

7685
/* Declared in int2str() */
7786
extern const char _dig_vec_upper[];

strings/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ SET(STRINGS_SOURCES bchange.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c
2424
ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c dtoa.c int2str.c
2525
ctype-unidata.c
2626
is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c
27-
str2int.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c
27+
str2int.c strcend.c strend.c strfill.c strmake.c strnmov.c
2828
strxmov.c strxnmov.c xml.c
2929
strmov_overlapp.c
3030
my_strchr.c strcont.c strappend.c json_lib.c json_normalize.c)

strings/strmov.c

Lines changed: 0 additions & 48 deletions
This file was deleted.

strings/uca-dump.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,14 +417,20 @@ static int process_option(OPT *options, const char *opt)
417417
static const LEX_CSTRING opt_levels= {STRING_WITH_LEN("--levels=")};
418418
static const LEX_CSTRING opt_no_contractions= {STRING_WITH_LEN("--no-contractions")};
419419
static const LEX_CSTRING opt_case_first= {STRING_WITH_LEN("--case-first=")};
420+
const char *eq = strchr(opt, '=');
420421
if (!lstrncmp(opt, opt_name_prefix))
421422
{
422-
options->name_prefix= opt + opt_name_prefix.length;
423+
if (!eq)
424+
return 1;
425+
426+
options->name_prefix = eq + 1;
423427
return 0;
424428
}
425429
if (!lstrncmp(opt, opt_levels))
426430
{
427-
options->levels= (uint) strtoul(opt + opt_levels.length, NULL, 10);
431+
if (!eq)
432+
return 1;
433+
options->levels= (uint) strtoul(eq + 1, NULL, 10);
428434
if (options->levels < 1 || options->levels > 3)
429435
{
430436
printf("Bad --levels value\n");
@@ -434,13 +440,15 @@ static int process_option(OPT *options, const char *opt)
434440
}
435441
if (!lstrncmp(opt, opt_case_first))
436442
{
437-
const char *value= opt + opt_case_first.length;
438-
if (!strcasecmp(value, "upper"))
443+
if (!eq)
444+
return 1;
445+
eq++;
446+
if (!strcasecmp(eq, "upper"))
439447
{
440448
options->case_first_upper= TRUE;
441449
return 0;
442450
}
443-
if (!strcasecmp(value, "lower"))
451+
if (!strcasecmp(eq, "lower"))
444452
{
445453
options->case_first_upper= FALSE;
446454
return 0;

0 commit comments

Comments
 (0)