Fix NULL string printing in printf (dotnet/coreclr#8800)
authorJan Vorlicek <janvorli@microsoft.com>
Wed, 4 Jan 2017 21:05:43 +0000 (22:05 +0100)
committerGitHub <noreply@github.com>
Wed, 4 Jan 2017 21:05:43 +0000 (22:05 +0100)
The functions implementing various printf flavors in PAL were not handling
correctly the case when a string pointer passed to them for %S and %s formats
was NULL. Instead of printing `(null)`, they were crashing.

This change fixes the problem and also adds PAL tests to verify it is working
properly.

Commit migrated from https://github.com/dotnet/coreclr/commit/edc1320180a3d68a16855da8da82f01871bf3a1d

28 files changed:
src/coreclr/src/pal/src/cruntime/printfcpp.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_snprintf_s/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_snprintf_s/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_snwprintf_s/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_vsnprintf_s/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_vsnprintf_s/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/_vsnwprintf_s/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/fprintf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/fprintf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/fwprintf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/fwprintf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/printf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/printf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/sprintf_s/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/sprintf_s/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/swprintf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/swprintf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vfprintf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vfprintf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vprintf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vprintf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vsprintf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vsprintf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vswprintf/test2/test2.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/vswprintf/test3/test3.cpp
src/coreclr/src/pal/tests/palsuite/c_runtime/wprintf/test2/test2.cpp

index 85ec698..0b90721 100644 (file)
@@ -35,6 +35,9 @@ SET_DEFAULT_DEBUG_CHANNEL(CRT);
 
 using namespace CorUnix;
 
+static const char __nullstring[] = "(null)";  /* string to print on null ptr */
+static const WCHAR __wnullstring[] = W("(null)"); /* string to print on null ptr */
+
 int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, va_list ap);
 int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *format, va_list ap);
 
@@ -863,7 +866,7 @@ Parameters:
     - padding style flags (PRINTF_FORMAT_FLAGS)
 *******************************************************************************/
 
