博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jsoncpp v0.5中的一个bug
阅读量:6271 次
发布时间:2019-06-22

本文共 3446 字,大约阅读时间需要 11 分钟。

本文目的

今天在使用jsoncpp 0.5的时候很偶然的发现了一个bug,由于jsoncpp在业界被广泛使用,所以有必要将这个bug指出。

 

一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/*
 
* bug_demo.cpp
 
*
 
*  Created on: 2011-11-22
 
*      Author: bourneli
 
*/
#include "json/json.h"
#include <iostream>
#include <fstream>
 
using 
namespace 
std;
 
int 
main()
{
    
Json::Value oRootVal;
 
    
Json::Reader oJsonReader;
    
oJsonReader.parse(
"{\"aInt\" : 3}"
, oRootVal);
 
    
Json::Value oInt = oRootVal[
"aInt"
];
    
cout <<
"aInt : " 
<< oInt.asInt() << endl;
    
if 
(oInt.isConvertibleTo(Json::stringValue))
    
{
        
cout <<
"aInt as string : " 
<< oInt.asString() << endl;
    
}
    
else
    
{
        
cout <<
"aInt cannot convert to a string" 
<< endl;
    
}
    
return 
0;
}

根据上面的代码,如果使用过jsoncpp,应该可以预测输出,如下:

aInt : 3

aInt as string : 3

但是,实际上却是:

抛异常了 囧~~~

 

原因分析

Json::Value::isConvertibleTo函数,从字面意思上看,就是判断当前value是否可以转成目标类型,我们看看Json::Value::isConvertibleTo的源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
bool
Value::isConvertibleTo( ValueType other )
const
{
   
switch 
( type_ )
   
{
   
case 
nullValue:
      
return 
true
;
   
case 
intValue:
      
return 
( other == nullValue  &&  value_.int_ == 0 )
             
|| other == intValue
             
|| ( other == uintValue  && value_.int_ >= 0 )
             
|| other == realValue
             
|| other == stringValue
             
|| other == booleanValue;
   
case 
uintValue:
      
return 
( other == nullValue  &&  value_.uint_ == 0 )
             
|| ( other == intValue  && value_.uint_ <= (unsigned)maxInt )
             
|| other == uintValue
             
|| other == realValue
             
|| other == stringValue
             
|| other == booleanValue;
   
case 
realValue:
      
return 
( other == nullValue  &&  value_.real_ == 0.0 )
             
|| ( other == intValue  &&  value_.real_ >= minInt  &&  value_.real_ <= maxInt )
             
|| ( other == uintValue  &&  value_.real_ >= 0  &&  value_.real_ <= maxUInt )
             
|| other == realValue
             
|| other == stringValue
             
|| other == booleanValue;
   
case 
booleanValue:
      
return 
( other == nullValue  &&  value_.bool_ ==
false 
)
             
|| other == intValue
             
|| other == uintValue
             
|| other == realValue
             
|| other == stringValue
             
|| other == booleanValue;
   
case 
stringValue:
      
return 
other == stringValue
             
|| ( other == nullValue  &&  (!value_.string_  ||  value_.string_[0] == 0) );
   
case 
arrayValue:
      
return 
other == arrayValue
             
||  ( other == nullValue  &&  value_.map_->size() == 0 );
   
case 
objectValue:
      
return 
other == objectValue
             
||  ( other == nullValue  &&  value_.map_->size() == 0 );
   
default
:
      
JSON_ASSERT_UNREACHABLE;
   
}
   
return 
false
;
// unreachable;
}

实现很简单,就是一系列的类型转换映射。上面的代码中第13行的地方就说明,int类型的Value是可以转化成string类型的Value。

但是实际上,却抛出了异常,我们可以分析下Json::Value::AsString函数的实现,源代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
std::string
Value::asString()
const
{
   
switch 
( type_ )
   
{
   
case 
nullValue:
      
return 
""
;
   
case 
stringValue:
      
return 
value_.string_ ? value_.string_ :
""
;
   
case 
booleanValue:
      
return 
value_.bool_ ?
"true" 
:
"false"
;
   
case 
intValue:
   
case 
uintValue:
   
case 
realValue:
   
case 
arrayValue:
   
case 
objectValue:
      
JSON_ASSERT_MESSAGE(
false
,
"Type is not convertible to string" 
);
   
default
:
      
JSON_ASSERT_UNREACHABLE;
   
}
   
return 
""
;
// unreachable
}

实现也很简单,也是通过当前value的类型,判断是否可以转成string类型。第12行和第17行表明:转换映射和isConvertibleTo不一致。这就是导致bug的直接原因。

总结

此bug不是什么致命bug,并不能掩盖jsoncpp的跨平台,简单,轻量级等优点,使用的时候需要注意这里,否则会带来问题。所以,建议不要使用isConvertibleTo这个函数,而是通过手动判断当前数据类型,然后使用C++内置的类型转换,就不会出现该问题。

相关资料

下面的链接是jsoncpp在sourceforge官方网站上对该bug的描述

没有注册的同学无法浏览,这里截个图:

声明:如有转载本博文章,请注明出处。您的支持是我的动力!文章部分内容来自互联网,本人不负任何法律责任。
本文转自bourneli博客园博客,原文链接:http://www.cnblogs.com/bourneli/archive/2011/12/28/2304618.html
,如需转载请自行联系原作者
你可能感兴趣的文章
Oracle体系结构之oracle密码文件管理
查看>>
【leetcode】Remove Element (easy)
查看>>
mysql多表查询及其 group by 组内排序
查看>>
alsa的snd_pcm_readi()函数和snd_pcm_writei()
查看>>
Android学习网站推荐(转)
查看>>
嵌入式根文件系统的移植和制作详解
查看>>
MEF部件的生命周期(PartCreationPolicy)
查看>>
LCD的接口类型详解
查看>>
nginx 基础文档
查看>>
LintCode: Unique Characters
查看>>
Jackson序列化和反序列化Json数据完整示例
查看>>
.net 中的DllImport
查看>>
nyoj 517 最小公倍数 【java睑板】
查看>>
include与jsp:include区别
查看>>
ftp的20 21端口和主动被动模式
查看>>
MySQL存储引擎选型
查看>>
Java中的statickeyword具体解释
查看>>
Linux车载系统的开发方向
查看>>
并发编程之五--ThreadLocal
查看>>
摄像头驱动OV7725学习笔记连载(二):0V7725 SCCB时序的实现之寄存器配置
查看>>