]> wimlib.net Git - wimlib/commitdiff
encoding.c: avoid UBSAN warning in convert_string()
authorEric Biggers <ebiggers3@gmail.com>
Tue, 28 Mar 2023 06:14:42 +0000 (23:14 -0700)
committerEric Biggers <ebiggers3@gmail.com>
Tue, 28 Mar 2023 06:25:17 +0000 (23:25 -0700)
When 'in == NULL && in_nbytes == 0', the statement 'in_end = in +
in_nbytes' executes 'NULL + 0'.  clang's UndefinedBehaviorSanitizer
complains that this is undefined:

    src/encoding.c:223:31: runtime error: applying zero offset to null pointer

This is questionable, but let's avoid it...

src/encoding.c

index 9337c9a16e6a277b2f4880058103b4cdd1377eee..a1407b322843c04c4ed249f1c033f9f29f04432c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * encoding.c - UTF-8 and UTF-16LE codecs and utility functions
  *
- * Copyright (C) 2012-2016 Eric Biggers
+ * Copyright 2012-2023 Eric Biggers
  *
  * This file is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License as published by the Free
@@ -220,8 +220,7 @@ convert_string(const u8 * const in, const size_t in_nbytes,
               decode_codepoint_fn decode_codepoint,
               encode_codepoint_fn encode_codepoint)
 {
-       const u8 * const in_end = in + in_nbytes;
-       const u8 *p_in;
+       size_t i;
        u8 *p_out;
        size_t out_nbytes = 0;
        u8 *out;
@@ -229,8 +228,8 @@ convert_string(const u8 * const in, const size_t in_nbytes,
        u32 c;
 
        /* Validate the input string and compute the output size. */
-       for (p_in = in; p_in != in_end; ) {
-               p_in += (*decode_codepoint)(p_in, in_end - p_in, true, &c);
+       for (i = 0; i < in_nbytes; ) {
+               i += (*decode_codepoint)(&in[i], in_nbytes - i, true, &c);
                if (unlikely(c == INVALID_CODEPOINT)) {
                        errno = EILSEQ;
                        return ilseq_err;
@@ -244,8 +243,9 @@ convert_string(const u8 * const in, const size_t in_nbytes,
                return WIMLIB_ERR_NOMEM;
 
        /* Do the conversion. */
-       for (p_in = in, p_out = out; p_in != in_end; ) {
-               p_in += (*decode_codepoint)(p_in, in_end - p_in, false, &c);
+       p_out = out;
+       for (i = 0; i < in_nbytes; ) {
+               i += (*decode_codepoint)(&in[i], in_nbytes - i, false, &c);
                p_out += (*encode_codepoint)(c, p_out);
        }