-INT Internal_AddPaddingVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, LPSTR In,
+INT Internal_AddPaddingVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, LPCSTR In,
                                        INT Padding, INT Flags)
 {
     LPSTR Out;
@@ -1096,7 +1099,8 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
 {
     CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */
     LPCWSTR Fmt = format;
-    LPWSTR TempWStr = NULL;
+    LPCWSTR TempWStr = NULL;
+    LPWSTR AllocedTempWStr = NULL;
     LPWSTR WorkingWStr = NULL;
     WCHAR TempWChar[2];
     INT Flags;
@@ -1105,7 +1109,6 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
     INT Prefix;
     INT Type;
     INT TempInt;
-    BOOL WStrWasMalloced = FALSE;
     int mbtowcResult;
     int written=0;
     int paddingReturnValue;
@@ -1133,7 +1136,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
                  (Type == PFF_TYPE_STRING || Type == PFF_TYPE_WSTRING)) ||
                  (Type == PFF_TYPE_WSTRING && (Flags & PFF_ZERO) != 0))
             {
-                WStrWasMalloced = FALSE;
+                AllocedTempWStr = NULL;
 
                 if (WIDTH_STAR == Width)
                 {
@@ -1162,37 +1165,50 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
                 else
                 {
                     /* %lS assumes a LPSTR argument. */
-                    LPSTR s = va_arg(ap, LPSTR );
-                    UINT Length = 0;
-                    Length = MultiByteToWideChar( CP_ACP, 0, s, -1, NULL, 0 );
-                    if ( Length != 0 )
+                    LPCSTR s = va_arg(ap, LPSTR );
+                    if (s == NULL)
+                    {
+                        TempWStr = NULL;
+                    }
+                    else
                     {
-                        TempWStr =
-                            (LPWSTR)InternalMalloc( (Length) * sizeof( WCHAR ) );
-                        if ( TempWStr )
+                        UINT Length = 0;
+                        Length = MultiByteToWideChar( CP_ACP, 0, s, -1, NULL, 0 );
+                        if ( Length != 0 )
                         {
-                            WStrWasMalloced = TRUE;
-                            MultiByteToWideChar( CP_ACP, 0, s, -1,
-                                                 TempWStr, Length );
+                            AllocedTempWStr =
+                                (LPWSTR)InternalMalloc( (Length) * sizeof( WCHAR ) );
+                            
+                            if ( AllocedTempWStr )
+                            {
+                                MultiByteToWideChar( CP_ACP, 0, s, -1,
+                                                     AllocedTempWStr, Length );
+                                TempWStr = AllocedTempWStr;
+                            }
+                            else
+                            {
+                                ERROR( "InternalMalloc failed.\n" );
+                                LOGEXIT("vfwprintf returns int -1\n");
+                                PERF_EXIT(vfwprintf);
+                                va_end(ap);
+                                return -1;
+                            }
                         }
                         else
                         {
-                            ERROR( "InternalMalloc failed.\n" );
+                            ASSERT( "Unable to convert from multibyte "
+                                   " to wide char.\n" );
                             LOGEXIT("vfwprintf returns int -1\n");
                             PERF_EXIT(vfwprintf);
                             va_end(ap);
                             return -1;
                         }
                     }
-                    else
-                    {
-                        ASSERT( "Unable to convert from multibyte "
-                               " to wide char.\n" );
-                        LOGEXIT("vfwprintf returns int -1\n");
-                        PERF_EXIT(vfwprintf);
-                        va_end(ap);
-                        return -1;
-                    }
+                }
+
+                if (TempWStr == NULL)
+                {
+                    TempWStr = __wnullstring;
                 }
 
                 INT Length = PAL_wcslen(TempWStr);
@@ -1203,10 +1219,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
                     LOGEXIT("vfwprintf returns int -1\n");
                     PERF_EXIT(vfwprintf);
                     pthrCurrent->SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                    if (WStrWasMalloced)
-                    {
-                        free(TempWStr);
-                    }
+                    free(AllocedTempWStr);
                     va_end(ap);
                     return -1;
                 }
@@ -1221,10 +1234,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
                     if (wcsncpy_s(WorkingWStr, (Length + 1), TempWStr, Precision+1) != SAFECRT_SUCCESS)
                     {
                         ERROR("Internal_AddPaddingVfwprintf failed\n");
-                        if (WStrWasMalloced)
-                        {
-                            free(TempWStr);
-                        }
+                        free(AllocedTempWStr);
                         free(WorkingWStr);
                         LOGEXIT("wcsncpy_s failed!\n");
                         PERF_EXIT(vfwprintf);
@@ -1250,10 +1260,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
                 if (paddingReturnValue == -1)
                 {
                     ERROR("Internal_AddPaddingVfwprintf failed\n");
-                    if (WStrWasMalloced)
-                    {
-                        free(TempWStr);
-                    }
+                    free(AllocedTempWStr);
                     free(WorkingWStr);
                     LOGEXIT("vfwprintf returns int -1\n");
                     PERF_EXIT(vfwprintf);
@@ -1263,10 +1270,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for
                 written += paddingReturnValue;
 
                 free(WorkingWStr);
-                if (WStrWasMalloced)
-                {
-                    free(TempWStr);
-                }
+                free(AllocedTempWStr);
             }
             else if (Prefix == PFF_PREFIX_LONG && Type == PFF_TYPE_CHAR)
             {
@@ -1525,7 +1529,7 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format,
 {
     CHAR TempBuff[1024]; /* used to hold a single %<foo> format string */
     LPCSTR Fmt = format;
-    LPWSTR TempWStr;
+    LPCWSTR TempWStr;
     LPSTR TempStr;
     WCHAR TempWChar;
     INT Flags;
@@ -1574,6 +1578,10 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format,
                 }
 
                 TempWStr = va_arg(ap, LPWSTR);
+                if (TempWStr == NULL)\
+                {
+                    TempWStr = __wnullstring;
+                }
                 Length = WideCharToMultiByte(CP_ACP, 0, TempWStr, -1, 0,
                                              0, 0, 0);
                 if (!Length)
@@ -1743,9 +1751,13 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format,
             {
                 // Some versions of fprintf don't support 0-padded strings,
                 // so we handle them here.
-                char *tempStr;
+                const char *tempStr;
 
                 tempStr = va_arg(ap, char *);
+                if (tempStr == NULL)
+                {
+                    tempStr = __nullstring;
+                }
                 Length = strlen(tempStr);
                 paddingReturnValue = Internal_AddPaddingVfprintf(
                                                 pthrCurrent,
index e586694..54ef80b 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");   
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoWStrTest("foo %ls", NULL, "foo (null)");
+    DoWStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index 3c52b44..99c25a6 100644 (file)
@@ -39,6 +39,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
     
     PAL_Terminate();
     return PASS;
index 86bfdc9..7d8dd65 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo    ba"));
     DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar  "));
     DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
+    DoWStrTest(convert("foo %s"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hs"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ws"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %Ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %I64s"), NULL, convert("foo (null)"));
 
     PAL_Terminate();
     return PASS;
index f6db6f2..b4a4a32 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest(convert("foo %5.2S"), "bar", convert("foo    ba"));
     DoStrTest(convert("foo %-5S"), "bar", convert("foo bar  "));
     DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
+    DoStrTest(convert("foo %S"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %lS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %wS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %LS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %I64S"), NULL, convert("foo (null)"));
 
     PAL_Terminate();
     return PASS;
index 69c8c27..e5808f3 100644 (file)
@@ -37,6 +37,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");   
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoWStrTest("foo %ls", NULL, "foo (null)");
+    DoWStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index a244aa4..bb8b153 100644 (file)
@@ -37,6 +37,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
     
     PAL_Terminate();
     return PASS;
index 18e5adf..b2958df 100644 (file)
@@ -34,6 +34,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo    ba"));
     DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar  "));
     DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
+    DoWStrTest(convert("foo %s"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hs"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ws"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %Ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %I64s"), NULL, convert("foo (null)"));
 
     PAL_Terminate();
     return PASS;
index 5e2bfa2..657a911 100644 (file)
@@ -34,6 +34,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest(convert("foo %5.2S"), "bar", convert("foo    ba"));
     DoStrTest(convert("foo %-5S"), "bar", convert("foo bar  "));
     DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
+    DoStrTest(convert("foo %S"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %lS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %wS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %LS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %I64S"), NULL, convert("foo (null)"));
 
     PAL_Terminate();
     return PASS;
index 1ed7f3f..1441827 100644 (file)
@@ -36,6 +36,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoWStrTest("foo %ls", NULL, "foo (null)");
+    DoWStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;    
index 6185135..dd34c08 100644 (file)
@@ -35,6 +35,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index ecd3c51..1e03147 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest(convert("foo %5.2s"), convert("bar"), "foo    ba");
     DoWStrTest(convert("foo %-5s"), convert("bar"), "foo bar  ");
     DoWStrTest(convert("foo %05s"), convert("bar"), "foo 00bar");
+    DoWStrTest(convert("foo %s"), NULL, "foo (null)");
+    DoStrTest(convert("foo %hs"), NULL, "foo (null)");
+    DoWStrTest(convert("foo %ls"), NULL, "foo (null)");
+    DoWStrTest(convert("foo %ws"), NULL, "foo (null)");
+    DoWStrTest(convert("foo %Ls"), NULL, "foo (null)");
+    DoWStrTest(convert("foo %I64s"), NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;    
index d718a19..ff24aa7 100644 (file)
@@ -37,6 +37,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest(convert("foo %5.2S"),"bar", "foo    ba");
     DoStrTest(convert("foo %-5S"), "bar", "foo bar  ");
     DoStrTest(convert("foo %05S"), "bar", "foo 00bar");
+    DoStrTest(convert("foo %S"), NULL, "foo (null)");
+    DoStrTest(convert("foo %hS"), NULL, "foo (null)");
+    DoWStrTest(convert("foo %lS"), NULL, "foo (null)");
+    DoWStrTest(convert("foo %wS"), NULL, "foo (null)");
+    DoStrTest(convert("foo %LS"), NULL, "foo (null)");
+    DoStrTest(convert("foo %I64S"), NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index e766ef4..1c61b1d 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoWStrTest("foo %ls", NULL, "foo (null)");
+    DoWStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;    
index 5cc5309..79fe721 100644 (file)
@@ -37,6 +37,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index 990f4f0..a3eb71d 100644 (file)
@@ -40,6 +40,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoWStrTest("foo %ls", NULL, "foo (null)");
+    DoWStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;    
index c0dc8e1..dd6e590 100644 (file)
@@ -39,6 +39,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index deffd3e..1c2f420 100644 (file)
@@ -40,6 +40,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo    ba"));
     DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar  "));
     DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
+    DoWStrTest(convert("foo %s"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hs"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ws"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %Ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %I64s"), NULL, convert("foo (null)"));
 
     PAL_Terminate();
     return PASS;
index 42875c0..8c6c38c 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest(convert("foo %5.2S"),"bar", convert("foo    ba"));
     DoStrTest(convert("foo %-5S"), "bar", convert("foo bar  "));
     DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
+    DoStrTest(convert("foo %S"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %lS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %wS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %LS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %I64S"), NULL, convert("foo (null)"));
     PAL_Terminate();
     return PASS;
 }
index d01117f..0228734 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoStrTest("foo %ls", NULL, "foo (null)");
+    DoStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;    
index 0081daa..879446f 100644 (file)
@@ -37,6 +37,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index 4d9c9bc..72b79e5 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoWStrTest("foo %ls", NULL, "foo (null)");
+    DoWStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;    
index 5376c56..66cd509 100644 (file)
@@ -37,6 +37,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index fbd4b41..fc9163e 100644 (file)
@@ -36,6 +36,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest("foo %5.2s", "bar", "foo    ba");
     DoStrTest("foo %-5s", "bar", "foo bar  ");
     DoStrTest("foo %05s", "bar", "foo 00bar");   
+    DoStrTest("foo %s", NULL, "foo (null)");
+    DoStrTest("foo %hs", NULL, "foo (null)");
+    DoWStrTest("foo %ls", NULL, "foo (null)");
+    DoWStrTest("foo %ws", NULL, "foo (null)");
+    DoStrTest("foo %Ls", NULL, "foo (null)");
+    DoStrTest("foo %I64s", NULL, "foo (null)");
 
     PAL_Terminate();
     return PASS;
index 742370e..4656bf3 100644 (file)
@@ -37,6 +37,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest("foo %5.2S", convert("bar"), "foo    ba");
     DoWStrTest("foo %-5S", convert("bar"), "foo bar  ");
     DoWStrTest("foo %05S", convert("bar"), "foo 00bar");
+    DoWStrTest("foo %S", NULL, "foo (null)");
+    DoStrTest("foo %hS", NULL, "foo (null)");
+    DoWStrTest("foo %lS", NULL, "foo (null)");
+    DoWStrTest("foo %wS", NULL, "foo (null)");
+    DoWStrTest("foo %LS", NULL, "foo (null)");
+    DoWStrTest("foo %I64S", NULL, "foo (null)");
     
     PAL_Terminate();
     return PASS;
index 491d99f..a7b1b3a 100644 (file)
@@ -34,6 +34,12 @@ int __cdecl main(int argc, char *argv[])
     DoWStrTest(convert("foo %5.2s"), convert("bar"), convert("foo    ba"));
     DoWStrTest(convert("foo %-5s"), convert("bar"), convert("foo bar  "));
     DoWStrTest(convert("foo %05s"), convert("bar"), convert("foo 00bar"));
+    DoWStrTest(convert("foo %s"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hs"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %ws"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %Ls"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %I64s"), NULL, convert("foo (null)"));
 
     PAL_Terminate();
     return PASS;
index 1eb0b65..40c7d2a 100644 (file)
@@ -34,6 +34,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest(convert("foo %5.2S"), "bar", convert("foo    ba"));
     DoStrTest(convert("foo %-5S"), "bar", convert("foo bar  "));
     DoStrTest(convert("foo %05S"), "bar", convert("foo 00bar"));
+    DoStrTest(convert("foo %S"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %hS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %lS"), NULL, convert("foo (null)"));
+    DoWStrTest(convert("foo %wS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %LS"), NULL, convert("foo (null)"));
+    DoStrTest(convert("foo %I64S"), NULL, convert("foo (null)"));
 
     PAL_Terminate();
     return PASS;
index 254e98a..4e54d45 100644 (file)
@@ -38,6 +38,12 @@ int __cdecl main(int argc, char *argv[])
     DoStrTest(u"foo %5.2s", u"bar", u"foo    ba");
     DoStrTest(u"foo %-5s", u"bar", u"foo bar  ");
     DoStrTest(u"foo %05s", u"bar", u"foo 00bar");
+    DoStrTest(u"foo %s", NULL, u"foo (null)");
+    DoStrTest(u"foo %hs", NULL, u"foo (null)");
+    DoStrTest(u"foo %ls", NULL, u"foo (null)");
+    DoStrTest(u"foo %ws", NULL, u"foo (null)");
+    DoStrTest(u"foo %Ls", NULL, u"foo (null)");
+    DoStrTest(u"foo %I64s", NULL, u"foo (null)");
 
     PAL_Terminate();
     return PASS;