Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Libpng
提交
9d51afca
T
Third Party Libpng
项目概览
OpenHarmony
/
Third Party Libpng
12 个月 前同步成功
通知
4
Star
22
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Libpng
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9d51afca
编写于
2月 12, 2010
作者:
G
Glenn Randers-Pehrson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[devel] Complete rewrite of png_decompress_chunk() by John Bowler
上级
389c1f20
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
143 addition
and
356 deletion
+143
-356
pngpriv.h
pngpriv.h
+1
-3
pngrutil.c
pngrutil.c
+142
-353
未找到文件。
pngpriv.h
浏览文件 @
9d51afca
/* pngpriv.h - private declarations for use inside libpng
*
* libpng version 1.
5.0beta05 - February 9
, 2010
* libpng version 1.
4.1beta11 - February 13
, 2010
* For conditions of distribution and use, see copyright notice in png.h
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
...
...
@@ -306,8 +306,6 @@ PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
/* Decompress data in a chunk that uses compression */
#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
PNG_EXTERN
png_size_t
png_measure_decompressed_chunk
PNGARG
((
png_structp
png_ptr
,
int
comp_type
,
png_size_t
chunklength
,
png_size_t
prefix_length
));
PNG_EXTERN
void
png_decompress_chunk
PNGARG
((
png_structp
png_ptr
,
int
comp_type
,
png_size_t
chunklength
,
png_size_t
prefix_length
,
png_size_t
*
data_length
));
...
...
pngrutil.c
浏览文件 @
9d51afca
/* pngrutil.c - utilities to read a PNG file
*
* Last changed in libpng 1.4.1 [February 1
2
, 2010]
* Last changed in libpng 1.4.1 [February 1
3
, 2010]
* Copyright (c) 1998-2010 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
...
...
@@ -201,72 +201,93 @@ png_crc_error(png_structp png_ptr)
#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
defined(PNG_READ_iCCP_SUPPORTED)
png_size_t
png_
measure_decompressed_chunk
(
png_structp
png_ptr
,
int
comp_typ
e
,
png_size_t
chunklength
,
png_size_t
prefix
_size
)
static
png_size_t
png_
inflate
(
png_structp
png_ptr
,
const
png_byte
*
data
,
png_size_t
siz
e
,
png_bytep
output
,
png_size_t
output
_size
)
{
png_charp
text
;
png_charp
test
=
"X"
;
png_size_t
text_size
=
0
;
png_size_t
count
=
0
;
png_ptr
->
zstream
.
next_in
=
(
png_bytep
)
data
;
/* const_cast: VALID */
png_ptr
->
zstream
.
avail_in
=
size
;
if
(
comp_type
==
PNG_COMPRESSION_TYPE_BASE
)
while
(
1
)
{
int
ret
=
Z_OK
;
int
ret
,
avail
;
png_ptr
->
zstream
.
next_in
=
(
png_bytep
)(
png_ptr
->
chunkdata
+
prefix_size
);
png_ptr
->
zstream
.
avail_in
=
(
uInt
)(
chunklength
-
prefix_size
);
/* Reset the output buffer each time round - we empty it
* after every inflate call.
*/
png_ptr
->
zstream
.
next_out
=
png_ptr
->
zbuf
;
png_ptr
->
zstream
.
avail_out
=
(
uInt
)
png_ptr
->
zbuf_size
;
png_ptr
->
zstream
.
avail_out
=
png_ptr
->
zbuf_size
;
text
=
NULL
;
ret
=
inflate
(
&
png_ptr
->
zstream
,
Z_NO_FLUSH
);
avail
=
png_ptr
->
zbuf_size
-
png_ptr
->
zstream
.
avail_out
;
while
(
png_ptr
->
zstream
.
avail_in
)
/* First copy/count any new output - but only if we didn't
* get an error code.
*/
if
((
ret
==
Z_OK
||
ret
==
Z_STREAM_END
)
&&
avail
>
0
)
{
ret
=
inflate
(
&
png_ptr
->
zstream
,
Z_PARTIAL_FLUSH
);
if
(
ret
!=
Z_OK
&&
ret
!=
Z_STREAM_END
)
break
;
if
(
output
!=
0
&&
output_size
>
count
)
{
int
copy
=
output_size
-
count
;
if
(
avail
<
copy
)
copy
=
avail
;
png_memcpy
(
output
+
count
,
png_ptr
->
zbuf
,
copy
);
}
count
+=
avail
;
}
if
(
!
png_ptr
->
zstream
.
avail_out
||
ret
==
Z_STREAM_END
)
{
if
(
text
==
NULL
)
/* Initialize the decompression buffer */
{
text_size
=
prefix_size
+
png_ptr
->
zbuf_size
-
png_ptr
->
zstream
.
avail_out
;
if
(
ret
==
Z_OK
)
continue
;
text
=
test
;
}
else
/* Enlarge the decompression buffer */
{
text_size
+=
png_ptr
->
zbuf_size
-
png_ptr
->
zstream
.
avail_out
;
#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
if
(
png_ptr
->
user_chunk_malloc_max
&&
(
text_size
>=
png_ptr
->
user_chunk_malloc_max
-
1
))
/* Termination conditions - always reset the zstream, it
* must be left in inflateInit state.
*/
png_ptr
->
zstream
.
avail_in
=
0
;
inflateReset
(
&
png_ptr
->
zstream
);
if
(
ret
==
Z_STREAM_END
)
return
count
;
/* NOTE: may be zero. */
/* Now handle the error codes - the API always returns 0
* and the error message is dumped into the uncompressed
* buffer if available.
*/
{
char
*
msg
,
umsg
[
52
];
if
(
png_ptr
->
zstream
.
msg
!=
0
)
msg
=
png_ptr
->
zstream
.
msg
;
else
{
#ifdef PNG_STDIO_SUPPORTED
switch
(
ret
)
{
case
Z_BUF_ERROR
:
msg
=
"Buffer error in compressed datastream in %s chunk"
;
break
;
case
Z_DATA_ERROR
:
msg
=
"Data error in compressed datastream in %s chunk"
;
break
;
default:
msg
=
"Incomplete compressed datastream in %s chunk"
;
break
;
}
png_snprintf
(
umsg
,
sizeof
umsg
,
msg
,
png_ptr
->
chunk_name
);
msg
=
umsg
;
#else
if
((
PNG_USER_CHUNK_MALLOC_MAX
>
0
)
&&
text_size
>=
PNG_USER_CHUNK_MALLOC_MAX
-
1
)
msg
=
"Damaged compressed datastream in chunk other than IDAT"
;
#endif
{
png_warning
(
png_ptr
,
"Exceeded malloc limit while expanding chunk"
);
text_size
=
0
;
break
;
}
}
}
if
(
ret
==
Z_STREAM_END
)
break
;
}
else
{
png_ptr
->
zstream
.
next_out
=
png_ptr
->
zbuf
;
png_ptr
->
zstream
.
avail_out
=
(
uInt
)
png_ptr
->
zbuf_size
;
}
png_warning
(
png_ptr
,
msg
);
}
inflateReset
(
&
png_ptr
->
zstream
);
png_ptr
->
zstream
.
avail_in
=
0
;
/* 0 means an error - notice that this code simple ignores
* zero length compressed chunks as a result.
*/
return
0
;
}
return
text_size
;
}
/*
...
...
@@ -281,338 +302,106 @@ png_decompress_chunk(png_structp png_ptr, int comp_type,
png_size_t
chunklength
,
png_size_t
prefix_size
,
png_size_t
*
newlength
)
{
static
PNG_CONST
char
msg
[]
=
"Error decoding compressed chunk"
;
png_charp
text
;
png_size_t
text_size
;
png_size_t
expanded_size
;
expanded_size
=
png_measure_decompressed_chunk
(
png_ptr
,
comp_type
,
chunklength
,
prefix_size
);
if
(
expanded_size
==
0
)
/* The caller should guarantee this */
if
(
prefix_size
>
chunklength
)
{
*
newlength
=
0
;
return
;
/* The recovery is to delete the chunk. */
png_warning
(
png_ptr
,
"invalid chunklength"
);
prefix_size
=
0
;
/* To delete everything */
}
if
(
comp_type
==
PNG_COMPRESSION_TYPE_BASE
)
else
if
(
comp_type
==
PNG_COMPRESSION_TYPE_BASE
)
{
int
ret
=
Z_OK
;
png_ptr
->
zstream
.
next_in
=
(
png_bytep
)(
png_ptr
->
chunkdata
+
prefix_size
);
png_ptr
->
zstream
.
avail_in
=
(
uInt
)(
chunklength
-
prefix_size
);
png_ptr
->
zstream
.
next_out
=
png_ptr
->
zbuf
;
png_ptr
->
zstream
.
avail_out
=
(
uInt
)
png_ptr
->
zbuf_size
;
text_size
=
0
;
text
=
NULL
;
while
(
png_ptr
->
zstream
.
avail_in
)
{
ret
=
inflate
(
&
png_ptr
->
zstream
,
Z_PARTIAL_FLUSH
);
if
(
ret
!=
Z_OK
&&
ret
!=
Z_STREAM_END
)
{
if
(
png_ptr
->
zstream
.
msg
!=
NULL
)
png_warning
(
png_ptr
,
png_ptr
->
zstream
.
msg
);
else
png_warning
(
png_ptr
,
msg
);
inflateReset
(
&
png_ptr
->
zstream
);
png_ptr
->
zstream
.
avail_in
=
0
;
png_size_t
expanded_size
=
png_inflate
(
png_ptr
,
png_ptr
->
chunkdata
+
prefix_size
,
chunklength
-
prefix_size
,
0
/*output*/
,
0
/*output size*/
);
if
(
text
==
NULL
)
{
text_size
=
prefix_size
+
png_sizeof
(
msg
)
+
1
;
text
=
(
png_charp
)
png_malloc_warn
(
png_ptr
,
text_size
);
if
(
text
==
NULL
)
{
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
NULL
;
png_error
(
png_ptr
,
"Not enough memory to decompress chunk"
);
}
png_memcpy
(
text
,
png_ptr
->
chunkdata
,
prefix_size
);
}
text
[
text_size
-
1
]
=
0x00
;
/* Copy what we can of the error message into the text chunk */
text_size
=
(
png_size_t
)(
chunklength
-
(
text
-
png_ptr
->
chunkdata
)
-
1
);
if
(
text_size
>
png_sizeof
(
msg
))
text_size
=
png_sizeof
(
msg
);
png_memcpy
(
text
+
prefix_size
,
msg
,
text_size
);
break
;
}
if
(
!
png_ptr
->
zstream
.
avail_out
||
ret
==
Z_STREAM_END
)
{
if
(
text
==
NULL
)
{
text_size
=
prefix_size
+
png_ptr
->
zbuf_size
-
png_ptr
->
zstream
.
avail_out
;
text
=
(
png_charp
)
png_malloc_warn
(
png_ptr
,
text_size
+
1
);
if
(
text
==
NULL
)
{
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
NULL
;
png_error
(
png_ptr
,
"Not enough memory to decompress chunk"
);
}
png_memcpy
(
text
+
prefix_size
,
png_ptr
->
zbuf
,
text_size
-
prefix_size
);
png_memcpy
(
text
,
png_ptr
->
chunkdata
,
prefix_size
);
*
(
text
+
text_size
)
=
0x00
;
}
else
{
png_charp
tmp
;
/* Now check the limits on this chunk - if the limit fails the
* compressed data will be removed, the prefix will remain.
*/
#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
if
(
png_ptr
->
user_chunk_malloc_max
&&
(
prefix_size
+
expanded_size
>=
png_ptr
->
user_chunk_malloc_max
-
1
))
#else
if
((
PNG_USER_CHUNK_MALLOC_MAX
>
0
)
&&
prefix_size
+
expanded_size
>=
PNG_USER_CHUNK_MALLOC_MAX
-
1
)
#endif
png_warning
(
png_ptr
,
"Exceeded size limit while expanding chunk"
);
tmp
=
text
;
text
=
(
png_charp
)
png_malloc_warn
(
png_ptr
,
(
png_size_t
)(
text_size
+
png_ptr
->
zbuf_size
-
png_ptr
->
zstream
.
avail_out
+
1
));
if
(
text
==
NULL
)
{
png_free
(
png_ptr
,
tmp
);
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
NULL
;
png_error
(
png_ptr
,
"Not enough memory to decompress chunk"
);
}
png_memcpy
(
text
,
tmp
,
text_size
);
png_free
(
png_ptr
,
tmp
);
png_memcpy
(
text
+
text_size
,
png_ptr
->
zbuf
,
(
png_ptr
->
zbuf_size
-
png_ptr
->
zstream
.
avail_out
));
text_size
+=
png_ptr
->
zbuf_size
-
png_ptr
->
zstream
.
avail_out
;
*
(
text
+
text_size
)
=
0x00
;
}
if
(
ret
==
Z_STREAM_END
)
break
;
else
{
png_ptr
->
zstream
.
next_out
=
png_ptr
->
zbuf
;
png_ptr
->
zstream
.
avail_out
=
(
uInt
)
png_ptr
->
zbuf_size
;
}
}
}
if
(
ret
!=
Z_STREAM_END
)
/* If the size is zero either there was an error and a message
* has already been output (warning) or the size really is zero
* and we have nothing to do - the code will exit through the
* error case below.
*/
else
if
(
expanded_size
>
0
)
{
#ifdef PNG_STDIO_SUPPORTED
char
umsg
[
52
];
if
(
ret
==
Z_BUF_ERROR
)
png_snprintf
(
umsg
,
52
,
"Buffer error in compressed datastream in %s chunk"
,
png_ptr
->
chunk_name
);
else
if
(
ret
==
Z_DATA_ERROR
)
png_snprintf
(
umsg
,
52
,
"Data error in compressed datastream in %s chunk"
,
png_ptr
->
chunk_name
);
else
png_snprintf
(
umsg
,
52
,
"Incomplete compressed datastream in %s chunk"
,
png_ptr
->
chunk_name
);
/* Success (maybe) - really uncompress the chunk. */
png_size_t
new_size
=
0
;
png_charp
text
=
png_malloc_warn
(
png_ptr
,
prefix_size
+
expanded_size
+
1
);
png_warning
(
png_ptr
,
umsg
);
#else
png_warning
(
png_ptr
,
"Incomplete compressed datastream in chunk other than IDAT"
);
#endif
text_size
=
prefix_size
;
if
(
text
==
NULL
)
if
(
text
!=
NULL
)
{
text
=
(
png_charp
)
png_malloc_warn
(
png_ptr
,
text_size
+
1
);
if
(
text
==
NULL
)
{
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
NULL
;
png_error
(
png_ptr
,
"Not enough memory for text"
);
}
png_memcpy
(
text
,
png_ptr
->
chunkdata
,
prefix_size
);
}
*
(
text
+
text_size
)
=
0x00
;
png_memcpy
(
text
,
png_ptr
->
chunkdata
,
prefix_size
);
new_size
=
png_inflate
(
png_ptr
,
png_ptr
->
chunkdata
+
prefix_size
,
chunklength
-
prefix_size
,
text
+
prefix_size
,
expanded_size
);
text
[
prefix_size
+
expanded_size
]
=
0
;
/* just in case */
if
(
new_size
==
expanded_size
)
{
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
text
;
*
newlength
=
prefix_size
+
expanded_size
;
return
;
/* The success return! */
}
png_warning
(
png_ptr
,
"png_inflate logic error"
);
png_free
(
png_ptr
,
text
);
}
else
png_warning
(
png_ptr
,
"Not enough memory to decompress chunk"
);
}
inflateReset
(
&
png_ptr
->
zstream
);
png_ptr
->
zstream
.
avail_in
=
0
;
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
text
;
*
newlength
=
text_size
;
}
else
/* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
{
#ifdef PNG_STDIO_SUPPORTED
char
umsg
[
50
];
png_snprintf
(
umsg
,
50
,
"Unknown zTXt compression type %d"
,
comp_type
);
#ifdef PNG_STDIO_SUPPORTED
png_snprintf
(
umsg
,
sizeof
umsg
,
"Unknown zTXt compression type %d"
,
comp_type
);
png_warning
(
png_ptr
,
umsg
);
#else
png_warning
(
png_ptr
,
"Unknown zTXt compression type"
);
#endif
*
(
png_ptr
->
chunkdata
+
prefix_size
)
=
0x00
;
*
newlength
=
prefix_size
;
/* The recovery is to simply drop the data. */
}
}
#if 0 /* doesn't work */
{
static PNG_CONST char msg[] = "Error decoding compressed chunk";
png_charp text;
png_size_t text_size;
png_size_t expanded_size;
expanded_size = png_measure_decompressed_chunk(png_ptr, comp_type,
chunklength, prefix_size);
if (expanded_size == 0)
{
*newlength=0;
return;
}
if (comp_type == PNG_COMPRESSION_TYPE_BASE)
/* Generic error return - leave the prefix, delete the compressed
* data, reallocate the chunkdata to remove the potentially large
* amount of compressed data.
*/
{
int ret = Z_OK;
png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size);
png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
text_size = 0;
text = NULL;
while (png_ptr->zstream.avail_in)
png_charp
text
=
png_malloc_warn
(
png_ptr
,
prefix_size
+
1
);
if
(
text
!=
NULL
)
{
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
{
if (png_ptr->zstream.msg != NULL)
png_warning(png_ptr, png_ptr->zstream.msg);
else
png_warning(png_ptr, msg);
inflateReset(&png_ptr->zstream);
png_ptr->zstream.avail_in = 0;
if (text == NULL)
{
text_size = prefix_size + png_sizeof(msg) + 1;
text = (png_charp)png_malloc_warn(png_ptr, text_size);
if (text == NULL)
{
png_error(png_ptr,
"Not enough memory to decompress chunk");
text_size = 0;
break;
}
png_memcpy(text, png_ptr->chunkdata, prefix_size);
}
text[text_size - 1] = 0x00;
/* Copy what we can of the error message into the text chunk */
text_size = (png_size_t)(chunklength -
(text - png_ptr->chunkdata) - 1);
if (text_size > png_sizeof(msg))
text_size = png_sizeof(msg);
png_memcpy(text + prefix_size, msg, text_size);
break;
}
if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
{
if (text == NULL) /* Initialize the decompression buffer */
{
text_size = expanded_size;
text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
if (text == NULL)
{
png_error(png_ptr,
"Not enough memory to decompress chunk");
text_size = 0;
break;
}
png_memcpy(text + prefix_size, png_ptr->zbuf,
text_size - prefix_size);
png_memcpy(text, png_ptr->chunkdata, prefix_size);
*(text + text_size) = 0x00;
}
if (ret == Z_STREAM_END)
break;
else
{
png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
}
}
}
if (ret != Z_STREAM_END)
{
#ifdef PNG_STDIO_SUPPORTED
char umsg[52];
if (ret == Z_BUF_ERROR)
png_snprintf(umsg, 52,
"Buffer error in compressed datastream in %s chunk",
png_ptr->chunk_name);
else if (ret == Z_DATA_ERROR)
png_snprintf(umsg, 52,
"Data error in compressed datastream in %s chunk",
png_ptr->chunk_name);
else
png_snprintf(umsg, 52,
"Incomplete compressed datastream in %s chunk",
png_ptr->chunk_name);
png_warning(png_ptr, umsg);
#else
png_warning(png_ptr,
"Incomplete compressed datastream in chunk other than IDAT");
#endif
text_size
=
prefix_size
;
if
(
text
==
NULL
)
{
text
=
(
png_charp
)
png_malloc_warn
(
png_ptr
,
text_size
+
1
);
if
(
text
==
NULL
)
{
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
NULL
;
png_error
(
png_ptr
,
"Not enough memory for text"
);
}
if
(
prefix_size
>
0
)
png_memcpy
(
text
,
png_ptr
->
chunkdata
,
prefix_size
);
}
*
(
text
+
text_size
)
=
0x00
;
}
inflateReset
(
&
png_ptr
->
zstream
);
png_ptr
->
zstream
.
avail_in
=
0
;
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
text
;
png_free
(
png_ptr
,
png_ptr
->
chunkdata
);
png_ptr
->
chunkdata
=
text
;
*
newlength
=
text_size
;
/* This is an extra zero in the 'uncompressed' part. */
*
(
png_ptr
->
chunkdata
+
prefix_size
)
=
0x00
;
}
/* Ignore a malloc error here - it is safe. */
}
else
/* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
{
#ifdef PNG_STDIO_SUPPORTED
char
umsg
[
50
];
png_snprintf
(
umsg
,
50
,
"Unknown zTXt compression type %d"
,
comp_type
);
png_warning
(
png_ptr
,
umsg
);
#else
png_warning
(
png_ptr
,
"Unknown zTXt compression type"
);
#endif
*
(
png_ptr
->
chunkdata
+
prefix_size
)
=
0x00
;
*
newlength
=
prefix_size
;
}
*
newlength
=
prefix_size
;
}
#endif
#endif
/* Read and check the IDHR chunk */
void
/* PRIVATE */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录