Skip to content

Commit 1c29ed2

Browse files
author
John Wellbelove
committed
Sync to ETL 20.44.2
1 parent fc3bc0f commit 1c29ed2

25 files changed

+1123
-136
lines changed

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Embedded Template Library ETL",
3-
"version": "20.44.1",
3+
"version": "20.44.2",
44
"authors": {
55
"name": "John Wellbelove",
66
"email": "[email protected]"

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Embedded Template Library ETL
2-
version=20.44.1
2+
version=20.44.2
33
author= John Wellbelove <[email protected]>
44
maintainer=John Wellbelove <[email protected]>
55
license=MIT

src/etl/absolute.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ SOFTWARE.
3131
#ifndef ETL_ABSOLUTE_INCLUDED
3232
#define ETL_ABSOLUTE_INCLUDED
3333

34+
#include "platform.h"
3435
#include "type_traits.h"
3536
#include "integral_limits.h"
3637

src/etl/basic_string.h

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ namespace etl
560560
//*********************************************************************
561561
reference operator [](size_type i)
562562
{
563+
ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(string_out_of_bounds));
563564
return p_buffer[i];
564565
}
565566

@@ -570,6 +571,7 @@ namespace etl
570571
//*********************************************************************
571572
const_reference operator [](size_type i) const
572573
{
574+
ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(string_out_of_bounds));
573575
return p_buffer[i];
574576
}
575577

@@ -603,6 +605,7 @@ namespace etl
603605
//*********************************************************************
604606
reference front()
605607
{
608+
ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
606609
return p_buffer[0];
607610
}
608611

@@ -612,6 +615,7 @@ namespace etl
612615
//*********************************************************************
613616
const_reference front() const
614617
{
618+
ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
615619
return p_buffer[0];
616620
}
617621

@@ -621,7 +625,8 @@ namespace etl
621625
//*********************************************************************
622626
reference back()
623627
{
624-
return p_buffer[current_size - 1];
628+
ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
629+
return p_buffer[size() - 1];
625630
}
626631

627632
//*********************************************************************
@@ -630,7 +635,8 @@ namespace etl
630635
//*********************************************************************
631636
const_reference back() const
632637
{
633-
return p_buffer[current_size - 1];
638+
ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(string_out_of_bounds));
639+
return p_buffer[size() - 1];
634640
}
635641

636642
//*********************************************************************
@@ -764,7 +770,7 @@ namespace etl
764770
set_truncated(n > CAPACITY);
765771

766772
#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
767-
ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation));
773+
ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
768774
#endif
769775
#endif
770776

@@ -912,7 +918,7 @@ namespace etl
912918
set_truncated(n > free_space);
913919

914920
#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
915-
ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation));
921+
ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
916922
#endif
917923
#endif
918924

