]> granicus.if.org Git - icu/commitdiff
ICU-8901 u_formatMessage(unused argument): ignore unused argument, no failure
authorMarkus Scherer <markus.icu@gmail.com>
Sun, 7 Oct 2012 02:50:40 +0000 (02:50 +0000)
committerMarkus Scherer <markus.icu@gmail.com>
Sun, 7 Oct 2012 02:50:40 +0000 (02:50 +0000)
X-SVN-Rev: 32541

icu4c/source/i18n/msgfmt.cpp
icu4c/source/i18n/umsg.cpp
icu4c/source/test/cintltst/cmsgtst.c

index de28260a47c7467baafbe6abed664b5ce0964835..3c74aa5be0553148e04f1104d0f809c35e78513c 100644 (file)
@@ -1490,6 +1490,7 @@ void MessageFormat::cacheExplicitFormats(UErrorCode& status) {
     }
     // Set all argTypes to kObject, as a "none" value, for lack of any better value.
     // We never use kObject for real arguments.
+    // We use it as "no argument yet" for the check for hasArgTypeConflicts.
     for (int32_t i = 0; i < argTypeCount; ++i) {
         argTypes[i] = Formattable::kObject;
     }
index 33015dd467a17632a6e3eab8f9b7af2fd4dc3784..8143932e7ef13cb4d6558824a23d7e86ae7c2989 100644 (file)
@@ -1,7 +1,7 @@
 /*
 *******************************************************************************
 *
-*   Copyright (C) 1999-2011, International Business Machines
+*   Copyright (C) 1999-2012, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *
 *******************************************************************************
@@ -457,11 +457,12 @@ umsg_vformat(   const UMessageFormat *fmt,
             break;
 
         case Formattable::kObject:
+            // Unused argument number. Read and ignore a pointer argument.
+            va_arg(ap, void*);
+            break;
+
         default:
-            // This will never happen because MessageFormat doesn't
-            // support kObject.  When MessageFormat is changed to
-            // understand MeasureFormats, modify this code to do the
-            // right thing. [alan]
+            // Unknown/unsupported argument type.
             U_ASSERT(FALSE);
             *status=U_ILLEGAL_ARGUMENT_ERROR;
             break;
index a16b1ba31ada8aa8c48b5e82acf5796dc15fcfb0..dc605765433f441cc2f2cbde193d8a9a10797831 100644 (file)
@@ -28,6 +28,8 @@
 #include "cmsgtst.h"
 #include "cformtst.h"
 
+#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
+
 static const char* const txt_testCasePatterns[] = {
    "Quotes '', '{', a {0,number,integer} '{'0}",
    "Quotes '', '{', a {0,number,integer} '{'0}",
@@ -1110,6 +1112,24 @@ static void MessageLength(void)
     }
 }
 
+static void TestMessageWithUnusedArgNumber() {
+    UErrorCode errorCode = U_ZERO_ERROR;
+    U_STRING_DECL(pattern, "abc {1} def", 11);
+    UChar x[2] = { 0x78, 0 };  // "x"
+    UChar y[2] = { 0x79, 0 };  // "y"
+    U_STRING_DECL(expected, "abc y def", 9);
+    UChar result[20];
+    int32_t length;
+
+    U_STRING_INIT(pattern, "abc {1} def", 11);
+    U_STRING_INIT(expected, "abc y def", 9);
+    length = u_formatMessage("en", pattern, -1, result, LENGTHOF(result), &errorCode, x, y);
+    if (U_FAILURE(errorCode) || length != u_strlen(expected) || u_strcmp(result, expected) != 0) {
+        log_err("u_formatMessage(pattern with only {1}, 2 args) failed: result length %d, UErrorCode %s \n",
+                (int)length, u_errorName(errorCode));
+    }
+}
+
 static void TestErrorChaining(void) {
     UErrorCode status = U_USELESS_COLLATOR_ERROR;
 
@@ -1164,6 +1184,7 @@ void addMsgForTest(TestNode** root)
     addTest(root, &TestParseMessageWithValist, "tsformat/cmsgtst/TestParseMessageWithValist");
     addTest(root, &TestJ904, "tsformat/cmsgtst/TestJ904");
     addTest(root, &MessageLength, "tsformat/cmsgtst/MessageLength");
+    addTest(root, &TestMessageWithUnusedArgNumber, "tsformat/cmsgtst/TestMessageWithUnusedArgNumber");
     addTest(root, &TestErrorChaining, "tsformat/cmsgtst/TestErrorChaining");
     addTest(root, &TestMsgFormatSelect, "tsformat/cmsgtst/TestMsgFormatSelect");
 }