`
javatar
  • 浏览: 1705045 次
  • 性别: Icon_minigender_1
  • 来自: 杭州699号
社区版块
存档分类
最新评论

Hessian3.2.1在序列化32.5k字符串时的问题

阅读更多
转于自己在公司的Blog:
http://pt.alibaba-inc.com/wp/experience_929/hessian-big-string-serialize-problems.html

网站出现比较奇怪的现象,线上总有些Offer信息反序化时出错,而测试环境却没有出现过,

通过远程调试线上环境,发现Hessian3.2.1在处理0x33标记时,会出错,跟进去发现:

Hessian3.2.1在处理大String时,以32k为一个块,最后一个不满32k的块分三种情况处理:

(1) 块大小为1到31个byte时:
用一个byte表示长度(一个byte最多表示31的长度),后面跟具体数据。

(2) 块大小为32到1023个byte时:
用两个byte表示长度,后面跟具体数据,因只需要高位byte的4个bit位,加低位byte就能够表示1023的长度,为了不浪费,高位byte的另外4个bit位被压缩用于flag。

(3) 块大小为1023到32k-1个byte时:
用’s’前缀标识为小块,进行块读取。

问题出在第二种情况,Hessian2Input没有还原压缩的4个bit位。

(1) 异常信息: (出错位置上的串已改为xxx表示)
expected string at 0x33 java.lang.String (xxx)

at com.caucho.hessian.io.Hessian2Input.error(Hessian2Input.java:2714)

at com.caucho.hessian.io.Hessian2Input.expect(Hessian2Input.java:2685)

at com.caucho.hessian.io.Hessian2Input.parseChar(Hessian2Input.java:2442)

at com.caucho.hessian.io.Hessian2Input.readString(Hessian2Input.java:1285)

at com.caucho.hessian.io.JavaDeserializer$StringFieldDeserializer.deserialize(JavaDeserializer.java:580)

... 21 more

at com.caucho.hessian.io.JavaDeserializer.logDeserializeError(JavaDeserializer.java:671)

at com.caucho.hessian.io.JavaDeserializer$StringFieldDeserializer.deserialize(JavaDeserializer.java:584)

at com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:233)

at com.caucho.hessian.io.JavaDeserializer.readObject(JavaDeserializer.java:157)

at com.caucho.hessian.io.Hessian2Input.readObjectInstance(Hessian2Input.java:2067)

at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1592)

at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1576)

... 14 more

(2) 问题代码: (Hessian2Input)
private int parseChar() throws IOException
{

while (_chunkLength <= 0) {

if (_isLastChunk)

return -1;

int code = _offset < _length ? (_buffer[_offset++] & 0xff) : read();

switch (code) {

case BC_STRING_CHUNK:

_isLastChunk = false;

_chunkLength = (read() << 8 ) + read();

break;

case 'S':

_isLastChunk = true;

_chunkLength = (read() << 8 ) + read();

break;

case 0x00: case 0x01: case 0x02: case 0x03:

case 0x04: case 0x05: case 0x06: case 0x07:

case 0x08: case 0x09: case 0x0a: case 0x0b:

case 0x0c: case 0x0d: case 0x0e: case 0x0f:

case 0x10: case 0x11: case 0x12: case 0x13:

case 0x14: case 0x15: case 0x16: case 0x17:

case 0x18: case 0x19: case 0x1a: case 0x1b:

case 0x1c: case 0x1d: case 0x1e: case 0x1f:

_isLastChunk = true;

_chunkLength = code - 0x00;

break;

// 问题所在,没有处理结尾块在1F到1K范围内时压缩的4个bit位
// 下面四行是新增的修复代码:
case 0x30: case 0x31: case 0x32: case 0x33:
_isLastChunk = true;
_chunkLength = ((code - 0x30) << 8 ) + read();
break;

default:

throw expect("string", code);

}

}

_chunkLength--;

return parseUTF8Char();

}

(3) 测试代码:
public static void main(String[] args) throws IOException {

test(1024 * 32); // OK

test(1024 * 32 + 1); // OK

test(1024 * 32 + 31); // OK

test(1024 * 32 + 32); // ERROR

test(1024 * 32 + 512); // ERROR

test(1024 * 32 + 1023); // ERROR

test(1024 * 33); // OK

}

public static void test(int size) throws IOException {

SerializerFactory reponseSerializerFactory = new SerializerFactory();

StringBuilder buf = new StringBuilder();

for (int i = 0; i < size; i ++) {

buf.append('A');

}

String str = buf.toString();

System.out.println("length: " + str.getBytes().length);

ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(2048);

Hessian2Output hessianOutput = new Hessian2Output(byteBuffer);

hessianOutput.setSerializerFactory(reponseSerializerFactory);

hessianOutput.writeObject(str);

hessianOutput.flush();

byte[] bytes = byteBuffer.toByteArray();

ByteArrayInputStream input = new ByteArrayInputStream(bytes);

Hessian2Input hessianInput = new Hessian2Input(input);

hessianInput.setSerializerFactory(reponseSerializerFactory);

String result = (String)hessianInput.readObject(String.class);

System.out.println("result: " + result);

}
分享到:
评论

相关推荐

    hessian学习基础篇——序列化和反序列化

    这对于优化自定义序列化逻辑或者解决Hessian使用中遇到的问题非常有帮助。 总结起来,Hessian是一种高效、轻量级的二进制序列化协议,特别适合于跨语言的网络通信。理解并掌握Hessian的基本概念和使用方法,能够...

    Hessian 的字段序列化小记

    在序列化过程中,Hessian会将Java对象转换为字节流,反序列化时则将字节流恢复为原始对象。 1. **Hessian序列化流程** - 首先,Hessian序列化器会遍历Java对象的所有字段,对每个字段进行处理。 - 对于基本类型,...

    S25-hessian反序列化1

    在使用Hessian时,需要注意其安全问题,因为不正确的序列化处理可能导致潜在的安全风险,例如远程代码执行(RCE)漏洞。因此,在实际开发中,应确保了解并正确使用Hessian,以防止潜在的安全隐患。

    Hessian-3.2.1.jar和源码

    Hessian是一个轻量级的remotingonhttp工具,使用简单的方法提供了RMI的功能。相比Webservice,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合发送二进制数据。

    Hessian多个版本打包下载

    这包括设置服务器端和客户端的Hessian服务,定义服务接口,处理序列化和反序列化的过程,以及调试可能出现的问题。在进行版本升级时,要注意兼容性问题,确保旧版本的服务仍能正常工作,同时充分利用新版本带来的...

    hessian序列化规范

    2. **兼容性问题**:不同版本的Hessian库可能存在兼容性问题,升级时需要谨慎。 3. **安全性**:由于Hessian的数据是二进制的,若未进行加密处理,可能会增加安全风险。 六、实际应用与优化 在实际项目中,开发者...

    hessian-lite-3.2.1-fixed-2.jar

    com.alibaba:hessian-lite:jar:3.2.1-fixed-2 hessian-lite hessian-lite-3.2.1-fixed-2.jar

    Hessian 2.0序列化协议规范.docx

    这些序列化规则使得Hessian 2.0在处理各种数据类型时既高效又灵活。此外,Hessian 2.0还支持其他数据类型,如字符串、null值、数组和映射等,它们同样遵循类似的压缩和优化原则。 总结,Hessian 2.0序列化协议规范...

    Nacos JRaft Hessian 反序列化 RCE 分析.pdf

    这一安全问题的核心在于 Nacos JRaft 在处理来自客户端的特定构造的数据时未能正确地验证或过滤这些数据,从而允许攻击者通过发送恶意构造的 Hessian 数据包来触发反序列化操作,进而执行任意代码。 #### 三、漏洞...

    浅谈Java序列化和hessian序列化的差异

    Java序列化和Hessian序列化是两种常用的序列化机制,它们都可以将对象转换为字节流,以便在网络上传输。但是,两者之间有着很大的差异,今天我们就来比较一下它们的实现机制和特点。 Java序列化 Java序列化是Java...

    removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)

    removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)

    Spring中集成Hessian的问题

    在Spring框架中集成Hessian是为了实现远程方法调用(Remote Method Invocation, RMI),这是一种轻量级的序列化协议,可以高效地传输Java对象。Hessian使得服务提供者和服务消费者之间能够通过网络进行快速的数据...

    hessian-lite

    1. **远程调用**:在Dubbo框架中,Hessian-lite用于实现服务调用的二进制序列化和反序列化,使得远程方法调用(RMI)更加高效。它将Java对象转换为二进制流,通过网络发送,然后在服务端反序列化回原来的对象,降低了...

    Hessian

    2. **简单类型支持**:Hessian支持基本的Java数据类型,如整型、浮点型、字符串、日期等,并且可以序列化和反序列化复杂对象。 3. **流式传输**:Hessian协议允许数据分块传输,这意味着服务端可以立即响应部分结果...

    Hessian应用

    Hessian协议定义了一套规则,用于表示各种数据类型,包括基本类型、字符串、日期、集合和自定义对象。这样,客户端通过网络发送一个Hessian序列化的请求,服务端接收后反序列化为本地对象,然后执行相应的操作,再...

    hessian

    在这个过程中,开发者需要注意的是,虽然Hessian协议提供了自动类型映射,但有时仍需自定义序列化和反序列化的逻辑,特别是在处理自定义对象或者特殊数据结构时。 在实际应用中,Hessian常用于构建轻量级的分布式...

    Hessian案列代码

    Hessian的目标是提供一个轻量级、高效的序列化和通信机制,使得对象能够在网络间透明地进行传输。在这个案例代码中,我们将探讨Hessian如何工作以及如何在实际项目中应用。 首先,Hessian协议的特点在于它的二进制...

    Hessian 学习 例子 实例

    在IT行业中,Hessian是一种二进制序列化协议,它被广泛用于远程方法调用(RMI)和Web服务中,以提高数据传输效率。Hessian由Caucho Technology开发,其目标是提供轻量级、高效的通信方式,特别是在网络带宽有限的...

Global site tag (gtag.js) - Google Analytics