@@ -932,6 +938,8 @@ namespace etl
932938
//*********************************************************************
933939
iterator insert(const_iterator position, T value)
934940
{
941+
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
942+
935943
// Quick hack, as iterators are pointers.
936944
iterator insert_position = to_iterator(position);
937945

@@ -984,6 +992,8 @@ namespace etl
984992
//*********************************************************************
985993
iterator insert(const_iterator position, size_type n, T value)
986994
{
995+
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
996+
987997
iterator position_ = to_iterator(position);
988998

989999
if (n == 0)
@@ -1071,6 +1081,9 @@ namespace etl
10711081
template <typename TIterator>
10721082
iterator insert(const_iterator position, TIterator first, TIterator last)
10731083
{
1084+
ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position <= cend(), ETL_ERROR(string_out_of_bounds));
1085+
ETL_ASSERT_CHECK_EXTRA(first <= last, ETL_ERROR(string_iterator));
1086+
10741087
iterator position_ = to_iterator(position);
10751088

10761089
if (first == last)
@@ -1307,6 +1320,8 @@ namespace etl
13071320
//*********************************************************************
13081321
etl::ibasic_string<T>& erase(size_type position, size_type length_ = npos)
13091322
{
1323+
ETL_ASSERT_CHECK_EXTRA(position <= size(), ETL_ERROR(string_out_of_bounds));
1324+
13101325
// Limit the length.
13111326
length_ = etl::min(length_, size() - position);
13121327

@@ -1322,6 +1337,8 @@ namespace etl
13221337
//*********************************************************************
13231338
iterator erase(iterator i_element)
13241339
{
1340+
ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(string_out_of_bounds));
1341+
13251342
etl::mem_move(i_element + 1, end(), i_element);
13261343
p_buffer[--current_size] = 0;
13271344

@@ -1335,6 +1352,8 @@ namespace etl
13351352
//*********************************************************************
13361353
iterator erase(const_iterator i_element)
13371354
{
1355+
ETL_ASSERT_CHECK_EXTRA(cbegin() <= i_element && i_element < cend(), ETL_ERROR(string_out_of_bounds));
1356+
13381357
iterator i_element_(to_iterator(i_element));
13391358

13401359
etl::mem_move(i_element + 1, end(), i_element_);
@@ -1353,6 +1372,8 @@ namespace etl
13531372
//*********************************************************************
13541373
iterator erase(const_iterator first, const_iterator last)
13551374
{
1375+
ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(string_out_of_bounds));
1376+
13561377
iterator first_ = to_iterator(first);
13571378
iterator last_ = to_iterator(last);
13581379

@@ -2753,15 +2774,19 @@ namespace etl
27532774
set_truncated((count > free_space) || this->is_truncated() || truncated);
27542775

27552776
#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
2756-
ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation));
2777+
ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
27572778
#endif
2779+
#else
2780+
(void)truncated;
27582781
#endif
27592782

27602783
#if ETL_HAS_STRING_CLEAR_AFTER_USE
27612784
if (secure)
27622785
{
27632786
set_secure();
27642787
}
2788+
#else
2789+
(void)secure;
27652790
#endif
27662791

27672792
// Limit the actual distance to the capacity.
@@ -2799,15 +2824,19 @@ namespace etl
27992824
#if ETL_HAS_STRING_TRUNCATION_CHECKS
28002825
set_truncated(truncated);
28012826
#if ETL_HAS_ERROR_ON_STRING_TRUNCATION
2802-
ETL_ASSERT(is_truncated == false, ETL_ERROR(string_truncation));
2827+
ETL_ASSERT(is_truncated() == false, ETL_ERROR(string_truncation));
28032828
#endif
2829+
#else
2830+
(void)truncated;
28042831
#endif
28052832

28062833
#if ETL_HAS_STRING_CLEAR_AFTER_USE
28072834
if (secure)
28082835
{
28092836
set_secure();
28102837
}
2838+
#else
2839+
(void)secure;
28112840
#endif
28122841

28132842
cleanup();

src/etl/callback_timer_deferred_locked.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ SOFTWARE.
2929
#ifndef ETL_CALLBACK_TIMER_DEFERRED_LOCKED_INCLUDED
3030
#define ETL_CALLBACK_TIMER_DEFERRED_LOCKED_INCLUDED
3131

32+
#include "platform.h"
3233
#include "callback_timer_locked.h"
3334
#include "etl/nullptr.h"
3435
#include "etl/optional.h"

src/etl/fsm.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,19 @@ namespace etl
172172
}
173173
};
174174

