+/* Tests for empty segments in ISO-2022-JP/KR/CN, HZ, check that UConverterCallbackReason is UCNV_IRREGULAR */
+typedef struct {
+ const char * converterName;
+ const char * inputText;
+ int inputTextLength;
+} EmptySegmentTest;
+
+/* Callback for TestJitterbug6175, should only get called for empty segment errors */
+static void UCNV_TO_U_CALLBACK_EMPTYSEGMENT( const void *context, UConverterToUnicodeArgs *toArgs, const char* codeUnits,
+ int32_t length, UConverterCallbackReason reason, UErrorCode * err ) {
+ if (reason > UCNV_IRREGULAR)
+ return;
+ if (reason != UCNV_IRREGULAR)
+ log_err("toUnicode callback invoked for empty segment but reason is not UCNV_IRREGULAR\n");
+ /* Standard stuff below from UCNV_TO_U_CALLBACK_SUBSTITUTE */
+ *err = U_ZERO_ERROR;
+ ucnv_cbToUWriteSub(toArgs,0,err);
+}
+
+enum { kEmptySegmentToUCharsMax = 64 };
+static void TestJitterbug6175(void) {
+ static const char iso2022jp_a[] = { 0x61, 0x62, 0x1B,0x24,0x42, 0x1B,0x28,0x42, 0x63, 0x64, 0x0D, 0x0A };
+ static const char iso2022kr_a[] = { 0x1B,0x24,0x29,0x43, 0x61, 0x0E, 0x0F, 0x62, 0x0D, 0x0A };
+ static const char iso2022cn_a[] = { 0x61, 0x1B,0x24,0x29,0x41, 0x62, 0x0E, 0x0F, 0x1B,0x24,0x2A,0x48, 0x1B,0x4E, 0x6A,0x65, 0x63, 0x0D, 0x0A };
+ static const char iso2022cn_b[] = { 0x61, 0x1B,0x24,0x29,0x41, 0x62, 0x0E, 0x1B,0x24,0x29,0x47, 0x68,0x64, 0x0F, 0x63, 0x0D, 0x0A };
+ static const char hzGB2312_a[] = { 0x61, 0x62, 0x7E,0x7B, 0x7E,0x7D, 0x63, 0x64 };
+ static const EmptySegmentTest emptySegmentTests[] = {
+ /* converterName inputText inputTextLength */
+ { "ISO-2022-JP", iso2022jp_a, sizeof(iso2022jp_a) },
+ { "ISO-2022-KR", iso2022kr_a, sizeof(iso2022kr_a) },
+ { "ISO-2022-CN", iso2022cn_a, sizeof(iso2022cn_a) },
+ { "ISO-2022-CN", iso2022cn_b, sizeof(iso2022cn_b) },
+ { "HZ-GB-2312", hzGB2312_a, sizeof(hzGB2312_a) },
+ /* terminator: */
+ { NULL, NULL, 0, }
+ };
+ const EmptySegmentTest * testPtr;
+ for (testPtr = emptySegmentTests; testPtr->converterName != NULL; ++testPtr) {
+ UErrorCode err = U_ZERO_ERROR;
+ UConverter * cnv = ucnv_open(testPtr->converterName, &err);
+ if (U_FAILURE(err)) {
+ log_data_err("Unable to open %s converter: %s\n", testPtr->converterName, u_errorName(err));
+ return;
+ }
+ ucnv_setToUCallBack(cnv, UCNV_TO_U_CALLBACK_EMPTYSEGMENT, NULL, NULL, NULL, &err);
+ if (U_FAILURE(err)) {
+ log_data_err("Unable to setToUCallBack for %s converter: %s\n", testPtr->converterName, u_errorName(err));
+ ucnv_close(cnv);
+ return;
+ }
+ {
+ UChar toUChars[kEmptySegmentToUCharsMax];
+ UChar * toUCharsPtr = toUChars;
+ const UChar * toUCharsLimit = toUCharsPtr + kEmptySegmentToUCharsMax;
+ const char * inCharsPtr = testPtr->inputText;
+ const char * inCharsLimit = inCharsPtr + testPtr->inputTextLength;
+ ucnv_toUnicode(cnv, &toUCharsPtr, toUCharsLimit, &inCharsPtr, inCharsLimit, NULL, TRUE, &err);
+ }
+ ucnv_close(cnv);
+ }
+}
+