浅谈Golang中Json反序列化的一些 “坑” !_golang反序列化漏洞_Larouzey的博客-程序员宅基地

技术标签: Golang  Go  Jason反序列化  

菜鸟程序猿学习Go语言时遇到的一些坑
???

1、反序列化结构体 的“字段/属性”要求要与 序列化时结构体 的“字段/属性”必须保持一致。

简单的来说就是序列化定义的结构体,在反序列化的时候,结构体 标识符 可以不一样(可以理解为结构体的名字),但是结构体的内部 字段/属性 要一致
举个例子:
结构体序列化之前

type Hero struct {
	Name string `json:"hero_name"` //反射,Go中通过 对命名的首字母大写来确认公有
	Age int
	Skill string
} 

func main() {
	hero := Hero {
			Name :"SuperMan ~",
			Age : 1 ,
			Skill : "镭射眼",
		}

		//将Hero 序列化
		data, err := json.Marshal(&hero) //序列化函数
		if err != nil {
			fmt.Printf("序列号错误 err=%v\n", err)
		}
		//输出序列化后的结果
		fmt.Printf("Hero序列化后=%v\n", string(data))
	}

结果为:

终端显示 : {"Name":"SuperMan ~","Age" : 1 ,"Skill" : "镭射眼"}

结构体反序列化:

type ParallelUniverseHero struct {
	Name string
	Age int
	Skill string
} 
str := "{\"Name\":\"SuperMan ~\",\"Age\":1,\"Skill\":\"镭射眼\"}" //系统读取的字符串可以不用加“\”转译,手动输入的需要转译

	//定义一个Monster实例
	var PUhero Monster

	err := json.Unmarshal([]byte(str), &PUhero) //反序列化函数
	if err != nil {
		fmt.Printf("unmarshal err=%v\n", err)
	}
	fmt.Printf("反序列化后 PUhero=%\n", PUhero)

结果为:

终端显示 : {"Name":"SuperMan ~","Age" : 1 ,"Skill" : "镭射眼"}
(比较懒就不截图了 =v= !)

从两段代码中可以看到结构体的标识符(名字),并不一样,但是仍然可以正常的获取输出。但是如果结构体的字段个数或内容不一致,就会出现异常结果,或为初始定义时的空内容或0或false。(这里不会报错!而且还可以执行通过,编辑器检查不出来,很坑!很有可能出现字段内容为空的问题。会正常显示内容,但是内容是错误的)

2、反序列化Map或Slice的类型要求要与 序列化时Map或Slice的类型必须保持一致。

对于Map和Slice的反序列化,对类型上有严格的要求。下面我拿map举例,Slice是类似的。
代码:

序列化Map

func testmap() string {
	//定义一个map
	var batman map[string]interface{}  //使用map时,需要先 make 在内存中开辟空间
	batman = make(map[string]interface{})
	batman["name"] = "BatMan"
	batman["age"] = 30
	batman["skill"] = "有钱!"

	//将 batman 这个map进行序列化
	data, err := json.Marshal(batman)
	if err != nil {
		fmt.Printf("序列化错误 err=%v\n", err)
	}
	//输出序列化后的结果
	//fmt.Printf("batman 序列化后=%v\n", string(data))
}

得到的结果是:

