[Secure Coding] master: C++: Subscripting to read the NUL character in std::string not supported (e6ed150)
by fweimer@fedoraproject.org
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit e6ed150d2b97ffeecfdc00fd04c154307486f87d
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Thu Sep 19 15:08:53 2013 +0200
C++: Subscripting to read the NUL character in std::string not supported
>---------------------------------------------------------------
defensive-coding/en-US/CXX-Std.xml | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/defensive-coding/en-US/CXX-Std.xml b/defensive-coding/en-US/CXX-Std.xml
index b221949..56e1ad0 100644
--- a/defensive-coding/en-US/CXX-Std.xml
+++ b/defensive-coding/en-US/CXX-Std.xml
@@ -115,6 +115,10 @@
Use the <function>at(size_type)</function> member function
instead. See <xref
linkend="sect-Defensive_Coding-CXX-Std-Subscript"/>.
+ Furthermore, accessing the terminating NUL character using
+ <literal>operator[]</literal> is not possible. (In some
+ implementations, the <literal>c_str()</literal> member function
+ writes the NUL character on demand.)
</para>
<para>
Never write to the pointers returned by
10 years, 7 months
[Secure Coding] master: C++: Mention front(), back() and data() member functions of vectors (7db67ea)
by fweimer@fedoraproject.org
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit 7db67ea9b35a0cb04a0b68048802950775558579
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Thu Sep 19 15:15:28 2013 +0200
C++: Mention front(), back() and data() member functions of vectors
>---------------------------------------------------------------
defensive-coding/en-US/CXX-Std.xml | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/defensive-coding/en-US/CXX-Std.xml b/defensive-coding/en-US/CXX-Std.xml
index 56e1ad0..155f70c 100644
--- a/defensive-coding/en-US/CXX-Std.xml
+++ b/defensive-coding/en-US/CXX-Std.xml
@@ -163,6 +163,15 @@
<literal>operator[](size_type)</literal>, even though it is
slightly more verbose.
</para>
+ <para>
+ The <literal>front()</literal> and <literal>back()</literal>
+ member functions are undefined if a vector object is empty. You
+ can use <literal>vec.at(0)</literal> and
+ <literal>vec.at(vec.size() - 1)</literal> as checked
+ replacements. For an empty vector, <literal>data()</literal> is
+ defined; it returns an arbitrary pointer, but not necessarily
+ the NULL pointer.
+ </para>
</section>
<section id="sect-Defensive_Coding-CXX-Std-Iterators">
<title>Iterators</title>
10 years, 7 months
[Secure Coding] master: Updated POT files (749d19d)
by Eric Christensen
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit 749d19d9ed8385458f3ecffb7df3f25522775e78
Author: Eric Christensen <sparks(a)fedoraproject.org>
Date: Tue Sep 17 20:49:59 2013 -0400
Updated POT files
>---------------------------------------------------------------
Diff suppressed because of size. To see it, use:
git diff --patch-with-stat --no-color --find-copies-harder --ignore-space-at-eol ^749d19d9ed8385458f3ecffb7df3f25522775e78~1 749d19d9ed8385458f3ecffb7df3f25522775e78
10 years, 7 months
[Secure Coding] master: Started marking up new Web Applications chapter (a1dc2ad)
by Eric Christensen
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit a1dc2adddb22aea6225a2014db7c2c342f76965f
Author: Eric Christensen <echriste(a)redhat.com>
Date: Wed Sep 18 16:40:08 2013 -0400
Started marking up new Web Applications chapter
>---------------------------------------------------------------
Diff suppressed because of size. To see it, use:
git diff --patch-with-stat --no-color --find-copies-harder --ignore-space-at-eol ^a1dc2adddb22aea6225a2014db7c2c342f76965f~1 a1dc2adddb22aea6225a2014db7c2c342f76965f
10 years, 7 months
[Secure Coding] master: Merge branch 'master' of git+ssh://git.fedorahosted.org/git/secure-coding (afbe090)
by Eric Christensen
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit afbe09041885e6a3a92df626851f88c42ef1a243
Merge: 0d2ea66 2067762
Author: Eric Christensen <sparks(a)fedoraproject.org>
Date: Tue Sep 17 20:42:46 2013 -0400
Merge branch 'master' of git+ssh://git.fedorahosted.org/git/secure-coding
>---------------------------------------------------------------
defensive-coding/en-US/CXX-Language.xml | 16 +-
defensive-coding/en-US/CXX-Std.xml | 161 +++++++++++++++++++-
defensive-coding/en-US/Tasks-Serialization.xml | 2 +-
.../C-String-Functions-strncat-as-strncpy.xml | 2 +-
defensive-coding/src/C-String-Functions.c | 2 +-
5 files changed, 171 insertions(+), 12 deletions(-)
diff --git a/defensive-coding/en-US/CXX-Language.xml b/defensive-coding/en-US/CXX-Language.xml
index 9dbc4f3..b6e6df9 100644
--- a/defensive-coding/en-US/CXX-Language.xml
+++ b/defensive-coding/en-US/CXX-Language.xml
@@ -19,8 +19,9 @@
array. Current GCC versions generate code that performs a
computation of the form <literal>sizeof(T) * size_t(n) +
cookie_size</literal>, where <literal>cookie_size</literal> is
- currently at most 8. This computation can overflow, and
- GCC-generated code does not detect this.
+ currently at most 8. This computation can overflow, and GCC
+ versions prior to 4.8 generated code which did not detect this.
+ (Fedora 18 was the first release which fixed this in GCC.)
</para>
<para>
The <literal>std::vector</literal> template can be used instead
@@ -28,11 +29,12 @@
overflow internally.)
</para>
<para>
- If there is no alternative to <literal>operator new[]</literal>,
- code which allocates arrays with a variable length must check
- for overflow manually. For the <literal>new T[n]</literal>
- example, the size check could be <literal>n || (n > 0 &&
- n > (size_t(-1) - 8) / sizeof(T))</literal>. (See <xref
+ If there is no alternative to <literal>operator new[]</literal>
+ and the sources will be compiled with older GCC versions, code
+ which allocates arrays with a variable length must check for
+ overflow manually. For the <literal>new T[n]</literal> example,
+ the size check could be <literal>n || (n > 0 && n >
+ (size_t(-1) - 8) / sizeof(T))</literal>. (See <xref
linkend="sect-Defensive_Coding-C-Arithmetic"/>.) If there are
additional dimensions (which must be constants according to the
C++ standard), these should be included as factors in the
diff --git a/defensive-coding/en-US/CXX-Std.xml b/defensive-coding/en-US/CXX-Std.xml
index 5ed53a4..b221949 100644
--- a/defensive-coding/en-US/CXX-Std.xml
+++ b/defensive-coding/en-US/CXX-Std.xml
@@ -7,10 +7,142 @@
The C++ standard library includes most of its C counterpart
by reference, see <xref linkend="sect-Defensive_Coding-C-Libc"/>.
</para>
- <section>
+ <section id="sect-Defensive_Coding-CXX-Std-Functions">
+ <title>Functions that are difficult to use</title>
+ <para>
+ This section collects functions and function templates which are
+ part of the standard library and are difficult to use.
+ </para>
+ <section id="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators">
+ <title>Unpaired iterators</title>
+ <para>
+ Functions which use output operators or iterators which do not
+ come in pairs (denoting ranges) cannot perform iterator range
+ checking.
+ (See <xref linkend="sect-Defensive_Coding-CXX-Std-Iterators"/>)
+ Function templates which involve output iterators are
+ particularly dangerous:
+ </para>
+ <itemizedlist>
+ <listitem><para><function>std::copy</function></para></listitem>
+ <listitem><para><function>std::copy_backward</function></para></listitem>
+ <listitem><para><function>std::copy_if</function></para></listitem>
+ <listitem><para><function>std::move</function> (three-argument variant)</para></listitem>
+ <listitem><para><function>std::move_backward</function></para></listitem>
+ <listitem><para><function>std::partition_copy_if</function></para></listitem>
+ <listitem><para><function>std::remove_copy</function></para></listitem>
+ <listitem><para><function>std::remove_copy_if</function></para></listitem>
+ <listitem><para><function>std::replace_copy</function></para></listitem>
+ <listitem><para><function>std::replace_copy_if</function></para></listitem>
+ <listitem><para><function>std::swap_ranges</function></para></listitem>
+ <listitem><para><function>std::transform</function></para></listitem>
+ </itemizedlist>
+ <para>
+ In addition, <function>std::copy_n</function>,
+ <function>std::fill_n</function> and
+ <function>std::generate_n</function> do not perform iterator
+ checking, either, but there is an explicit count which has to be
+ supplied by the caller, as opposed to an implicit length
+ indicator in the form of a pair of forward iterators.
+ </para>
+ <para>
+ These output-iterator-expecting functions should only be used
+ with unlimited-range output iterators, such as iterators
+ obtained with the <function>std::back_inserter</function>
+ function.
+ </para>
+ <para>
+ Other functions use single input or forward iterators, which can
+ read beyond the end of the input range if the caller is not careful:
+ </para>
+ <itemizedlist>
+ <listitem><para><function>std::equal</function></para></listitem>
+ <listitem><para><function>std::is_permutation</function></para></listitem>
+ <listitem><para><function>std::mismatch</function></para></listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="sect-Defensive_Coding-CXX-Std-String">
+ <title>String handling with <literal>std::string</literal></title>
+ <para>
+ The <literal>std::string</literal> class provides a convenient
+ way to handle strings. Unlike C strings,
+ <literal>std::string</literal> objects have an explicit length
+ (and can contain embedded NUL characters), and storage for its
+ characters is managed automatically. This section discusses
+ <literal>std::string</literal>, but these observations also
+ apply to other instances of the
+ <literal>std::basic_string</literal> template.
+ </para>
+ <para>
+ The pointer returned by the <function>data()</function> member
+ function does not necessarily point to a NUL-terminated string.
+ To obtain a C-compatible string pointer, use
+ <function>c_str()</function> instead, which adds the NUL
+ terminator.
+ </para>
+ <para>
+ The pointers returned by the <function>data()</function> and
+ <function>c_str()</function> functions and iterators are only
+ valid until certain events happen. It is required that the
+ exact <literal>std::string</literal> object still exists (even
+ if it was initially created as a copy of another string object).
+ Pointers and iterators are also invalidated when non-const
+ member functions are called, or functions with a non-const
+ reference parameter. The behavior of the GCC implementation
+ deviates from that required by the C++ standard if multiple
+ threads are present. In general, only the first call to a
+ non-const member function after a structural modification of the
+ string (such as appending a character) is invalidating, but this
+ also applies to member function such as the non-const version of
+ <function>begin()</function>, in violation of the C++ standard.
+ </para>
+ <para>
+ Particular care is necessary when invoking the
+ <function>c_str()</function> member function on a temporary
+ object. This is convenient for calling C functions, but the
+ pointer will turn invalid as soon as the temporary object is
+ destroyed, which generally happens when the outermost expression
+ enclosing the expression on which <function>c_str()</function>
+ is called completes evaluation. Passing the result of
+ <function>c_str()</function> to a function which does not store
+ or otherwise leak that pointer is safe, though.
+ </para>
+ <para>
+ Like with <literal>std::vector</literal> and
+ <literal>std::array</literal>, subscribing with
+ <literal>operator[]</literal> does not perform bounds checks.
+ Use the <function>at(size_type)</function> member function
+ instead. See <xref
+ linkend="sect-Defensive_Coding-CXX-Std-Subscript"/>.
+ </para>
+ <para>
+ Never write to the pointers returned by
+ <function>data()</function> or <function>c_str()</function>
+ after casting away <literal>const</literal>. If you need a
+ C-style writable string, use a
+ <literal>std::vector<char></literal> object and its
+ <function>data()</function> member function. In this case, you
+ have to explicitly add the terminating NUL character.
+ </para>
+ <para>
+ GCC's implementation of <literal>std::string</literal> is
+ currently based on reference counting. It is expected that a
+ future version will remove the reference counting, due to
+ performance and conformance issues. As a result, code that
+ implicitly assumes sharing by holding to pointers or iterators
+ for too long will break, resulting in run-time crashes or worse.
+ On the other hand, non-const iterator-returning functions will
+ no longer give other threads an opportunity for invalidating
+ existing iterators and pointers because iterator invalidation
+ does not depend on sharing of the internal character array
+ object anymore.
+ </para>
+ </section>
+ <section id="sect-Defensive_Coding-CXX-Std-Subscript">
<title>Containers and <literal>operator[]</literal></title>
<para>
- Many containers similar to <literal>std::vector</literal>
+ Many sequence containers similar to <literal>std::vector</literal>
provide both <literal>operator[](size_type)</literal> and a
member function <literal>at(size_type)</literal>. This applies
to <literal>std::vector</literal> itself,
@@ -28,5 +160,30 @@
slightly more verbose.
</para>
</section>
+ <section id="sect-Defensive_Coding-CXX-Std-Iterators">
+ <title>Iterators</title>
+ <para>
+ Iterators do not perform any bounds checking. Therefore, all
+ functions that work on iterators should accept them in pairs,
+ denoting a range, and make sure that iterators are not moved
+ outside that range. For forward iterators and bidirectional
+ iterators, you need to check for equality before moving the
+ first or last iterator in the range. For random-access
+ iterators, you need to compute the difference before adding or
+ subtracting an offset. It is not possible to perform the
+ operation and check for an invalid operator afterwards.
+ </para>
+ <para>
+ Output iterators cannot be compared for equality. Therefore, it
+ is impossible to write code that detects that it has been
+ supplied an output area that is too small, and their use should
+ be avoided.
+ </para>
+ <para>
+ These issues make some of the standard library functions
+ difficult to use correctly, see <xref
+ linkend="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"/>.
+ </para>
+ </section>
</section>
diff --git a/defensive-coding/en-US/Tasks-Serialization.xml b/defensive-coding/en-US/Tasks-Serialization.xml
index 456da55..008e75b 100644
--- a/defensive-coding/en-US/Tasks-Serialization.xml
+++ b/defensive-coding/en-US/Tasks-Serialization.xml
@@ -64,7 +64,7 @@
<itemizedlist>
<listitem><para>
Python's <package>pickle</package> and <package>cPickle</package>
- modules
+ modules, and wrappers such as <package>shelve</package>
</para></listitem>
<listitem><para>
Perl's <package>Storable</package> package
diff --git a/defensive-coding/en-US/snippets/C-String-Functions-strncat-as-strncpy.xml b/defensive-coding/en-US/snippets/C-String-Functions-strncat-as-strncpy.xml
index 0895eaf..1f5c8c6 100644
--- a/defensive-coding/en-US/snippets/C-String-Functions-strncat-as-strncpy.xml
+++ b/defensive-coding/en-US/snippets/C-String-Functions-strncat-as-strncpy.xml
@@ -4,5 +4,5 @@
<!-- Automatically generated file. Do not edit. -->
<programlisting language="C">
buf[0] = '\0';
-strncpy(buf, data, sizeof(buf) - 1);
+strncat(buf, data, sizeof(buf) - 1);
</programlisting>
diff --git a/defensive-coding/src/C-String-Functions.c b/defensive-coding/src/C-String-Functions.c
index 34d9c31..9f8898a 100644
--- a/defensive-coding/src/C-String-Functions.c
+++ b/defensive-coding/src/C-String-Functions.c
@@ -70,7 +70,7 @@ main(void)
assert(strncmp(buf, data, 9) == 0);
//+ C String-Functions-strncat-as-strncpy
buf[0] = '\0';
- strncpy(buf, data, sizeof(buf) - 1);
+ strncat(buf, data, sizeof(buf) - 1);
//-
}
{
10 years, 7 months
[Secure Coding] master: Updated copyright date (0d2ea66)
by Eric Christensen
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit 0d2ea6699f3a689fdc173f6f0588e40f7c7271df
Author: Eric Christensen <sparks(a)fedoraproject.org>
Date: Tue Aug 27 23:13:09 2013 -0400
Updated copyright date
>---------------------------------------------------------------
defensive-coding/en-US/Defensive_Coding.ent | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/defensive-coding/en-US/Defensive_Coding.ent b/defensive-coding/en-US/Defensive_Coding.ent
index 0bf84b7..ae4cb86 100644
--- a/defensive-coding/en-US/Defensive_Coding.ent
+++ b/defensive-coding/en-US/Defensive_Coding.ent
@@ -1,2 +1,2 @@
-<!ENTITY YEAR "2012">
+<!ENTITY YEAR "2012-2013">
<!ENTITY HOLDER "Red Hat, Inc">
10 years, 7 months
[Secure Coding] master: C++: Warn about functions that deal with unpaired iterators (2067762)
by fweimer@fedoraproject.org
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit 2067762b472676ef892b55a5263bcf3dd0f16040
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Tue Sep 17 13:51:27 2013 +0200
C++: Warn about functions that deal with unpaired iterators
>---------------------------------------------------------------
defensive-coding/en-US/CXX-Std.xml | 60 ++++++++++++++++++++++++++++++++++++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/defensive-coding/en-US/CXX-Std.xml b/defensive-coding/en-US/CXX-Std.xml
index 88fa803..b221949 100644
--- a/defensive-coding/en-US/CXX-Std.xml
+++ b/defensive-coding/en-US/CXX-Std.xml
@@ -7,6 +7,61 @@
The C++ standard library includes most of its C counterpart
by reference, see <xref linkend="sect-Defensive_Coding-C-Libc"/>.
</para>
+ <section id="sect-Defensive_Coding-CXX-Std-Functions">
+ <title>Functions that are difficult to use</title>
+ <para>
+ This section collects functions and function templates which are
+ part of the standard library and are difficult to use.
+ </para>
+ <section id="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators">
+ <title>Unpaired iterators</title>
+ <para>
+ Functions which use output operators or iterators which do not
+ come in pairs (denoting ranges) cannot perform iterator range
+ checking.
+ (See <xref linkend="sect-Defensive_Coding-CXX-Std-Iterators"/>)
+ Function templates which involve output iterators are
+ particularly dangerous:
+ </para>
+ <itemizedlist>
+ <listitem><para><function>std::copy</function></para></listitem>
+ <listitem><para><function>std::copy_backward</function></para></listitem>
+ <listitem><para><function>std::copy_if</function></para></listitem>
+ <listitem><para><function>std::move</function> (three-argument variant)</para></listitem>
+ <listitem><para><function>std::move_backward</function></para></listitem>
+ <listitem><para><function>std::partition_copy_if</function></para></listitem>
+ <listitem><para><function>std::remove_copy</function></para></listitem>
+ <listitem><para><function>std::remove_copy_if</function></para></listitem>
+ <listitem><para><function>std::replace_copy</function></para></listitem>
+ <listitem><para><function>std::replace_copy_if</function></para></listitem>
+ <listitem><para><function>std::swap_ranges</function></para></listitem>
+ <listitem><para><function>std::transform</function></para></listitem>
+ </itemizedlist>
+ <para>
+ In addition, <function>std::copy_n</function>,
+ <function>std::fill_n</function> and
+ <function>std::generate_n</function> do not perform iterator
+ checking, either, but there is an explicit count which has to be
+ supplied by the caller, as opposed to an implicit length
+ indicator in the form of a pair of forward iterators.
+ </para>
+ <para>
+ These output-iterator-expecting functions should only be used
+ with unlimited-range output iterators, such as iterators
+ obtained with the <function>std::back_inserter</function>
+ function.
+ </para>
+ <para>
+ Other functions use single input or forward iterators, which can
+ read beyond the end of the input range if the caller is not careful:
+ </para>
+ <itemizedlist>
+ <listitem><para><function>std::equal</function></para></listitem>
+ <listitem><para><function>std::is_permutation</function></para></listitem>
+ <listitem><para><function>std::mismatch</function></para></listitem>
+ </itemizedlist>
+ </section>
+ </section>
<section id="sect-Defensive_Coding-CXX-Std-String">
<title>String handling with <literal>std::string</literal></title>
<para>
@@ -124,6 +179,11 @@
supplied an output area that is too small, and their use should
be avoided.
</para>
+ <para>
+ These issues make some of the standard library functions
+ difficult to use correctly, see <xref
+ linkend="sect-Defensive_Coding-CXX-Std-Functions-Unpaired_Iterators"/>.
+ </para>
</section>
</section>
10 years, 7 months
[Secure Coding] master: C++: Add section on iterators (f2167f7)
by fweimer@fedoraproject.org
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit f2167f7ee2ba265cee120e87e8be6c581094aec1
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Tue Sep 17 13:28:00 2013 +0200
C++: Add section on iterators
>---------------------------------------------------------------
defensive-coding/en-US/CXX-Std.xml | 22 +++++++++++++++++++++-
1 files changed, 21 insertions(+), 1 deletions(-)
diff --git a/defensive-coding/en-US/CXX-Std.xml b/defensive-coding/en-US/CXX-Std.xml
index 181ad48..88fa803 100644
--- a/defensive-coding/en-US/CXX-Std.xml
+++ b/defensive-coding/en-US/CXX-Std.xml
@@ -87,7 +87,7 @@
<section id="sect-Defensive_Coding-CXX-Std-Subscript">
<title>Containers and <literal>operator[]</literal></title>
<para>
- Many containers similar to <literal>std::vector</literal>
+ Many sequence containers similar to <literal>std::vector</literal>
provide both <literal>operator[](size_type)</literal> and a
member function <literal>at(size_type)</literal>. This applies
to <literal>std::vector</literal> itself,
@@ -105,5 +105,25 @@
slightly more verbose.
</para>
</section>
+ <section id="sect-Defensive_Coding-CXX-Std-Iterators">
+ <title>Iterators</title>
+ <para>
+ Iterators do not perform any bounds checking. Therefore, all
+ functions that work on iterators should accept them in pairs,
+ denoting a range, and make sure that iterators are not moved
+ outside that range. For forward iterators and bidirectional
+ iterators, you need to check for equality before moving the
+ first or last iterator in the range. For random-access
+ iterators, you need to compute the difference before adding or
+ subtracting an offset. It is not possible to perform the
+ operation and check for an invalid operator afterwards.
+ </para>
+ <para>
+ Output iterators cannot be compared for equality. Therefore, it
+ is impossible to write code that detects that it has been
+ supplied an output area that is too small, and their use should
+ be avoided.
+ </para>
+ </section>
</section>
10 years, 7 months
[Secure Coding] master: Add material on std::string (594eead)
by fweimer@fedoraproject.org
Repository : http://git.fedorahosted.org/git/?p=secure-coding.git
On branch : master
>---------------------------------------------------------------
commit 594eeadc16bea3c82521470f3d6d1026edd6c608
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Tue Sep 17 13:10:09 2013 +0200
Add material on std::string
>---------------------------------------------------------------
defensive-coding/en-US/CXX-Std.xml | 79 +++++++++++++++++++++++++++++++++++-
1 files changed, 78 insertions(+), 1 deletions(-)
diff --git a/defensive-coding/en-US/CXX-Std.xml b/defensive-coding/en-US/CXX-Std.xml
index 5ed53a4..181ad48 100644
--- a/defensive-coding/en-US/CXX-Std.xml
+++ b/defensive-coding/en-US/CXX-Std.xml
@@ -7,7 +7,84 @@
The C++ standard library includes most of its C counterpart
by reference, see <xref linkend="sect-Defensive_Coding-C-Libc"/>.
</para>
- <section>
+ <section id="sect-Defensive_Coding-CXX-Std-String">
+ <title>String handling with <literal>std::string</literal></title>
+ <para>
+ The <literal>std::string</literal> class provides a convenient
+ way to handle strings. Unlike C strings,
+ <literal>std::string</literal> objects have an explicit length
+ (and can contain embedded NUL characters), and storage for its
+ characters is managed automatically. This section discusses
+ <literal>std::string</literal>, but these observations also
+ apply to other instances of the
+ <literal>std::basic_string</literal> template.
+ </para>
+ <para>
+ The pointer returned by the <function>data()</function> member
+ function does not necessarily point to a NUL-terminated string.
+ To obtain a C-compatible string pointer, use
+ <function>c_str()</function> instead, which adds the NUL
+ terminator.
+ </para>
+ <para>
+ The pointers returned by the <function>data()</function> and
+ <function>c_str()</function> functions and iterators are only
+ valid until certain events happen. It is required that the
+ exact <literal>std::string</literal> object still exists (even
+ if it was initially created as a copy of another string object).
+ Pointers and iterators are also invalidated when non-const
+ member functions are called, or functions with a non-const
+ reference parameter. The behavior of the GCC implementation
+ deviates from that required by the C++ standard if multiple
+ threads are present. In general, only the first call to a
+ non-const member function after a structural modification of the
+ string (such as appending a character) is invalidating, but this
+ also applies to member function such as the non-const version of
+ <function>begin()</function>, in violation of the C++ standard.
+ </para>
+ <para>
+ Particular care is necessary when invoking the
+ <function>c_str()</function> member function on a temporary
+ object. This is convenient for calling C functions, but the
+ pointer will turn invalid as soon as the temporary object is
+ destroyed, which generally happens when the outermost expression
+ enclosing the expression on which <function>c_str()</function>
+ is called completes evaluation. Passing the result of
+ <function>c_str()</function> to a function which does not store
+ or otherwise leak that pointer is safe, though.
+ </para>
+ <para>
+ Like with <literal>std::vector</literal> and
+ <literal>std::array</literal>, subscribing with
+ <literal>operator[]</literal> does not perform bounds checks.
+ Use the <function>at(size_type)</function> member function
+ instead. See <xref
+ linkend="sect-Defensive_Coding-CXX-Std-Subscript"/>.
+ </para>
+ <para>
+ Never write to the pointers returned by
+ <function>data()</function> or <function>c_str()</function>
+ after casting away <literal>const</literal>. If you need a
+ C-style writable string, use a
+ <literal>std::vector<char></literal> object and its
+ <function>data()</function> member function. In this case, you
+ have to explicitly add the terminating NUL character.
+ </para>
+ <para>
+ GCC's implementation of <literal>std::string</literal> is
+ currently based on reference counting. It is expected that a
+ future version will remove the reference counting, due to
+ performance and conformance issues. As a result, code that
+ implicitly assumes sharing by holding to pointers or iterators
+ for too long will break, resulting in run-time crashes or worse.
+ On the other hand, non-const iterator-returning functions will
+ no longer give other threads an opportunity for invalidating
+ existing iterators and pointers because iterator invalidation
+ does not depend on sharing of the internal character array
+ object anymore.
+ </para>
+ </section>
+ <section id="sect-Defensive_Coding-CXX-Std-Subscript">
<title>Containers and <literal>operator[]</literal></title>
<para>
Many containers similar to <literal>std::vector</literal>
10 years, 7 months