C++ Standard Library
  1. C++ Standard Library
  2. STDCXX-765

Incorrect using rw_asnprintf() with %{+} format and not NUL-terminated buffer in _rw_fmtflags(), _rw_fmtevent(), _rw_fmtlc()

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 4.2.0
    • Fix Version/s: 4.2.1
    • Component/s: Test Driver
    • Labels:
      None
    • Environment:

      All

    • Severity:
      Incorrect Behavior

      Description

      The buf parameter of the _rw_fmtflags(), _rw_fmtevent() and _rw_fmtlc() functions contains not NUL-terminated data. The length of data in buf is stored in buf.endoff.
      The rw_asnprintf() function accepts the only buf.pbuf and buf.pbufsize, but not buf.endoff. When %{+} format is used, the length of data in buf calculated using strlen() function, but this length is incorrect due to data is not NUL-terminated.
      Another bug is that _rw_fmtflags(), _rw_fmtevent() and _rw_fmtlc() functions are returns len, but without updating the buf.endoff. Due to this the result of rw_asnprintf() is cutted in further processing.

      These problems are detected in 0.printf test after latest update.

      The schematic patch without error checking is below. This patch is not intended to apply. It's only shows how these bugs should be fixed.

      Index: tests/src/fmt_bits.cpp
      ===================================================================
      --- tests/src/fmt_bits.cpp	(revision 637399)
      +++ tests/src/fmt_bits.cpp	(working copy)
      @@ -204,9 +204,12 @@
       
       #endif   // _RWSTD_NO_EXT_BIN_IO
       
      -        len = rw_asnprintf (buf.pbuf, buf.pbufsize,
      -                            "%{+} | %{?}std::ios::%{;}base(%d)",
      -                            spec.fl_pound, base);
      +        (*buf.pbuf) [buf.endoff] = '\0';
      +        int res = rw_asnprintf (buf.pbuf, buf.pbufsize,
      +                                "%{+} | %{?}std::ios::%{;}base(%d)",
      +                                spec.fl_pound, base);
      +        buf.endoff += res;
      +        len += res;
           }
       
           return len;
      @@ -303,9 +306,12 @@
               : std::ios::erase_event   == event ? "erase_event"
               : 0;
       
      -    return rw_asnprintf (buf.pbuf, buf.pbufsize,
      -                         "%{+}%{?}std::ios::%{;}%{?}%s%{:}event(%d)%{;}",
      -                         spec.fl_pound, 0 != str, str, event);
      +    (*buf.pbuf) [buf.endoff] = '\0';
      +    int len = rw_asnprintf (buf.pbuf, buf.pbufsize,
      +                            "%{+}%{?}std::ios::%{;}%{?}%s%{:}event(%d)%{;}",
      +                            spec.fl_pound, 0 != str, str, event);
      +    buf.endoff += len;
      +    return len;
       }
       
       /********************************************************************/
      @@ -329,8 +335,12 @@
       
           }
       
      -    if (str)
      -        return rw_asnprintf (buf.pbuf, buf.pbufsize, "%{+}%s", str);
      +    if (str) {
      +        (*buf.pbuf) [buf.endoff] = '\0';
      +        int len = rw_asnprintf (buf.pbuf, buf.pbufsize, "%{+}%s", str);
      +        buf.endoff += len;
      +        return len;
      +    }
       
           static const Bitnames names [] = {
               BITNAME (std::locale, all),
      
      1. stdcxx-765.diff
        3 kB
        Martin Sebor

        Activity

        Farid Zaripov created issue -
        Farid Zaripov made changes -
        Field Original Value New Value
        Description The buf parameter of the _rw_fmtflags(), _rw_fmtevent() and _rw_fmtlc() functions contains not NUL-terminated data. The length of data in buf is stored in buf.endoff.
        The rw_asnprintf() function accepts the only buf.pbuf and buf.pbufsize, but not buf.endoff. When %{+} format is used, the length of data in buf calculated using strlen() function, but this length is incorrect due to data is not NUL-terminated.
        Another bug is that _rw_fmtflags(), _rw_fmtevent() and _rw_fmtlc() functions are returns len, but without updating the buf.endoff. Due to this the result of rw_asnprintf() is cutted in further processing.

        These problems are detected in 0.printf test after lates update.

        The schematic patch without error checking is below. This patch is not intended to apply. Its only shows how these bugs should be fixed.

        {noformat}
        Index: tests/src/fmt_bits.cpp
        ===================================================================
        --- tests/src/fmt_bits.cpp (revision 637399)
        +++ tests/src/fmt_bits.cpp (working copy)
        @@ -204,9 +204,12 @@
         
         #endif // _RWSTD_NO_EXT_BIN_IO
         
        - len = rw_asnprintf (buf.pbuf, buf.pbufsize,
        - "%{+} | %{?}std::ios::%{;}base(%d)",
        - spec.fl_pound, base);
        + (*buf.pbuf) [buf.endoff] = '\0';
        + int res = rw_asnprintf (buf.pbuf, buf.pbufsize,
        + "%{+} | %{?}std::ios::%{;}base(%d)",
        + spec.fl_pound, base);
        + buf.endoff += res;
        + len += res;
             }
         
             return len;
        @@ -303,9 +306,12 @@
                 : std::ios::erase_event == event ? "erase_event"
                 : 0;
         
        - return rw_asnprintf (buf.pbuf, buf.pbufsize,
        - "%{+}%{?}std::ios::%{;}%{?}%s%{:}event(%d)%{;}",
        - spec.fl_pound, 0 != str, str, event);
        + (*buf.pbuf) [buf.endoff] = '\0';
        + int len = rw_asnprintf (buf.pbuf, buf.pbufsize,
        + "%{+}%{?}std::ios::%{;}%{?}%s%{:}event(%d)%{;}",
        + spec.fl_pound, 0 != str, str, event);
        + buf.endoff += len;
        + return len;
         }
         
         /********************************************************************/
        @@ -329,8 +335,12 @@
         
             }
         
        - if (str)
        - return rw_asnprintf (buf.pbuf, buf.pbufsize, "%{+}%s", str);
        + if (str) {
        + (*buf.pbuf) [buf.endoff] = '\0';
        + int len = rw_asnprintf (buf.pbuf, buf.pbufsize, "%{+}%s", str);
        + buf.endoff += len;
        + return len;
        + }
         
             static const Bitnames names [] = {
                 BITNAME (std::locale, all),
        {noformat}
        The buf parameter of the _rw_fmtflags(), _rw_fmtevent() and _rw_fmtlc() functions contains not NUL-terminated data. The length of data in buf is stored in buf.endoff.
        The rw_asnprintf() function accepts the only buf.pbuf and buf.pbufsize, but not buf.endoff. When %{+} format is used, the length of data in buf calculated using strlen() function, but this length is incorrect due to data is not NUL-terminated.
        Another bug is that _rw_fmtflags(), _rw_fmtevent() and _rw_fmtlc() functions are returns len, but without updating the buf.endoff. Due to this the result of rw_asnprintf() is cutted in further processing.

        These problems are detected in 0.printf test after latest update.

        The schematic patch without error checking is below. This patch is not intended to apply. It's only shows how these bugs should be fixed.

        {noformat}
        Index: tests/src/fmt_bits.cpp
        ===================================================================
        --- tests/src/fmt_bits.cpp (revision 637399)
        +++ tests/src/fmt_bits.cpp (working copy)
        @@ -204,9 +204,12 @@
         
         #endif // _RWSTD_NO_EXT_BIN_IO
         
        - len = rw_asnprintf (buf.pbuf, buf.pbufsize,
        - "%{+} | %{?}std::ios::%{;}base(%d)",
        - spec.fl_pound, base);
        + (*buf.pbuf) [buf.endoff] = '\0';
        + int res = rw_asnprintf (buf.pbuf, buf.pbufsize,
        + "%{+} | %{?}std::ios::%{;}base(%d)",
        + spec.fl_pound, base);
        + buf.endoff += res;
        + len += res;
             }
         
             return len;
        @@ -303,9 +306,12 @@
                 : std::ios::erase_event == event ? "erase_event"
                 : 0;
         
        - return rw_asnprintf (buf.pbuf, buf.pbufsize,
        - "%{+}%{?}std::ios::%{;}%{?}%s%{:}event(%d)%{;}",
        - spec.fl_pound, 0 != str, str, event);
        + (*buf.pbuf) [buf.endoff] = '\0';
        + int len = rw_asnprintf (buf.pbuf, buf.pbufsize,
        + "%{+}%{?}std::ios::%{;}%{?}%s%{:}event(%d)%{;}",
        + spec.fl_pound, 0 != str, str, event);
        + buf.endoff += len;
        + return len;
         }
         
         /********************************************************************/
        @@ -329,8 +335,12 @@
         
             }
         
        - if (str)
        - return rw_asnprintf (buf.pbuf, buf.pbufsize, "%{+}%s", str);
        + if (str) {
        + (*buf.pbuf) [buf.endoff] = '\0';
        + int len = rw_asnprintf (buf.pbuf, buf.pbufsize, "%{+}%s", str);
        + buf.endoff += len;
        + return len;
        + }
         
             static const Bitnames names [] = {
                 BITNAME (std::locale, all),
        {noformat}
        Martin Sebor made changes -
        Attachment stdcxx-765.diff [ 12378012 ]
        Martin Sebor made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Fixed [ 1 ]
        Martin Sebor made changes -
        Assignee Martin Sebor [ sebor ]

          People

          • Assignee:
            Martin Sebor
            Reporter:
            Farid Zaripov
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development