控制台输出:batman 序列化后=map[skill:有钱! age:30 name:BatMan

反序列化Map:

	str := testmap() //这里直接使用map的序列化中的Json字符串
	
	//定义一个map
	var a map[string]interface{}

	//反序列化
	//注意:反序列化map,不需要make,因为make操作被封装到 Unmarshal函数
	err := json.Unmarshal([]byte(str), &a)
	if err != nil {
		fmt.Printf("unmarshal err=%v\n", err)
	}
	fmt.Printf("反序列化 batman的类型:%T", a)
	fmt.Printf("反序列化后 batman=%v\n", a)

结果是:

控制台输出 batman 反序列化后=map[skill:有钱! age:30 name:BatMan]

如果map的类型不一样的话

	str := "{\"skill\":\"有钱!\",\"age\":30,\"name\":\"BatMan\"}"
	
	//定义一个map,这里类型为[byte],而不是之前的[string]
	var a map[byte]interface{}

	err := json.Unmarshal([]byte(str), &a)
	if err != nil {
		fmt.Printf("unmarshal err=%v\n", err)
	}
	fmt.Printf("反序列化 batman的类型:%T", a)
	fmt.Printf("反序列化后 batman=%v\n", a)

结果就会出现:

unmarshal err=json: cannot unmarshal number skill into Go value of type uint8
反序列化 batman的类型:map[uint8]interface {}
反序列化后 batman=map[]

Slice报出的提示语和Map相同提示如下:
unmarshal err=json: cannot unmarshal number age into Go value of type uint8
反序列化后 slice=[map[] map[] map[] map[] map[]]

但仍然不会报错!!!可以执行通过!!!不过相比于结构体起码有个提示语。

未完待续…以后会陆续更新~~~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Larouzey/article/details/100993697

智能推荐

Nginx隐藏主机信息,proxy_hide_header 与fastcgi_hide_header-程序员宅基地

proxy_hide_header 与fastcgi_hide_header qunyingliunginx中proxy_hide_header 与fastcgi_hide_header都可以隐藏主机头信息,两者在具体使用时还是有着一定的区别的。刚好业..._fastcgi_hide_header

[转]DBUS-GLIB Binding,GLIB事件与DBUS事件是如何关联的-程序员宅基地

DBus有两种API接口,一种是直接使用DBUS的 low-level API,一种是使用Binding,Bindings有不同的类型,有PERL Binding、PYTHON Binding、GLIB Binding等。这里主要关注使用GLIB binding。和low-level API不同的是,GLIB binding则能够完成GLIB OBJECT的本地事件(native signal...

MongoDB集群运维笔记_mongo 复制集如何删除集群配置信息_暗涧幽火的博客-程序员宅基地

前面的文章介绍了MongoDB副本集和分片集群的做法,下面对MongoDB集群的日常维护操作进行小总结: MongDB副本集故障转移功能得益于它的选举机制。选举机制采用了Bully算法,可以很方便从分布式节点中选出主节点。Bully算法是一种协调者(主节点)竞选算法,主要思想是集群的每个成员都可以声明它是主节点并通知其他节点。别的节点可以选择接受这个声称或是拒绝并进入主节点竞争。被其他所有节点接受的节点才能成为主节点。节点按照一些属性来判断谁应该胜出。这个属性可以是一个静态ID,也可以是更..._mongo 复制集如何删除集群配置信息

Linux shell命令笔记 (一) 基本命令和远程控制工具_shell shell远程控制-程序员宅基地

查看文件树形结构yum install tree -y #全自动选ytree #树形结构去查看文件ifconfig -a #查询服务器的IPLinux 只有目录,没有文件夹连接服务器的工具1.putty(免费)推荐官网下载输入IP 端口号即可输入用户名密码进行登录2.Xshell(收费) 推荐使用个人版新建会话拥有Xftp用于文件传输..._shell shell远程控制

SAP 提示‘用户XXXX已经处理XXXX‘ 解决方法_sap订单未锁定已由处理_IamRunjiang的博客-程序员宅基地

用户操作出现报错如下如果有类似的报错的话,诸如物料XXXX的工厂数据被用户XXXX锁定可以通过SM12进入如下界面将锁定的条目,选中删除即可删除后重新操作即可成功_sap订单未锁定已由处理

随便推点

谈谈你对集成学习的见解与认识,描述一下它们的优势所在?_学生和老师正在经历的技术集成语言学习的优势是什么?你将如何解决这些问题?-程序员宅基地

【每日一问】谈谈你对集成学习的见解与认识,描述一下它们的优势所在?Datawhale优秀回答者:HipHopMan集成方法有很多种,一种叫做bagging,bagging的思想是,我把我的数据做一点微小的调整,就得到了一个跟原来不一样的数据集,我就能多训练一个模型出来,模型的数量多了,解释力自然就增强了。比如说我原来有100个人的数据,其中有两个分别叫Tony和Lily,我把Tony这条数据删..._学生和老师正在经历的技术集成语言学习的优势是什么?你将如何解决这些问题?

【C语言】学生考勤管理系统_c语言考勤管理系统_小园园子的博客-程序员宅基地

实现一个简单、实用的学生考勤系统程序,主要功能包括考勤数据的输入、输出、删除、修改、查询、添加、排序、数据统计等。通过此课题,熟练掌握文件、数组、指针的各种操作,以及一些基本算法的应用。_c语言考勤管理系统

c++模板特化和偏特化_枚举 偏特化-程序员宅基地

一:模板特化 1.函数模板特化 2.类模板特化二:模板偏特化 主要是类模板的偏特化,函数模板的偏特化没必要,因为可以通过重载来完成。 1.类模板的偏特化 2.函数模板的重载..._枚举 偏特化

MFC使用Windows API实现U盘插拔检测,获取U盘容量,U盘内容移动删除,开启和关闭U盘以及获取盘符_winapi如何判断u盘在忙碌中-程序员宅基地

文章目录前言一、利用OS API实现对U盘的管理二、实例代码1.实时判断U盘插入与拔出2.能够显示U盘的总容量、使用容量和剩余容量3.能够将某个目录上的文件或整个目录复制到U盘上4. 删除U盘上文件5.禁止U盘的使用及开启U盘的使用6.尝试读取PCB信息2.项目到底长啥样3.总结前言MFC实现对U盘的管理并用图形化界面展示出来。一、利用OS API实现对U盘的管理能够判断U盘是否存在能够显示U盘的总容量、使用容量和剩余容量;能够将某个目录上的文件或整个目录复制到U盘上;可以删除U盘上文_winapi如何判断u盘在忙碌中

Mysql当前列的值等于上一行的值累加前一列的值-程序员宅基地

前言:公司项目需要做数据可视化,统计一些数据,比如用户增长量,按每天分组,还要计算每天累加的用户量,一开始也是想了很久,不知道怎么做,后面 百度的,找打了一个解决办法。定义一个变量,然后进行两个值的相加:-- 用户数据+按日期+每天累计人数 SELECT reg_time, total1 as '每天增加用户数', @total := @total + t...

C#WinForm实现雷速网站逆向_c# 逆向_奥特曼洗澡中的博客-程序员宅基地

目录前言一、查找绘制前的关键代码二、解剖数据加密过程三、通过 C# WinForm 进行获取调用总结前言提示:本文仅用于学习分享,禁止用于任何违法行为,如有侵权,请联系删除。目标网址:足球赛果_足球联赛赛果_足球比赛赛果-雷速体育雷速体育足球赛果提供最新最全的欧洲杯、世界杯、五大联赛、中超等国内国际大小足球比赛的赛事结果,看足球赛果首选雷速体育!https://live.leisu.com/wanchang从上图中可以看到,页面中显示的数据变成了Canvas标签..._c# 逆向