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

技术标签: 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

智能推荐

《ZooKeeper:分布式过程协同技术详解》——2.5 小结_weixin_34194359的博客-程序员宝宝

本节书摘来自华章计算机《ZooKeeper:分布式过程协同技术详解》一书中的第2章,第2.5节,作者:Flavio Junqueira, Benjamin Reed 更多章节内容可以访问云栖社区“华章计算机”公众号查看。2.5 小结本章中,我们了解了许多基础的ZooKeeper概念,我们看到了ZooKeeper通过其API提供的基本功能,还探讨了其架...

详解COM Add In的LoadBehavior及其妙用_v_jzho的博客-程序员宝宝

详解COM Add In的LoadBehavior及其妙用            Office的所有COM Add In,包括用Shared Add In模板和VSTO Add In模板创建的,都会在注册表里面存储一些信息。对于当前用户安装的Add In,以Excel为例,对应的注册表键值存储于:My Computer/HKCU/Software/Microsoft/Offic

ios wkweb设置图片_iOS 详解WKWebview屏蔽广告,保存图片以及截取链接_weixin_39789690的博客-程序员宝宝

(原创)2017-6-20最近刚刚实现的功能, 分享一下经验(原谅文章没有句号, 为了开发方便我设置的中文下使用英文标点).自己做了一个比较简单浏览器, 里面有模仿UC实现长按页面屏蔽广告的功能保存网页图片和获取网页跳页的链接都是基于上面做的扩展, 这里详细讲去除广告思路:手动去除广告主要有以下几个步骤:1, 获取html上的触摸事件2, 捕获触摸事件返回的html坐标(注意, 是html上的坐标...

linux splice函数,关于splice函数未定义_weixin_40001634的博客-程序员宝宝

没有用好man的下场呵呵,找个错误一直不知所措。先看splice函数:1 SPLICE(2) Linux Programmer's Manual SPLICE(2)23 NAME4 splice - splice data to/froma pipe56 SYNOPSIS7 #define _GNU_SO...

安装最新版mysql-8.0.18(yum安装)_未语的博客-程序员宝宝

注意安装mysql-8.0.18前要先删除本机安装的mariadb检查已经安装的mariadb列表rpm -qa | grep mariadb执行上面命令后会列出本机安装的mariadb列表例如:mariadb-libs-5.5.60-1.el7_5.x86_64然后执行删除,删除分为2种1,rpm -e --nodeps 后面跟上上面得到的结果rpm -e --nodeps mariadb-libs-5.5.60-1.el7_5.x86_642,yum -y remo.

csdn 博客界面右边目录栏消失的解决办法_lgxo的博客-程序员宝宝

不小心把csdn中博客界面的右边目录栏给搞消失了,在网上搜了好长时间也没有找到解决方法,但是误打误撞又改回去了,于是写了这篇博客帮助和我一样不小心更改了博客界面的朋友。

随便推点

【每日新闻】2017年亚马逊研发投入排世界第一,超过华为、BAT 总和 | 数人云宣布与UMCloud合并..._Z1Y492Vn3ZYD9et3B06的博客-程序员宝宝

每一个企业级的人  都置顶了 中国软件网中国软件网  为你带来最新鲜的行业干货小编点评我们希望邀请更多的生态伙伴共同探讨共同行动2018年4月25日北京站,不见不散!趋势...

用gambit学博弈论--完全信息动态博弈-参与者信息集、博弈树上虚线的解释(三)_weixin_37718439的博客-程序员宝宝

参与者信息集  为了能够在博弈树上把信息集的概念体现出来,通常用虚线将属于同一信息集的所有决策结连接起来。  上图上有错误,参与者2不知道市场需求的大小。  从信息集的定义可知,一个信息集一般包含多个决策结,从上述例子中也看到信息集也可能只包含一个决策结。**只包含一个决策结的信息集称为单结信息集,到达单结信息集的参与者是完全知道其直接前列结上参与者的行动的。**如果博弈树的所有信息集都是单结的,该博弈就称为完美信息博弈,完美信息博弈意味着博弈中没有任何两个参与者同时行动,并且所有后行动者确切

如何使用 VLD 检测程序中的内存泄漏?_weixin_30339969的博客-程序员宝宝

下载地址:https://kinddragon.github.io/vld/下载 windows 安装包,进行安装即可,它会给你设置好 vs 的环境变量,使用时,直接在 vs ide 中包含即可。如何 在 Call Stack 位置无法显示文件名,和跟踪堆栈函数,则需要你更改 vld.ini 默认配置文件中的编码格式为 unicode然后它会在调试器中打印出调用堆栈,根据这个信息进行定位即可...

方差分析_root_zhb的博客-程序员宝宝

方差分析(Analysis of Variance,简称ANOVA)用于两个及两个以上样本均数差别的显著性检验。作用:确定参数对算法性能的影响基础概念:方差分析如何理解p值和F值Sum.sq.——平方和d.f. ——自由度Mean.Sq.——均方F-value——F值p-value——p值关于F值和p值每一个F值都会对应一个p值,F值越大,p值越小所以实际上F值和p值都能用来检验显著性差异p-value就是用于检验特征与变量之间相关性的假设你给出α值(常常取0.05,0.01

二分查找_aomi7565的博客-程序员宝宝

一、对有序后数组进行查找,未查找到返回 -1public static int swap(int[] t,int x){ int mid,low,high; low = 0; high = t.length-1; while(low < high){ mid = (low+high)/2; if(t[mid] > x){ high = mi...

视频教程-软考系统集成项目管理工程师视频教程(下)-软考_weixin_28882885的博客-程序员宝宝

软考系统集成项目管理工程师视频教程(下) 项目管理师、信息系统项目管理师、项...

推荐文章

热门文章

相关标签