175+
//***************************************************************************
176+
/// Exception for call to receive/start/etc. while receive/start/etc. is already happening.
177+
/// A call like that could result in an infinite loop or landing in an incorrect state.
178+
//***************************************************************************
179+
class fsm_reentrant_transition_forbidden : public etl::fsm_exception
180+
{
181+
public:
182+
fsm_reentrant_transition_forbidden(string_type file_name_, numeric_type line_number_)
183+
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:reentrant calls to start/receive/etc. forbidden", ETL_FSM_FILE_ID"G"), file_name_, line_number_)
184+
{
185+
}
186+
};
187+
175188
namespace private_fsm
176189
{
177190
template <typename T = void>
@@ -209,6 +222,47 @@ namespace etl
209222
: etl::integral_constant<bool, (TState0::STATE_ID == Id) && private_fsm::check_ids<Id + 1, TRest...>::value>
210223
{
211224
};
225+
226+
//***************************************************************************
227+
/// RAII detection mechanism to catch reentrant calls to methods that might
228+
/// transition the state machine to a different state.
229+
/// This is not a mutex.
230+
//***************************************************************************
231+
class fsm_reentrancy_guard
232+
{
233+
public:
234+
//*******************************************
235+
/// Constructor.
236+
/// Checks if another method has locked reentrancy.
237+
//*******************************************
238+
fsm_reentrancy_guard(bool& transition_guard_flag)
239+
: is_locked(transition_guard_flag)
240+
{
241+
ETL_ASSERT(!is_locked, ETL_ERROR(etl::fsm_reentrant_transition_forbidden));
242+
is_locked = true;
243+
}
244+
245+
//*******************************************
246+
/// Destructor.
247+
/// Releases lock on reentrancy.
248+
//*******************************************
249+
~fsm_reentrancy_guard() ETL_NOEXCEPT
250+
{
251+
is_locked = false;
252+
}
253+
254+
private:
255+
// Reference to the flag signifying a lock on the state machine.
256+
bool& is_locked;
257+
258+
// Copy & move semantics disabled since this is a guard.
259+
fsm_reentrancy_guard(fsm_reentrancy_guard const&) ETL_DELETE;
260+
fsm_reentrancy_guard& operator= (fsm_reentrancy_guard const&) ETL_DELETE;
261+
#if ETL_USING_CPP11
262+
fsm_reentrancy_guard(fsm_reentrancy_guard&&) ETL_DELETE;
263+
fsm_reentrancy_guard& operator= (fsm_reentrancy_guard&&) ETL_DELETE;
264+
#endif
265+
};
212266
}
213267

214268
class ifsm_state;
@@ -417,6 +471,7 @@ namespace etl
417471
, p_state(ETL_NULLPTR)
418472
, state_list(ETL_NULLPTR)
419473
, number_of_states(0U)
474+
, is_processing_state_change(false)
420475
{
421476
}
422477

@@ -467,6 +522,8 @@ namespace etl
467522
//*******************************************
468523
virtual void start(bool call_on_enter_state = true)
469524
{
525+
private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change);
526+
470527
// Can only be started once.
471528
if (!is_started())
472529
{
@@ -497,6 +554,8 @@ namespace etl
497554
//*******************************************
498555
void receive(const etl::imessage& message) ETL_OVERRIDE
499556
{
557+
private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change);
558+
500559
if (is_started())
501560
{
502561
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
@@ -514,6 +573,8 @@ namespace etl
514573
//*******************************************
515574
etl::fsm_state_id_t transition_to(etl::fsm_state_id_t new_state_id)
516575
{
576+
private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change);
577+
517578
if (is_started())
518579
{
519580
return process_state_change(new_state_id);
@@ -576,6 +637,8 @@ namespace etl
576637
//*******************************************
577638
virtual void reset(bool call_on_exit_state = false)
578639
{
640+
private_fsm::fsm_reentrancy_guard transition_lock(is_processing_state_change);
641+
579642
if (is_started() && call_on_exit_state)
580643
{
581644
p_state->on_exit_state();
@@ -655,6 +718,7 @@ namespace etl
655718
etl::ifsm_state* p_state; ///< A pointer to the current state.
656719
etl::ifsm_state** state_list; ///< The list of added states.
657720
etl::fsm_state_id_t number_of_states; ///< The number of states.
721+
bool is_processing_state_change; ///< Whether a method call that could potentially trigger a state change is active
658722
};
659723

660724
//*************************************************************************************************

0 commit comments

Comments
 (0)