Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use strnlen_s instead of strnlen if available #430

Open
wants to merge 2 commits into
base: rolling
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ set(rcutils_sources
src/strerror.c
src/string_array.c
src/string_map.c
src/strnlen.c
src/testing/fault_injection.c
src/time.c
${time_impl_c}
Expand Down Expand Up @@ -276,7 +277,7 @@ if(BUILD_TESTING)
)
if(TARGET test_error_handling_helpers)
target_include_directories(test_error_handling_helpers PUBLIC include)
target_link_libraries(test_error_handling_helpers osrf_testing_tools_cpp::memory_tools)
target_link_libraries(test_error_handling_helpers ${PROJECT_NAME} osrf_testing_tools_cpp::memory_tools)
endif()

ament_add_gtest(test_split
Expand Down
12 changes: 2 additions & 10 deletions include/rcutils/error_handling.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ extern "C"
{
#endif

#ifndef __STDC_WANT_LIB_EXT1__
#define __STDC_WANT_LIB_EXT1__ 1 // indicate we would like strnlen_s if available
#endif
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
Expand All @@ -36,23 +33,18 @@ extern "C"
#include "rcutils/allocator.h"
#include "rcutils/macros.h"
#include "rcutils/snprintf.h"
#include "rcutils/strnlen.h"
#include "rcutils/testing/fault_injection.h"
#include "rcutils/types/rcutils_ret.h"
#include "rcutils/visibility_control.h"

#ifdef __STDC_LIB_EXT1__
/// Write the given msg out to stderr, limiting the buffer size in the `fwrite`.
/**
* This ensures that there is an upper bound to a buffer overrun if `msg` is
* non-null terminated.
*/
#define RCUTILS_SAFE_FWRITE_TO_STDERR(msg) \
do {fwrite(msg, sizeof(char), strnlen_s(msg, 4096), stderr);} while (0)
#else
/// Write the given msg out to stderr.
#define RCUTILS_SAFE_FWRITE_TO_STDERR(msg) \
do {fwrite(msg, sizeof(char), strlen(msg), stderr);} while (0)
#endif
do {fwrite(msg, sizeof(char), rcutils_strnlen(msg, 4096), stderr);} while (0)

/// Set the error message to stderr using a format string and format arguments.
/**
Expand Down
44 changes: 44 additions & 0 deletions include/rcutils/strnlen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2023 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// \file

#ifndef RCUTILS__STRNLEN_H_
#define RCUTILS__STRNLEN_H_

#ifdef __cplusplus
extern "C"
{
#endif

#include "rcutils/macros.h"
#include "rcutils/visibility_control.h"

/// Determine the length of a fixed-size string
/**
* \param[in] s Null terminated string to find the length of.
* \param[in] maxlen Maximum length to look to find the trailing \0.
* \return The length of the string if it is less than maxlen, or
* \return maxlen if there is no \0 among the first maxlen characters.
*/
RCUTILS_PUBLIC
RCUTILS_WARN_UNUSED
size_t
rcutils_strnlen(const char * s, size_t maxlen);

#ifdef __cplusplus
}
#endif

#endif // RCUTILS__STRNLEN_H_
3 changes: 2 additions & 1 deletion src/error_handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ extern "C"
#include <rcutils/allocator.h>
#include <rcutils/macros.h>
#include <rcutils/strdup.h>
#include <rcutils/strnlen.h>

// RCUTILS_REPORT_ERROR_HANDLING_ERRORS and RCUTILS_WARN_ON_TRUNCATION are set in the header below
#include "./error_handling_helpers.h"
Expand Down Expand Up @@ -198,7 +199,7 @@ rcutils_set_error_state(
error_state.line_number = line_number;
#if RCUTILS_REPORT_ERROR_HANDLING_ERRORS
// Only warn of overwritting if the new error is different from the old ones.
size_t characters_to_compare = strnlen(error_string, RCUTILS_ERROR_MESSAGE_MAX_LENGTH);
size_t characters_to_compare = rcutils_strnlen(error_string, RCUTILS_ERROR_MESSAGE_MAX_LENGTH);
// assumption is that message length is <= max error string length
static_assert(
sizeof(gtls_rcutils_error_state.message) <= sizeof(gtls_rcutils_error_string.str),
Expand Down
3 changes: 2 additions & 1 deletion src/error_handling_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <string.h>

#include <rcutils/error_handling.h>
#include <rcutils/strnlen.h>

#ifdef __cplusplus
extern "C"
Expand Down Expand Up @@ -130,7 +131,7 @@ __rcutils_convert_uint64_t_into_c_str(uint64_t number, char * buffer, size_t buf
buffer[i] = '\0';

// reverse the string in place
__rcutils_reverse_str(buffer, strnlen(buffer, 21));
__rcutils_reverse_str(buffer, rcutils_strnlen(buffer, 21));
}

// do not use externally, internal function which is only to be used by error_handling.c
Expand Down
24 changes: 24 additions & 0 deletions src/strnlen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2023 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <string.h>

#include "rcutils/strnlen.h"

size_t
rcutils_strnlen(const char * s, size_t maxlen)
{
const char * found = memchr(s, '\0', maxlen);
return found ? (size_t)(found - s) : maxlen;
}
16 changes: 9 additions & 7 deletions test/test_error_handling_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

#include "osrf_testing_tools_cpp/memory_tools/gtest_quickstart.hpp"

#include "rcutils/strnlen.h"

#include "../src/error_handling_helpers.h"

TEST(test_error_handling, copy_string) {
Expand All @@ -32,7 +34,7 @@ TEST(test_error_handling, copy_string) {
written = __rcutils_copy_string(buffer, 3, "0123456789");
});
EXPECT_EQ(written, 2u);
EXPECT_EQ(strnlen(buffer, sizeof(buffer)), 2u);
EXPECT_EQ(rcutils_strnlen(buffer, sizeof(buffer)), 2u);
EXPECT_STREQ(buffer, "01");

// normal truncation, 1 short of buffer length
Expand All @@ -41,7 +43,7 @@ TEST(test_error_handling, copy_string) {
written = __rcutils_copy_string(buffer, 9, "0123456789");
});
EXPECT_EQ(written, 8u);
EXPECT_EQ(strnlen(buffer, sizeof(buffer)), 8u);
EXPECT_EQ(rcutils_strnlen(buffer, sizeof(buffer)), 8u);
EXPECT_STREQ(buffer, "01234567");

// input smaller than buffer, 1 short of buffer length
Expand All @@ -50,7 +52,7 @@ TEST(test_error_handling, copy_string) {
written = __rcutils_copy_string(buffer, 9, "");
});
EXPECT_EQ(written, 0u);
EXPECT_EQ(strnlen(buffer, sizeof(buffer)), 0u);
EXPECT_EQ(rcutils_strnlen(buffer, sizeof(buffer)), 0u);
EXPECT_STREQ(buffer, "");

// copy where src and dst overlap (testing use of memmove vs memcpy)
Expand All @@ -65,7 +67,7 @@ TEST(test_error_handling, copy_string) {
written = __rcutils_copy_string(buffer, sizeof(buffer), buffer + 3);
});
EXPECT_EQ(written, 6u);
EXPECT_EQ(strnlen(buffer, sizeof(buffer)), (sizeof(buffer) - 1) - 3);
EXPECT_EQ(rcutils_strnlen(buffer, sizeof(buffer)), (sizeof(buffer) - 1) - 3);
EXPECT_STREQ(buffer, "456789");
}

Expand All @@ -75,23 +77,23 @@ TEST(test_error_handling, reverse_str) {
char buffer[] = "even";
EXPECT_NO_MEMORY_OPERATIONS(
{
__rcutils_reverse_str(buffer, strnlen(buffer, sizeof(buffer)));
__rcutils_reverse_str(buffer, rcutils_strnlen(buffer, sizeof(buffer)));
});
EXPECT_STREQ(buffer, "neve");
}
{
char buffer[] = "reverseme";
EXPECT_NO_MEMORY_OPERATIONS(
{
__rcutils_reverse_str(buffer, strnlen(buffer, sizeof(buffer)));
__rcutils_reverse_str(buffer, rcutils_strnlen(buffer, sizeof(buffer)));
});
EXPECT_STREQ(buffer, "emesrever");
}
{
char buffer[] = "a";
EXPECT_NO_MEMORY_OPERATIONS(
{
__rcutils_reverse_str(buffer, strnlen(buffer, sizeof(buffer)));
__rcutils_reverse_str(buffer, rcutils_strnlen(buffer, sizeof(buffer)));
});
EXPECT_STREQ(buffer, "a");
}
Expand Down