surrogate pairs are representable in UTF8

#WEB-21028 fixed
This commit is contained in:
Dennis Ushakov
2016-05-24 18:34:38 +03:00
parent c6a637d0f1
commit 997f39dc89
3 changed files with 23 additions and 4 deletions
@@ -0,0 +1 @@
console.log("𝌆");
@@ -175,6 +175,18 @@ public class LossyEncodingTest extends DaemonAnalyzerTestCase {
assertEquals("File was loaded in the wrong encoding: 'UTF-8'", info.getDescription());
}
public void testSurrogateUTF8() throws Exception {
VirtualFile virtualFile = getVirtualFile(BASE_PATH + "/" + "surrogate.txt");
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
configureByExistingFile(virtualFile);
final Document document = FileDocumentManager.getInstance().getDocument(virtualFile);
assertFalse(FileDocumentManager.getInstance().isDocumentUnsaved(document));
assertEquals(CharsetToolkit.UTF8_CHARSET, virtualFile.getCharset());
assertEmpty(doHighlighting());
}
public void testInconsistentLineSeparators() throws Exception {
VirtualFile virtualFile = getVirtualFile(BASE_PATH + "/" + getTestName(false) + ".txt");
configureByExistingFile(virtualFile);
@@ -38,6 +38,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.encoding.ChangeFileEncodingAction;
import com.intellij.openapi.vfs.encoding.EncodingUtil;
@@ -173,8 +174,10 @@ public class LossyEncodingInspection extends LocalInspectionTool {
int errorCount = 0;
int start = -1;
for (int i = 0; i <= text.length(); i++) {
char c = i == text.length() ? 0 : text.charAt(i);
if (i == text.length() || isRepresentable(c, charset)) {
char c = i >= text.length() ? 0 : text.charAt(i);
char next = i + 1 >= text.length() ? 0 : text.charAt(i + 1);
char prev = i == 0 ? 0 : text.charAt(i - 1);
if (i == text.length() || isRepresentable(c, next, prev, charset)) {
if (start != -1) {
TextRange range = new TextRange(start, i);
String message = InspectionsBundle.message("unsupported.character.for.the.charset", charset);
@@ -192,8 +195,11 @@ public class LossyEncodingInspection extends LocalInspectionTool {
}
}
private static boolean isRepresentable(final char c, @NotNull Charset charset) {
String str = Character.toString(c);
private static boolean isRepresentable(final char c, final char next, char prev, @NotNull Charset charset) {
if (charset == CharsetToolkit.UTF8_CHARSET) {
if (Character.isSurrogatePair(c, next) || Character.isSurrogatePair(prev, c)) return true;
}
String str = String.valueOf(c);
ByteBuffer out = charset.encode(str);
CharBuffer buffer = charset.decode(out);
return str.equals(buffer.toString());