Diff
Not logged in

Differences From Artifact [0dcc7991ab]:

To Artifact [ac914a5f27]:


77
78
79
80
81
82
83

84
85
86
87
88
89
90
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91







+







};

/*
 * Functions used only in this module.
 */

static int		UtfCount(int ch);
static int		Overlong(unsigned char *src);

/*
 *---------------------------------------------------------------------------
 *
 * UtfCount --
 *
 *	Find the number of bytes in the Utf character "ch".
111
112
113
114
115
116
117
118





















































119
120
121
122
123
124
125
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178







-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#if TCL_UTF_MAX > 3
    if (((unsigned)(ch - 0x10000) <= 0xFFFFF)) {
	return 4;
    }
#endif
    return 3;
}


/*
 *---------------------------------------------------------------------------
 *
 * Overlong --
 *
 *	Utility routine to report whether /src/ points to the start of an
 *	overlong byte sequence that should be rejected.
 *
 * Results:
 *	A boolean.
 *---------------------------------------------------------------------------
 */

INLINE static int
Overlong(
    unsigned char *src)		/* Points to lead byte of a UTF-8 byte
				 * sequence. Caller guarantees it is safe
				 * to read src[0] and src[1]. */
{
    switch (*src) {
    case 0xC0:
	if (src[1] == 0x80) {
	    /* Valid sequence: \xC0\x80 for \u0000 */
	    return 0;
	}
	/* Reject overlong: \xC0\x81 - \xC0\xBF */
	return 1;
    case 0xC1:
	/* Reject overlong: \xC1\x80 - \xC1\xBF */
	return 1;
    case 0xE0:
	if (src[1] < 0xA0) {
	    /* Reject overlong: \xE0\x80\x80 - \xE0\x9F\xBF */
	    return 1;
	}
	/* Valid sequence: \xE0\xA0\x80 for \u0800 , etc. */
	return 0;
#if TCL_UTF_MAX > 3
    case 0xF0:
	if (src[1] < 0x90) {
	    /* Reject overlong: \xF0\x80\x80\x80 - \xF0\x8F\xBF\xBF */
	    return 1;
	}
	/* Valid sequence: \xF0\x90\x80\x80 for \U10000 , etc. */
	return 0
#endif
    default:
	/* All other lead bytes lead only valid sequences */
	return 0;
    }
}

/*
 *---------------------------------------------------------------------------
 *
 * Tcl_UniCharToUtf --
 *
 *	Store the given Tcl_UniChar as a sequence of UTF-8 bytes in the
 *	provided buffer. Equivalent to Plan 9 runetochar().
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768

769
770
771
772
773
774

775
776

777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
805
806
807
808
809
810
811







812



813
814





815


816













817
818
819
820
821
822
823







-
-
-
-
-
-
-
+
-
-
-
+

-
-
-
-
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-







	    }

	    /*
	     * trailBytesSeen > 0, so we can examine look[1] safely.
	     * Use that capability to screen out overlong sequences.
	     */

	    switch (byte) {
	    case 0xC0:
		if (look[1] == 0x80) {
		    /* Valid sequence: \xC0\x80 for \u0000 */
		    return (CONST char *)look;
		}
		/* Reject overlong: \xC0\x81 - \xC0\xBF */
	    if (Overlong(look)) {
		return fallback;
	    case 0xC1:
		/* Reject overlong: \xC1\x80 - \xC1\xBF */
		/* Reject */
		return fallback;
	    case 0xE0:
		if (look[1] < 0xA0) {
		    /* Reject overlong: \xE0\x80\x80 - \xE0\x9F\xBF */
		    return fallback;
		}
	    }
		/* Valid sequence: \xE0\xA0\x80 for \u0800 , etc. */
		return (CONST char *)look;
	    return (CONST char *)look;
#if TCL_UTF_MAX > 3
	    case 0xF0:
		if (look[1] < 0x90) {
		    /* Reject overlong: \xF0\x80\x80\x80 - \xF0\x8F\xBF\xBF */
		    return fallback;
		}
		/* Valid sequence: \xF0\x90\x80\x80 for \U10000 , etc. */
		return (CONST char *)look;
#endif
	    default:
		/* All other lead bytes lead only valid sequences */
		return (CONST char *)look;
	    }
	}

	/* We saw a trail byte. */
	trailBytesSeen++;

	if ((CONST char *)look == start) {
	    /*