Skip to content

Commit

Permalink
bug fixed for special char
Browse files Browse the repository at this point in the history
  • Loading branch information
yakolee committed May 5, 2014
1 parent 5e3ede7 commit cdf7cb2
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 73 deletions.
179 changes: 114 additions & 65 deletions src/main/java/com/alibaba/fastjson/serializer/SerializeWriter.java
Expand Up @@ -795,80 +795,129 @@ private void writeStringWithDoubleQuote(String text, final char seperator, boole
if (checkSpecial) {
for (int i = start; i < end; ++i) {
char ch = buf[i];

if (ch == '\u2028') {
specialCount++;
lastSpecialIndex = i;
lastSpecial = ch;
newcount += 4;

if (firstSpecialIndex == -1) {
firstSpecialIndex = i;
}
continue;
}

if (ch >= ']') {
if (ch == '\u2028') {
if (ch >= 0x7F && ch <= 0xA0) {
if (firstSpecialIndex == -1) {
firstSpecialIndex = i;
}

specialCount++;
lastSpecialIndex = i;
lastSpecial = ch;
newcount += 4;
if (firstSpecialIndex == -1) {
firstSpecialIndex = i;
}
}
continue;
}

if (ch == ' ') {
continue;
}

if (ch >= '0' && ch != '\\') {
continue;
}

if (ch < CharTypes.specicalFlags_doubleQuotes.length && CharTypes.specicalFlags_doubleQuotes[ch] != 0 //
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
if (isSpecial(ch, this.features)) {
specialCount++;
lastSpecialIndex = i;
lastSpecial = ch;

if (ch < CharTypes.specicalFlags_doubleQuotes.length //
&& CharTypes.specicalFlags_doubleQuotes[ch] == 4 //
) {
newcount += 4;
}

if (firstSpecialIndex == -1) {
firstSpecialIndex = i;
}
}
}
}

newcount += specialCount;
if (newcount > buf.length) {
expandCapacity(newcount);
}
count = newcount;
if (specialCount > 0) {
newcount += specialCount;
if (newcount > buf.length) {
expandCapacity(newcount);
}
count = newcount;

if (specialCount == 1) {
if (lastSpecial == '\u2028') {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 6;
int LengthOfCopy = end - lastSpecialIndex - 1;
System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = 'u';
buf[++lastSpecialIndex] = '2';
buf[++lastSpecialIndex] = '0';
buf[++lastSpecialIndex] = '2';
buf[++lastSpecialIndex] = '8';
} else {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 2;
int LengthOfCopy = end - lastSpecialIndex - 1;
System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial];
}
} else if (specialCount > 1) {
int textIndex = firstSpecialIndex - start;
int bufIndex = firstSpecialIndex;
for (int i = textIndex; i < text.length(); ++i) {
char ch = text.charAt(i);
if (specialCount == 1) {
if (lastSpecial == '\u2028') {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 6;
int LengthOfCopy = end - lastSpecialIndex - 1;
System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = 'u';
buf[++lastSpecialIndex] = '2';
buf[++lastSpecialIndex] = '0';
buf[++lastSpecialIndex] = '2';
buf[++lastSpecialIndex] = '8';
} else {
final char ch = lastSpecial;
if (ch < CharTypes.specicalFlags_doubleQuotes.length //
&& CharTypes.specicalFlags_doubleQuotes[ch] == 4) {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 6;
int LengthOfCopy = end - lastSpecialIndex - 1;
System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);

if (ch < CharTypes.specicalFlags_doubleQuotes.length //
&& CharTypes.specicalFlags_doubleQuotes[ch] != 0 //
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
buf[bufIndex++] = '\\';
buf[bufIndex++] = replaceChars[(int) ch];
end++;
} else {
buf[bufIndex++] = ch;
int bufIndex = lastSpecialIndex;
buf[bufIndex++] = '\\';
buf[bufIndex++] = 'u';
buf[bufIndex++] = CharTypes.digits[(ch >>> 12) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 8) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 4) & 15];
buf[bufIndex++] = CharTypes.digits[ch & 15];
} else {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 2;
int LengthOfCopy = end - lastSpecialIndex - 1;
System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = replaceChars[(int) ch];
}
}
} else if (specialCount > 1) {
int textIndex = firstSpecialIndex - start;
int bufIndex = firstSpecialIndex;
for (int i = textIndex; i < text.length(); ++i) {
char ch = text.charAt(i);

if (ch < CharTypes.specicalFlags_doubleQuotes.length //
&& CharTypes.specicalFlags_doubleQuotes[ch] != 0 //
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
buf[bufIndex++] = '\\';
if (CharTypes.specicalFlags_doubleQuotes[ch] == 4) {
buf[bufIndex++] = 'u';
buf[bufIndex++] = CharTypes.digits[(ch >>> 12) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 8) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 4) & 15];
buf[bufIndex++] = CharTypes.digits[ch & 15];
end += 5;
} else {
buf[bufIndex++] = replaceChars[(int) ch];
end++;
}
} else {
if (ch == '\u2028') {
buf[bufIndex++] = '\\';
buf[bufIndex++] = 'u';
buf[bufIndex++] = CharTypes.digits[(ch >>> 12) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 8) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 4) & 15];
buf[bufIndex++] = CharTypes.digits[ch & 15];
end += 5;
} else {
buf[bufIndex++] = ch;
}
}
}
}
}
}
Expand Down Expand Up @@ -1273,14 +1322,7 @@ private void writeFieldValueStringWithDoubleQuote(char seperator, String name, S
} else {
final char ch = lastSpecial;
if (ch < CharTypes.specicalFlags_doubleQuotes.length //
&& CharTypes.specicalFlags_doubleQuotes[ch] == 1) {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 2;
int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = replaceChars[(int) ch];
} else {
&& CharTypes.specicalFlags_doubleQuotes[ch] == 4) {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 6;
int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
Expand All @@ -1293,6 +1335,13 @@ private void writeFieldValueStringWithDoubleQuote(char seperator, String name, S
buf[bufIndex++] = CharTypes.digits[(ch >>> 8) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 4) & 15];
buf[bufIndex++] = CharTypes.digits[ch & 15];
} else {
int srcPos = lastSpecialIndex + 1;
int destPos = lastSpecialIndex + 2;
int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
buf[lastSpecialIndex] = '\\';
buf[++lastSpecialIndex] = replaceChars[(int) ch];
}
}
} else if (specialCount > 1) {
Expand All @@ -1305,16 +1354,16 @@ private void writeFieldValueStringWithDoubleQuote(char seperator, String name, S
&& CharTypes.specicalFlags_doubleQuotes[ch] != 0 //
|| (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
buf[bufIndex++] = '\\';
if (CharTypes.specicalFlags_doubleQuotes[ch] == 1) {
buf[bufIndex++] = replaceChars[(int) ch];
valueEnd++;
} else {
if (CharTypes.specicalFlags_doubleQuotes[ch] == 4) {
buf[bufIndex++] = 'u';
buf[bufIndex++] = CharTypes.digits[(ch >>> 12) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 8) & 15];
buf[bufIndex++] = CharTypes.digits[(ch >>> 4) & 15];
buf[bufIndex++] = CharTypes.digits[ch & 15];
valueEnd += 5;
} else {
buf[bufIndex++] = replaceChars[(int) ch];
valueEnd++;
}
} else {
if (ch == '\u2028') {
Expand Down
20 changes: 20 additions & 0 deletions src/test/java/com/alibaba/json/bvt/bug/Bug_for_dongqi.java
@@ -0,0 +1,20 @@
package com.alibaba.json.bvt.bug;

import java.util.HashMap;
import java.util.Map;

import org.junit.Assert;

import junit.framework.TestCase;

import com.alibaba.fastjson.JSON;


public class Bug_for_dongqi extends TestCase {
public void test_bug() throws Exception {
Map<String, Object> obj = new HashMap<String,Object>();
obj.put("value", ";\r\n3、ž 公");
System.out.print(JSON.toJSONString(obj));
Assert.assertEquals("{\"value\":\"\\r\\n3、\\u009E 公\"}", JSON.toJSONString(obj));
}
}
Expand Up @@ -11,35 +11,35 @@
public class TestSpecial_map extends TestCase {

public void test_0() throws Exception {
Assert.assertEquals("{\"name\":\"\\0\"}", JSON.toJSONString(Collections.singletonMap("name", "\0")));
Assert.assertEquals("{\"name\":\"\\u0000\"}", JSON.toJSONString(Collections.singletonMap("name", "\0")));
}

public void test_1() throws Exception {
Assert.assertEquals("{\"name\":\"\\1\"}", JSON.toJSONString(Collections.singletonMap("name", "\1")));
Assert.assertEquals("{\"name\":\"\\u0001\"}", JSON.toJSONString(Collections.singletonMap("name", "\1")));
}

public void test_2() throws Exception {
Assert.assertEquals("{\"name\":\"\\2\"}", JSON.toJSONString(Collections.singletonMap("name", "\2")));
Assert.assertEquals("{\"name\":\"\\u0002\"}", JSON.toJSONString(Collections.singletonMap("name", "\2")));
}

public void test_3() throws Exception {
Assert.assertEquals("{\"name\":\"\\3\"}", JSON.toJSONString(Collections.singletonMap("name", "\3")));
Assert.assertEquals("{\"name\":\"\\u0003\"}", JSON.toJSONString(Collections.singletonMap("name", "\3")));
}

public void test_4() throws Exception {
Assert.assertEquals("{\"name\":\"\\4\"}", JSON.toJSONString(Collections.singletonMap("name", "\4")));
Assert.assertEquals("{\"name\":\"\\u0004\"}", JSON.toJSONString(Collections.singletonMap("name", "\4")));
}

public void test_5() throws Exception {
Assert.assertEquals("{\"name\":\"\\5\"}", JSON.toJSONString(Collections.singletonMap("name", "\5")));
Assert.assertEquals("{\"name\":\"\\u0005\"}", JSON.toJSONString(Collections.singletonMap("name", "\5")));
}

public void test_6() throws Exception {
Assert.assertEquals("{\"name\":\"\\6\"}", JSON.toJSONString(Collections.singletonMap("name", "\6")));
Assert.assertEquals("{\"name\":\"\\u0006\"}", JSON.toJSONString(Collections.singletonMap("name", "\6")));
}

public void test_7() throws Exception {
Assert.assertEquals("{\"name\":\"\\7\"}", JSON.toJSONString(Collections.singletonMap("name", "\7")));
Assert.assertEquals("{\"name\":\"\\u0007\"}", JSON.toJSONString(Collections.singletonMap("name", "\7")));
}

public void test_8() throws Exception {
Expand Down

0 comments on commit cdf7cb2

Please sign in to comment.