Merge tag 'v6.2.12-lts' into tqtc/lts-6.2-opensource

Qt 6.2.12-lts release

Change-Id: Ifaa14ca9731d4b93578c10437ba27c67e5cde77f
This commit is contained in:
Tarja Sundqvist 2025-01-27 20:13:43 +02:00
commit 3a82051ead
220 changed files with 44045 additions and 27790 deletions

View File

@ -1,4 +1,4 @@
set(QT_REPO_MODULE_VERSION "6.2.11")
set(QT_REPO_MODULE_VERSION "6.2.12")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "")
# Minimum requirement for building Qt

View File

@ -6,4 +6,4 @@ DEFINES += QT_NO_JAVA_STYLE_ITERATORS
QT_SOURCE_TREE = $$PWD
QT_BUILD_TREE = $$shadowed($$PWD)
MODULE_VERSION = 6.2.11
MODULE_VERSION = 6.2.12

View File

@ -448,8 +448,8 @@ if (__qt_qml_plugins_config_file_list AND NOT QT_SKIP_AUTO_QML_PLUGIN_INCLUSION)
endif()")
endif()
get_target_property(qt_plugins "${QT_MODULE}" QT_PLUGINS)
if(qt_plugins OR QT_MODULE_PLUGIN_INCLUDES)
get_target_property(module_plugin_types "${QT_MODULE}" MODULE_PLUGIN_TYPES)
if(module_plugin_types OR QT_MODULE_PLUGIN_INCLUDES)
list(APPEND modules_with_plugins "${QT_MODULE}")
configure_file(
"${QT_CMAKE_DIR}/QtPlugins.cmake.in"

View File

@ -186,7 +186,7 @@ function(__qt_internal_walk_libs
# namespace. Which one is preferred doesn't really matter. This code exists to
# avoid ending up with both, Qt::Foo and Foo in our dependencies.
set(namespaceless_lib_target "${CMAKE_MATCH_1}")
if(TARGET namespaceless_lib_target)
if(TARGET "${namespaceless_lib_target}")
set(lib_target ${namespaceless_lib_target})
endif()
endif()

View File

@ -126,7 +126,9 @@ struct Renderable {
static struct Renderable renderables[] = {
{ "default", QSurfaceFormat::DefaultRenderableType },
#ifndef Q_OS_ANDROID
{ "OpenGL", QSurfaceFormat::OpenGL },
#endif
{ "OpenGL ES", QSurfaceFormat::OpenGLES }
};

View File

@ -61,7 +61,8 @@ set(JPEG_SOURCES
src/jerror.c
src/jfdctflt.c
src/jmemmgr.c
src/jmemnobs.c)
src/jmemnobs.c
src/jpeg_nbits.c)
qt_internal_add_3rdparty_library(BundledLibjpeg16bits
STATIC

View File

@ -1,4 +1,4 @@
Copyright (C) 2009-2023 D. R. Commander
Copyright (C) 2009-2024 D. R. Commander
Copyright (C) 2015, 2020 Google, Inc.
Copyright (C) 2019-2020 Arm Limited
Copyright (C) 2015-2016, 2018 Matthieu Darbois

View File

@ -160,7 +160,7 @@ FILES="
jmemnobs.c
jmemsys.h
jmorecfg.h
jpeg_nbits_table.h
jpeg_nbits.h
jquant1.c
jquant2.c
jsamplecomp.h

View File

@ -6,8 +6,8 @@
"Description": "The Independent JPEG Group's JPEG software",
"Homepage": "http://libjpeg-turbo.virtualgl.org/",
"Version": "3.0.1",
"DownloadLocation": "https://sourceforge.net/projects/libjpeg-turbo/files/3.0.1/libjpeg-turbo-3.0.1.tar.gz",
"Version": "3.0.2",
"DownloadLocation": "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.0.2/libjpeg-turbo-3.0.2.tar.gz",
"License": "Independent JPEG Group License and BSD 3-Clause \"New\" or \"Revised\" License and zlib License",
"LicenseId": "IJG AND BSD-3-Clause AND Zlib",
"LicenseFiles": [ "LICENSE", "ijg-license.txt", "zlib-license.txt"],

View File

@ -1,3 +1,38 @@
3.0.2
=====
### Significant changes relative to 3.0.1:
1. Fixed a signed integer overflow in the `tj3CompressFromYUV8()`,
`tj3DecodeYUV8()`, `tj3DecompressToYUV8()`, and `tj3EncodeYUV8()` functions,
detected by the Clang and GCC undefined behavior sanitizers, that could be
triggered by setting the `align` parameter to an unreasonably large value.
This issue did not pose a security threat, but removing the warning made it
easier to detect actual security issues, should they arise in the future.
2. Introduced a new parameter (`TJPARAM_MAXMEMORY` in the TurboJPEG C API and
`TJ.PARAM_MAXMEMORY` in the TurboJPEG Java API) and a corresponding TJBench
option (`-maxmemory`) for specifying the maximum amount of memory (in
megabytes) that will be allocated for intermediate buffers, which are used with
progressive JPEG compression and decompression, optimized baseline entropy
coding, lossless JPEG compression, and lossless transformation. The new
parameter and option serve the same purpose as the `max_memory_to_use` field in
the `jpeg_memory_mgr` struct in the libjpeg API, the `JPEGMEM` environment
variable, and the cjpeg/djpeg/jpegtran `-maxmemory` option.
3. Introduced a new parameter (`TJPARAM_MAXPIXELS` in the TurboJPEG C API and
`TJ.PARAM_MAXPIXELS` in the TurboJPEG Java API) and a corresponding TJBench
option (`-maxpixels`) for specifying the maximum number of pixels that the
decompression, lossless transformation, and packed-pixel image loading
functions/methods will process.
4. Fixed an error ("Unsupported color conversion request") that occurred when
attempting to decompress a 3-component lossless JPEG image without an Adobe
APP14 marker. The decompressor now assumes that a 3-component lossless JPEG
image without an Adobe APP14 marker uses the RGB colorspace if its component
IDs are 1, 2, and 3.
3.0.1
=====
@ -2146,7 +2181,7 @@ and unit tests now work on those architectures.
0.0.93
======
### Significant changes since 0.0.91:
### Significant changes relative to 0.0.91:
1. 2982659: Fixed x86-64 build on FreeBSD systems

View File

@ -6,7 +6,7 @@
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2009-2011, 2014-2016, 2018-2023, D. R. Commander.
* Copyright (C) 2009-2011, 2014-2016, 2018-2024, D. R. Commander.
* Copyright (C) 2015, Matthieu Darbois.
* Copyright (C) 2018, Matthias Räncker.
* Copyright (C) 2020, Arm Limited.
@ -35,41 +35,7 @@
#include "jchuff.h" /* Declarations shared with jc*huff.c */
#endif
#include <limits.h>
/*
* NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be
* used for bit counting rather than the lookup table. This will reduce the
* memory footprint by 64k, which is important for some mobile applications
* that create many isolated instances of libjpeg-turbo (web browsers, for
* instance.) This may improve performance on some mobile platforms as well.
* This feature is enabled by default only on Arm processors, because some x86
* chips have a slow implementation of bsr, and the use of clz/bsr cannot be
* shown to have a significant performance impact even on the x86 chips that
* have a fast implementation of it. When building for Armv6, you can
* explicitly disable the use of clz/bsr by adding -mthumb to the compiler
* flags (this defines __thumb__).
*/
/* NOTE: Both GCC and Clang define __GNUC__ */
#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
defined(_M_ARM) || defined(_M_ARM64)
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
#endif
#ifdef USE_CLZ_INTRINSIC
#if defined(_MSC_VER) && !defined(__clang__)
#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
#else
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
#endif
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
#else
#include "jpeg_nbits_table.h"
#define JPEG_NBITS(x) (jpeg_nbits_table[x])
#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x)
#endif
#include "jpeg_nbits.h"
/* Expanded entropy encoder object for Huffman encoding.

View File

@ -2,9 +2,9 @@
#define JPEG_LIB_VERSION 80
#define LIBJPEG_TURBO_VERSION 3.0.0
#define LIBJPEG_TURBO_VERSION 3.0.2
#define LIBJPEG_TURBO_VERSION_NUMBER 3000000
#define LIBJPEG_TURBO_VERSION_NUMBER 3000002
#define C_ARITH_CODING_SUPPORTED 1
@ -17,3 +17,4 @@
#endif
#define NO_PUTENV

View File

@ -4,11 +4,13 @@
#define BUILD ""
#define HIDDEN
#define INLINE inline
#define PACKAGE_NAME "libjpeg-turbo"
#define VERSION "3.0.0"
#define VERSION "3.0.2"
#if SIZE_MAX == 0xffffffff
#define SIZEOF_SIZE_T 4
@ -46,3 +48,4 @@
/* #undef WITH_SIMD */
#endif

View File

@ -1,6 +1,9 @@
/* libjpeg-turbo build number */
#define BUILD "@BUILD@"
/* How to hide global symbols. */
#define HIDDEN @HIDDEN@
/* Compiler's inline keyword */
#undef inline

View File

@ -6,7 +6,7 @@
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2011, 2015, 2018, 2021-2022, D. R. Commander.
* Copyright (C) 2011, 2015, 2018, 2021-2022, 2024, D. R. Commander.
* Copyright (C) 2016, 2018, 2022, Matthieu Darbois.
* Copyright (C) 2020, Arm Limited.
* Copyright (C) 2021, Alex Richardson.
@ -44,40 +44,7 @@
#ifdef C_PROGRESSIVE_SUPPORTED
/*
* NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be
* used for bit counting rather than the lookup table. This will reduce the
* memory footprint by 64k, which is important for some mobile applications
* that create many isolated instances of libjpeg-turbo (web browsers, for
* instance.) This may improve performance on some mobile platforms as well.
* This feature is enabled by default only on Arm processors, because some x86
* chips have a slow implementation of bsr, and the use of clz/bsr cannot be
* shown to have a significant performance impact even on the x86 chips that
* have a fast implementation of it. When building for Armv6, you can
* explicitly disable the use of clz/bsr by adding -mthumb to the compiler
* flags (this defines __thumb__).
*/
/* NOTE: Both GCC and Clang define __GNUC__ */
#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
defined(_M_ARM) || defined(_M_ARM64)
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
#endif
#ifdef USE_CLZ_INTRINSIC
#if defined(_MSC_VER) && !defined(__clang__)
#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
#else
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
#endif
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
#else
#include "jpeg_nbits_table.h"
#define JPEG_NBITS(x) (jpeg_nbits_table[x])
#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x)
#endif
#include "jpeg_nbits.h"
/* Expanded entropy encoder object for progressive Huffman encoding. */

View File

@ -6,7 +6,7 @@
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2016, 2022, D. R. Commander.
* Copyright (C) 2016, 2022, 2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@ -160,9 +160,12 @@ default_decompress_parms(j_decompress_ptr cinfo)
int cid1 = cinfo->comp_info[1].component_id;
int cid2 = cinfo->comp_info[2].component_id;
if (cid0 == 1 && cid1 == 2 && cid2 == 3)
cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
if (cid0 == 1 && cid1 == 2 && cid2 == 3) {
if (cinfo->master->lossless)
cinfo->jpeg_color_space = JCS_RGB; /* assume RGB w/out marker */
else
cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
} else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
else {
TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);

View File

@ -7,7 +7,7 @@
* Lossless JPEG Modifications:
* Copyright (C) 1999, Ken Murchison.
* libjpeg-turbo Modifications:
* Copyright (C) 2014, 2017, 2021-2022, D. R. Commander.
* Copyright (C) 2014, 2017, 2021-2023, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@ -111,7 +111,7 @@ JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
#if JPEG_LIB_VERSION >= 70
JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined")
#endif
JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
JMESSAGE(JERR_NO_BACKING_STORE, "Memory limit exceeded")
JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")

View File

@ -99,24 +99,6 @@ EXTERN(size_t) jpeg_mem_available(j_common_ptr cinfo, size_t min_bytes_needed,
#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
typedef unsigned short XMSH; /* type of extended-memory handles */
typedef unsigned short EMSH; /* type of expanded-memory handles */
typedef union {
short file_handle; /* DOS file handle if it's a temp file */
XMSH xms_handle; /* handle if it's a chunk of XMS */
EMSH ems_handle; /* handle if it's a chunk of EMS */
} handle_union;
#endif /* USE_MSDOS_MEMMGR */
#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
#include <Files.h>
#endif /* USE_MAC_MEMMGR */
typedef struct backing_store_struct *backing_store_ptr;
typedef struct backing_store_struct {
@ -130,22 +112,9 @@ typedef struct backing_store_struct {
void (*close_backing_store) (j_common_ptr cinfo, backing_store_ptr info);
/* Private fields for system-dependent backing-store management */
#ifdef USE_MSDOS_MEMMGR
/* For the MS-DOS manager (jmemdos.c), we need: */
handle_union handle; /* reference to backing-store storage object */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
#else
#ifdef USE_MAC_MEMMGR
/* For the Mac manager (jmemmac.c), we need: */
short temp_file; /* file reference number to temp file */
FSSpec tempSpec; /* the FSSpec for the temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
#else
/* For a typical implementation with temp files, we need: */
FILE *temp_file; /* stdio reference to temp file */
char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
#endif
#endif
} backing_store_info;

View File

@ -1,4 +1,32 @@
static const unsigned char jpeg_nbits_table[65536] = {
/*
* Copyright (C) 2024, D. R. Commander.
*
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*/
#include "jpeg_nbits.h"
#include "jconfigint.h"
#ifndef USE_CLZ_INTRINSIC
#define INCLUDE_JPEG_NBITS_TABLE
/* When building for x86[-64] with the SIMD extensions enabled, the C Huffman
* encoders can reuse jpeg_nbits_table from the SSE2 baseline Huffman encoder.
*/
#if (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || \
defined(_M_X64)) && defined(WITH_SIMD)
#undef INCLUDE_JPEG_NBITS_TABLE
#endif
#endif
#ifdef INCLUDE_JPEG_NBITS_TABLE
const unsigned char HIDDEN jpeg_nbits_table[65536] = {
0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
@ -4096,3 +4124,11 @@ static const unsigned char jpeg_nbits_table[65536] = {
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
};
#else
/* Suppress compiler warnings about empty translation unit. */
typedef int dummy_jpeg_nbits_table;
#endif

43
src/3rdparty/libjpeg/src/jpeg_nbits.h vendored Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2014, 2021, 2024, D. R. Commander.
* Copyright (C) 2014, Olle Liljenzin.
* Copyright (C) 2020, Arm Limited.
*
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*/
/*
* NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be
* used for bit counting rather than the lookup table. This will reduce the
* memory footprint by 64k, which is important for some mobile applications
* that create many isolated instances of libjpeg-turbo (web browsers, for
* instance.) This may improve performance on some mobile platforms as well.
* This feature is enabled by default only on Arm processors, because some x86
* chips have a slow implementation of bsr, and the use of clz/bsr cannot be
* shown to have a significant performance impact even on the x86 chips that
* have a fast implementation of it. When building for Armv6, you can
* explicitly disable the use of clz/bsr by adding -mthumb to the compiler
* flags (this defines __thumb__).
*/
/* NOTE: Both GCC and Clang define __GNUC__ */
#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
defined(_M_ARM) || defined(_M_ARM64)
#if !defined(__thumb__) || defined(__thumb2__)
#define USE_CLZ_INTRINSIC
#endif
#endif
#ifdef USE_CLZ_INTRINSIC
#if defined(_MSC_VER) && !defined(__clang__)
#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
#else
#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
#endif
#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
#else
extern const unsigned char jpeg_nbits_table[65536];
#define JPEG_NBITS(x) (jpeg_nbits_table[x])
#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x)
#endif

View File

@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2010, 2012-2023, D. R. Commander.
* Copyright (C) 2010, 2012-2024, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@ -37,7 +37,7 @@
*/
#define JCOPYRIGHT \
"Copyright (C) 2009-2023 D. R. Commander\n" \
"Copyright (C) 2009-2024 D. R. Commander\n" \
"Copyright (C) 2015, 2020 Google, Inc.\n" \
"Copyright (C) 2019-2020 Arm Limited\n" \
"Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
@ -52,4 +52,4 @@
"Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding"
#define JCOPYRIGHT_SHORT \
"Copyright (C) 1991-2023 The libjpeg-turbo Project and many others"
"Copyright (C) 1991-2024 The libjpeg-turbo Project and many others"

View File

@ -1,5 +1,5 @@
libpng 1.6.40 - June 21, 2023
=============================
libpng 1.6.43 - February 23, 2024
=================================
This is a public release of libpng, intended for use in production code.
@ -9,13 +9,13 @@ Files available for download
Source files with LF line endings (for Unix/Linux):
* libpng-1.6.40.tar.xz (LZMA-compressed, recommended)
* libpng-1.6.40.tar.gz
* libpng-1.6.43.tar.xz (LZMA-compressed, recommended)
* libpng-1.6.43.tar.gz (deflate-compressed)
Source files with CRLF line endings (for Windows):
* lpng1640.7z (LZMA-compressed, recommended)
* lpng1640.zip
* lpng1643.7z (LZMA-compressed, recommended)
* lpng1643.zip (deflate-compressed)
Other information:
@ -25,15 +25,36 @@ Other information:
* TRADEMARK.md
Changes from version 1.6.39 to version 1.6.40
Changes from version 1.6.42 to version 1.6.43
---------------------------------------------
* Fixed the eXIf chunk multiplicity checks.
* Fixed a memory leak in pCAL processing.
* Corrected the validity report about tRNS inside png_get_valid().
* Fixed various build issues on *BSD, Mac and Windows.
* Updated the configurations and the scripts for continuous integration.
* Cleaned up the code, the build scripts, and the documentation.
* Fixed the row width check in png_check_IHDR().
This corrected a bug that was specific to the 16-bit platforms,
and removed a spurious compiler warning from the 64-bit builds.
(Reported by Jacek Caban; fixed by John Bowler)
* Added eXIf chunk support to the push-mode reader in pngpread.c.
(Contributed by Chris Blume)
* Added contrib/pngexif for the benefit of the users who would like
to inspect the content of eXIf chunks.
* Added contrib/conftest/basic.dfa, a basic build-time configuration.
(Contributed by John Bowler)
* Fixed a preprocessor condition in pngread.c that broke build-time
configurations like contrib/conftest/pngcp.dfa.
(Contributed by John Bowler)
* Added CMake build support for LoongArch LSX.
(Contributed by GuXiWei)
* Fixed a CMake build error that occurred under a peculiar state of the
dependency tree. This was a regression introduced in libpng-1.6.41.
(Contributed by Dan Rosser)
* Marked the installed libpng headers as system headers in CMake.
(Contributed by Benjamin Buch)
* Updated the build support for RISCOS.
(Contributed by Cameron Cawley)
* Updated the makefiles to allow cross-platform builds to initialize
conventional make variables like AR and ARFLAGS.
* Added various improvements to the CI scripts in areas like version
consistency verification and text linting.
* Added version consistency verification to pngtest.c also.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.

View File

@ -6129,6 +6129,73 @@ Version 1.6.40 [June 21, 2023]
Updated the configurations and the scripts for continuous integration.
Cleaned up the code, the build scripts, and the documentation.
Version 1.6.41 [January 24, 2024]
Added SIMD-optimized code for the LoongArch LSX hardware.
(Contributed by GuXiWei, JinBo and ZhangLixia)
Fixed the run-time discovery of MIPS MSA hardware.
(Contributed by Sui Jingfeng)
Fixed an off-by-one error in the function png_do_check_palette_indexes(),
which failed to recognize errors that might have existed in the first
column of a broken palette-encoded image. This was a benign regression
accidentally introduced in libpng-1.6.33. No pixel was harmed.
(Contributed by Adam Richter; reviewed by John Bowler)
Fixed, improved and modernized the contrib/pngminus programs, i.e.,
png2pnm.c and pnm2png.c
Removed old and peculiar portability hacks that were meant to silence
warnings issued by gcc version 7.1 alone.
(Contributed by John Bowler)
Fixed and modernized the CMake file, and raised the minimum required
CMake version from 3.1 to 3.6.
(Contributed by Clinton Ingram, Timothy Lyanguzov, Tyler Kropp, et al.)
Allowed the configure script to disable the building of auxiliary tools
and tests, thus catching up with the CMake file.
(Contributed by Carlo Bramini)
Fixed a build issue on Mac.
(Contributed by Zixu Wang)
Moved the Autoconf macro files to scripts/autoconf.
Moved the CMake files (except for the main CMakeLists.txt) to
scripts/cmake and moved the list of their contributing authors to
scripts/cmake/AUTHORS.md
Updated the CI configurations and scripts.
Relicensed the CI scripts to the MIT License.
Improved the test coverage.
(Contributed by John Bowler)
Version 1.6.42 [January 29, 2024]
Fixed the implementation of the macro function png_check_sig().
This was an API regression, introduced in libpng-1.6.41.
(Reported by Matthieu Darbois)
Fixed and updated the libpng manual.
Version 1.6.43 [February 23, 2024]
Fixed the row width check in png_check_IHDR().
This corrected a bug that was specific to the 16-bit platforms,
and removed a spurious compiler warning from the 64-bit builds.
(Reported by Jacek Caban; fixed by John Bowler)
Added eXIf chunk support to the push-mode reader in pngpread.c.
(Contributed by Chris Blume)
Added contrib/pngexif for the benefit of the users who would like
to inspect the content of eXIf chunks.
Added contrib/conftest/basic.dfa, a basic build-time configuration.
(Contributed by John Bowler)
Fixed a preprocessor condition in pngread.c that broke build-time
configurations like contrib/conftest/pngcp.dfa.
(Contributed by John Bowler)
Added CMake build support for LoongArch LSX.
(Contributed by GuXiWei)
Fixed a CMake build error that occurred under a peculiar state of the
dependency tree. This was a regression introduced in libpng-1.6.41.
(Contributed by Dan Rosser)
Marked the installed libpng headers as system headers in CMake.
(Contributed by Benjamin Buch)
Updated the build support for RISCOS.
(Contributed by Cameron Cawley)
Updated the makefiles to allow cross-platform builds to initialize
conventional make variables like AR and ARFLAGS.
Added various improvements to the CI scripts in areas like version
consistency verification and text linting.
Added version consistency verification to pngtest.c also.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
Subscription is required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement

View File

@ -4,8 +4,8 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
PNG Reference Library License version 2
---------------------------------------
* Copyright (c) 1995-2023 The PNG Reference Library Authors.
* Copyright (c) 2018-2023 Cosmin Truta.
* Copyright (c) 1995-2024 The PNG Reference Library Authors.
* Copyright (c) 2018-2024 Cosmin Truta.
* Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
* Copyright (c) 1996-1997 Andreas Dilger.
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.

View File

@ -1,4 +1,4 @@
README for libpng version 1.6.40
README for libpng version 1.6.43
================================
See the note about version numbers near the top of `png.h`.
@ -142,10 +142,11 @@ Files included in this distribution
pngwrite.c => High-level write functions
pngwtran.c => Write data transformations
pngwutil.c => Write utility functions
arm/ => Optimized code for the ARM platform
intel/ => Optimized code for the INTEL-SSE2 platform
mips/ => Optimized code for the MIPS platform
powerpc/ => Optimized code for the PowerPC platform
arm/ => Optimized code for ARM Neon
intel/ => Optimized code for INTEL SSE2
loongarch/ => Optimized code for LoongArch LSX
mips/ => Optimized code for MIPS MSA and MIPS MMI
powerpc/ => Optimized code for PowerPC VSX
ci/ => Scripts for continuous integration
contrib/ => External contributions
arm-neon/ => Optimized code for the ARM-NEON platform
@ -158,6 +159,7 @@ Files included in this distribution
libtests/ => Test programs
oss-fuzz/ => Files used by the OSS-Fuzz project for fuzz-testing
libpng
pngexif/ => Program to inspect the EXIF information in PNG files
pngminim/ => Minimal decoder, encoder, and progressive decoder
programs demonstrating the use of pngusr.dfa
pngminus/ => Simple pnm2png and png2pnm programs

View File

@ -1,6 +1,6 @@
libpng-manual.txt - A description on how to use and modify libpng
Copyright (c) 2018-2023 Cosmin Truta
Copyright (c) 2018-2024 Cosmin Truta
Copyright (c) 1998-2018 Glenn Randers-Pehrson
This document is released under the libpng license.
@ -9,9 +9,9 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
libpng version 1.6.36, December 2018, through 1.6.40 - June 2023
libpng version 1.6.36, December 2018, through 1.6.43 - February 2024
Updated and distributed by Cosmin Truta
Copyright (c) 2018-2023 Cosmin Truta
Copyright (c) 2018-2024 Cosmin Truta
libpng versions 0.97, January 1998, through 1.6.35 - July 2018
Updated and distributed by Glenn Randers-Pehrson
@ -357,7 +357,7 @@ Customizing libpng.
return ERROR;
}
is_png = !png_sig_cmp(header, 0, number);
is_png = (png_sig_cmp(header, 0, number) == 0);
if (!is_png)
{
return NOT_PNG;
@ -385,8 +385,7 @@ create the structure, so your application should check for that.
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr,
(png_infopp)NULL, (png_infopp)NULL);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return ERROR;
}
@ -419,14 +418,13 @@ free any memory.
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr,
&end_info);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
fclose(fp);
return ERROR;
}
Pass (png_infopp)NULL instead of &end_info if you didn't create
an end_info structure.
Pass NULL instead of &end_info if you didn't create an end_info
structure.
If you would rather avoid the complexity of setjmp/longjmp issues,
you can compile libpng with PNG_NO_SETJMP, in which case
@ -496,7 +494,7 @@ You can set up a callback function to handle any unknown chunks in the
input stream. You must supply the function
read_chunk_callback(png_structp png_ptr,
png_unknown_chunkp chunk);
png_unknown_chunkp chunk)
{
/* The unknown chunk structure contains your
chunk data, along with similar data for any other
@ -547,9 +545,9 @@ a progress meter or the like. It's demonstrated in pngtest.c.
You must supply a function
void read_row_callback(png_structp png_ptr,
png_uint_32 row, int pass);
png_uint_32 row, int pass)
{
/* put your code here */
/* put your code here */
}
(You can give it another name that you like instead of "read_row_callback")
@ -1180,22 +1178,22 @@ where row_pointers is an array of pointers to the pixel data for each row:
If you know your image size and pixel size ahead of time, you can allocate
row_pointers prior to calling png_read_png() with
if (height > PNG_UINT_32_MAX/(sizeof (png_byte)))
png_error (png_ptr,
if (height > PNG_UINT_32_MAX / (sizeof (png_bytep)))
png_error(png_ptr,
"Image is too tall to process in memory");
if (width > PNG_UINT_32_MAX/pixel_size)
png_error (png_ptr,
if (width > PNG_UINT_32_MAX / pixel_size)
png_error(png_ptr,
"Image is too wide to process in memory");
row_pointers = png_malloc(png_ptr,
height*(sizeof (png_bytep)));
for (int i=0; i<height, i++)
row_pointers[i]=NULL; /* security precaution */
for (int i = 0; i < height, i++)
row_pointers[i] = NULL; /* security precaution */
for (int i=0; i<height, i++)
row_pointers[i]=png_malloc(png_ptr,
for (int i = 0; i < height, i++)
row_pointers[i] = png_malloc(png_ptr,
width*pixel_size);
png_set_rows(png_ptr, info_ptr, &row_pointers);
@ -1205,14 +1203,14 @@ row_pointers[i] to point into the proper places in your block, but first
be sure that your platform is able to allocate such a large buffer:
/* Guard against integer overflow */
if (height > PNG_SIZE_MAX/(width*pixel_size)) {
png_error(png_ptr,"image_data buffer would be too large");
}
if (height > PNG_SIZE_MAX/(width*pixel_size))
png_error(png_ptr, "image_data buffer would be too large");
png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size);
png_bytep buffer = png_malloc(png_ptr,
height*width*pixel_size);
for (int i=0; i<height, i++)
row_pointers[i]=buffer+i*width*pixel_size;
for (int i = 0; i < height, i++)
row_pointers[i] = buffer + i*width*pixel_size;
png_set_rows(png_ptr, info_ptr, &row_pointers);
@ -1465,25 +1463,24 @@ png_set_rgb_to_gray()).
non-paletted images (PNG_INFO_tRNS)
png_get_eXIf_1(png_ptr, info_ptr, &num_exif, &exif);
(PNG_INFO_eXIf)
exif - Exif profile (array of png_byte)
(PNG_INFO_eXIf)
png_get_hIST(png_ptr, info_ptr, &hist);
(PNG_INFO_hIST)
hist - histogram of palette (array of
png_uint_16)
png_uint_16) (PNG_INFO_hIST)
png_get_tIME(png_ptr, info_ptr, &mod_time);
mod_time - time image was last modified
(PNG_VALID_tIME)
(PNG_INFO_tIME)
png_get_bKGD(png_ptr, info_ptr, &background);
background - background color (of type
png_color_16p) (PNG_VALID_bKGD)
png_color_16p) (PNG_INFO_bKGD)
valid 16-bit red, green and blue
values, regardless of color_type
@ -1743,13 +1740,13 @@ grayscale images with bit depths of 2 or 4 or if there is a multiple-image
viewing application that wishes to treat all images in the same way.
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
png_set_palette_to_rgb(png_ptr);
if (png_get_valid(png_ptr, info_ptr,
PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY &&
bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand_gray_1_2_4_to_8(png_ptr);
The first two functions are actually aliases for png_set_expand(), added
in libpng version 1.0.4, with the function names expanded to improve code
@ -1764,18 +1761,20 @@ png_set_expand(); however, the resultant channels have 16 bits rather than 8.
Use this when the output color or gray channels are made linear to avoid fairly
severe accuracy loss.
if (bit_depth < 16)
png_set_expand_16(png_ptr);
if (bit_depth < 16)
png_set_expand_16(png_ptr);
PNG can have files with 16 bits per channel. If you only can handle
8 bits per channel, this will strip the pixels down to 8-bit.
if (bit_depth == 16)
{
#if PNG_LIBPNG_VER >= 10504
png_set_scale_16(png_ptr);
#else
png_set_strip_16(png_ptr);
#endif
}
(The more accurate "png_set_scale_16()" API became available in libpng version
1.5.4).
@ -1901,7 +1900,7 @@ Note that png_set_filler() does not change the color type. If you want
to do that, you can add a true alpha channel with
if (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_GRAY)
color_type == PNG_COLOR_TYPE_GRAY)
png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);
where "filler" contains the alpha value to assign to each pixel.
@ -1926,7 +1925,7 @@ with alpha.
if (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA)
png_set_rgb_to_gray(png_ptr, error_action,
double red_weight, double green_weight);
(double)red_weight, (double)green_weight);
error_action = 1: silently do the conversion
@ -1949,8 +1948,8 @@ In the corresponding fixed point API the red_weight and green_weight values are
simply scaled by 100,000:
png_set_rgb_to_gray(png_ptr, error_action,
png_fixed_point red_weight,
png_fixed_point green_weight);
(png_fixed_point)red_weight,
(png_fixed_point)green_weight);
If you have set error_action = 1 or 2, you can
later check whether the image really was gray, after processing
@ -2186,9 +2185,8 @@ do your own check for number_of_rows*width*pixel_size if you are using
a multiple-row buffer:
/* Guard against integer overflow */
if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) {
png_error(png_ptr,"image_data buffer would be too large");
}
if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size))
png_error(png_ptr, "image_data buffer would be too large");
Remember: Before you call png_read_update_info(), the png_get_*()
functions return the values corresponding to the original PNG image.
@ -2408,12 +2406,11 @@ separate.
if (!end_info)
{
png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return ERROR;
}
png_read_end(png_ptr, end_info);
png_read_end(png_ptr, end_info);
If you are not interested, you should still call png_read_end()
but you can pass NULL, avoiding the need to create an end_info structure.
@ -2421,7 +2418,7 @@ If you do this, libpng will not process any chunks after IDAT other than
skipping over them and perhaps (depending on whether you have called
png_set_crc_action) checking their CRCs while looking for the IEND chunk.
png_read_end(png_ptr, (png_infop)NULL);
png_read_end(png_ptr, NULL);
If you don't call png_read_end(), then your file pointer will be
left pointing to the first chunk after the last IDAT, which is probably
@ -2430,13 +2427,11 @@ the PNG datastream.
When you are done, you can free all memory allocated by libpng like this:
png_destroy_read_struct(&png_ptr, &info_ptr,
&end_info);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
or, if you didn't create an end_info structure,
png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
It is also possible to individually free the info_ptr members that
point to libpng-allocated storage with the following function:
@ -2556,15 +2551,13 @@ png_infop info_ptr;
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr,
(png_infopp)NULL, (png_infopp)NULL);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return ERROR;
}
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return ERROR;
}
@ -2597,8 +2590,7 @@ png_infop info_ptr;
{
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr,
(png_infopp)NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return ERROR;
}
@ -2763,8 +2755,7 @@ both "png_ptr"; you can call them anything you like, such as
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_write_struct(&png_ptr,
(png_infopp)NULL);
png_destroy_write_struct(&png_ptr, NULL);
return ERROR;
}
@ -2790,7 +2781,7 @@ section below for more information on the libpng error handling.
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_write_struct(&png_ptr, &info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
return ERROR;
}
@ -2844,9 +2835,9 @@ a progress meter or the like. It's demonstrated in pngtest.c.
You must supply a function
void write_row_callback(png_structp png_ptr, png_uint_32 row,
int pass);
int pass)
{
/* put your code here */
/* put your code here */
}
(You can give it another name that you like instead of "write_row_callback")
@ -3116,8 +3107,8 @@ width, height, bit_depth, and color_type must be the same in each call.
png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif);
exif - Exif profile (array of
png_byte) (PNG_INFO_eXIf)
exif - Exif profile (array of png_byte)
(PNG_INFO_eXIf)
png_set_hIST(png_ptr, info_ptr, hist);
@ -3127,12 +3118,12 @@ width, height, bit_depth, and color_type must be the same in each call.
png_set_tIME(png_ptr, info_ptr, mod_time);
mod_time - time image was last modified
(PNG_VALID_tIME)
(PNG_INFO_tIME)
png_set_bKGD(png_ptr, info_ptr, background);
background - background color (of type
png_color_16p) (PNG_VALID_bKGD)
png_color_16p) (PNG_INFO_bKGD)
png_set_text(png_ptr, info_ptr, text_ptr, num_text);
@ -4218,7 +4209,7 @@ png_create_read_struct_2() or png_create_write_struct_2() to register your
own functions as described above. These functions also provide a void
pointer that can be retrieved via
mem_ptr=png_get_mem_ptr(png_ptr);
mem_ptr = png_get_mem_ptr(png_ptr);
Your replacement memory functions must have prototypes as follows:
@ -4515,7 +4506,7 @@ When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
can still use PNG_DEBUG to control your own debugging:
#ifdef PNG_DEBUG
fprintf(stderr, ...
fprintf(stderr, ...);
#endif
When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
@ -4692,7 +4683,7 @@ deprecated since libpng-1.0.16 and libpng-1.2.6.
The function
png_check_sig(sig, num)
was replaced with
!png_sig_cmp(sig, 0, num)
png_sig_cmp(sig, 0, num) == 0
It has been deprecated since libpng-0.90.
The function
@ -4756,8 +4747,8 @@ png_get_mmx_bitdepth_threshold(), png_get_mmx_rowbytes_threshold(),
png_set_asm_flags(), and png_mmx_supported()
We removed the obsolete png_check_sig(), png_memcpy_check(), and
png_memset_check() functions. Instead use !png_sig_cmp(), memcpy(),
and memset(), respectively.
png_memset_check() functions. Instead use png_sig_cmp() == 0,
memcpy(), and memset(), respectively.
The function png_set_gray_1_2_4_to_8() was removed. It has been
deprecated since libpng-1.0.18 and 1.2.9, when it was replaced with
@ -5239,7 +5230,7 @@ changed, and is unaffected by conditional compilation macros. It is the
best choice for use in configure scripts for detecting the presence of any
libpng version since 0.88. In an autoconf "configure.in" you could use
AC_CHECK_LIB(png, png_get_io_ptr, ...
AC_CHECK_LIB(png, png_get_io_ptr, ...)
XV. Source code repository
@ -5248,12 +5239,12 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files
going back to version 0.70. You can access the git repository (read only)
at
https://github.com/glennrp/libpng or
https://github.com/pnggroup/libpng or
https://git.code.sf.net/p/libpng/code.git
or you can browse it with a web browser at
https://github.com/glennrp/libpng or
https://github.com/pnggroup/libpng or
https://sourceforge.net/p/libpng/code/ci/libpng16/tree/
Patches can be sent to png-mng-implement at lists.sourceforge.net or
@ -5263,7 +5254,7 @@ uploaded to the libpng bug tracker at
or as a "pull request" to
https://github.com/glennrp/libpng/pulls
https://github.com/pnggroup/libpng/pulls
We also accept patches built from the tar or zip distributions, and
simple verbal descriptions of bug fixes, reported either to the

View File

@ -1,7 +1,7 @@
/* png.c - location for general purpose libpng functions
*
* Copyright (c) 2018-2023 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -14,27 +14,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
typedef png_libpng_version_1_6_40 Your_png_h_is_not_version_1_6_40;
#ifdef __GNUC__
/* The version tests may need to be added to, but the problem warning has
* consistently been fixed in GCC versions which obtain wide-spread release.
* The problem is that many versions of GCC rearrange comparison expressions in
* the optimizer in such a way that the results of the comparison will change
* if signed integer overflow occurs. Such comparisons are not permitted in
* ANSI C90, however GCC isn't clever enough to work out that that do not occur
* below in png_ascii_from_fp and png_muldiv, so it produces a warning with
* -Wextra. Unfortunately this is highly dependent on the optimizer and the
* machine architecture so the warning comes and goes unpredictably and is
* impossible to "fix", even were that a good idea.
*/
#if __GNUC__ == 7 && __GNUC_MINOR__ == 1
#define GCC_STRICT_OVERFLOW 1
#endif /* GNU 7.1.x */
#endif /* GNU */
#ifndef GCC_STRICT_OVERFLOW
#define GCC_STRICT_OVERFLOW 0
#endif
typedef png_libpng_version_1_6_43 Your_png_h_is_not_version_1_6_43;
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
@ -73,21 +53,21 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
int PNGAPI
png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check)
{
png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
if (num_to_check > 8)
num_to_check = 8;
else if (num_to_check < 1)
return (-1);
return -1;
if (start > 7)
return (-1);
return -1;
if (start + num_to_check > 8)
num_to_check = 8 - start;
return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
return memcmp(&sig[start], &png_signature[start], num_to_check);
}
#endif /* READ */
@ -447,7 +427,6 @@ png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size),
memset(info_ptr, 0, (sizeof *info_ptr));
}
/* The following API is not called internally */
void PNGAPI
png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
int freer, png_uint_32 mask)
@ -686,9 +665,9 @@ png_voidp PNGAPI
png_get_io_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
return NULL;
return (png_ptr->io_ptr);
return png_ptr->io_ptr;
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
@ -752,7 +731,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
{
size_t pos = 0;
char number_buf[5]; /* enough for a four-digit year */
char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */
# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
# define APPEND_NUMBER(format, value)\
@ -815,8 +794,8 @@ png_get_copyright(png_const_structrp png_ptr)
return PNG_STRING_COPYRIGHT
#else
return PNG_STRING_NEWLINE \
"libpng version 1.6.40" PNG_STRING_NEWLINE \
"Copyright (c) 2018-2023 Cosmin Truta" PNG_STRING_NEWLINE \
"libpng version 1.6.43" PNG_STRING_NEWLINE \
"Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
@ -977,7 +956,7 @@ png_reset_zstream(png_structrp png_ptr)
return Z_STREAM_ERROR;
/* WARNING: this resets the window bits to the maximum! */
return (inflateReset(&png_ptr->zstream));
return inflateReset(&png_ptr->zstream);
}
#endif /* READ */
@ -986,7 +965,7 @@ png_uint_32 PNGAPI
png_access_version_number(void)
{
/* Version of *.c files used when building libpng */
return((png_uint_32)PNG_LIBPNG_VER);
return (png_uint_32)PNG_LIBPNG_VER;
}
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
@ -1842,14 +1821,14 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
}
# ifdef PNG_WARNINGS_SUPPORTED
else
{
char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */
{
char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */
pos = png_safecat(message, (sizeof message), pos,
png_format_number(number, number+(sizeof number),
PNG_NUMBER_FORMAT_x, value));
pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */
}
pos = png_safecat(message, (sizeof message), pos,
png_format_number(number, number+(sizeof number),
PNG_NUMBER_FORMAT_x, value));
pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */
}
# endif
/* The 'reason' is an arbitrary message, allow +79 maximum 195 */
pos = png_safecat(message, (sizeof message), pos, reason);
@ -2532,17 +2511,6 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
#endif /* COLORSPACE */
#ifdef __GNUC__
/* This exists solely to work round a warning from GNU C. */
static int /* PRIVATE */
png_gt(size_t a, size_t b)
{
return a > b;
}
#else
# define png_gt(a,b) ((a) > (b))
#endif
void /* PRIVATE */
png_check_IHDR(png_const_structrp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth,
@ -2564,8 +2532,16 @@ png_check_IHDR(png_const_structrp png_ptr,
error = 1;
}
if (png_gt(((width + 7) & (~7U)),
((PNG_SIZE_MAX
/* The bit mask on the first line below must be at least as big as a
* png_uint_32. "~7U" is not adequate on 16-bit systems because it will
* be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the
* type of the result at least as bit (in bits) as the RHS of the > operator
* which also avoids a common warning on 64-bit systems that the comparison
* of (png_uint_32) against the constant value on the RHS will always be
* false.
*/
if (((width + 7) & ~(png_alloc_size_t)7) >
(((PNG_SIZE_MAX
- 48 /* big_row_buf hack */
- 1) /* filter byte */
/ 8) /* 8-byte RGBA pixels */
@ -2891,14 +2867,6 @@ png_pow10(int power)
/* Function to format a floating point value in ASCII with a given
* precision.
*/
#if GCC_STRICT_OVERFLOW
#pragma GCC diagnostic push
/* The problem arises below with exp_b10, which can never overflow because it
* comes, originally, from frexp and is therefore limited to a range which is
* typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)).
*/
#pragma GCC diagnostic warning "-Wstrict-overflow=2"
#endif /* GCC_STRICT_OVERFLOW */
void /* PRIVATE */
png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
double fp, unsigned int precision)
@ -3220,10 +3188,6 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size,
/* Here on buffer too small. */
png_error(png_ptr, "ASCII conversion buffer too small");
}
#if GCC_STRICT_OVERFLOW
#pragma GCC diagnostic pop
#endif /* GCC_STRICT_OVERFLOW */
# endif /* FLOATING_POINT */
# ifdef PNG_FIXED_POINT_SUPPORTED
@ -3251,7 +3215,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
if (num <= 0x80000000) /* else overflowed */
{
unsigned int ndigits = 0, first = 16 /* flag value */;
char digits[10];
char digits[10] = {0};
while (num)
{
@ -3336,15 +3300,6 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
* the nearest .00001). Overflow and divide by zero are signalled in
* the result, a boolean - true on success, false on overflow.
*/
#if GCC_STRICT_OVERFLOW /* from above */
/* It is not obvious which comparison below gets optimized in such a way that
* signed overflow would change the result; looking through the code does not
* reveal any tests which have the form GCC complains about, so presumably the
* optimizer is moving an add or subtract into the 'if' somewhere.
*/
#pragma GCC diagnostic push
#pragma GCC diagnostic warning "-Wstrict-overflow=2"
#endif /* GCC_STRICT_OVERFLOW */
int
png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
png_int_32 divisor)
@ -3459,9 +3414,6 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
return 0;
}
#if GCC_STRICT_OVERFLOW
#pragma GCC diagnostic pop
#endif /* GCC_STRICT_OVERFLOW */
#endif /* READ_GAMMA || INCH_CONVERSIONS */
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)

View File

@ -1,9 +1,9 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.6.40
* libpng version 1.6.43
*
* Copyright (c) 2018-2023 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -15,7 +15,7 @@
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.35, July 2018:
* Glenn Randers-Pehrson
* libpng versions 1.6.36, December 2018, through 1.6.40, June 2023:
* libpng versions 1.6.36, December 2018, through 1.6.43, February 2024:
* Cosmin Truta
* See also "Contributing Authors", below.
*/
@ -27,8 +27,8 @@
* PNG Reference Library License version 2
* ---------------------------------------
*
* * Copyright (c) 1995-2023 The PNG Reference Library Authors.
* * Copyright (c) 2018-2023 Cosmin Truta.
* * Copyright (c) 1995-2024 The PNG Reference Library Authors.
* * Copyright (c) 2018-2024 Cosmin Truta.
* * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
* * Copyright (c) 1996-1997 Andreas Dilger.
* * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -239,7 +239,7 @@
* ...
* 1.5.30 15 10530 15.so.15.30[.0]
* ...
* 1.6.40 16 10640 16.so.16.40[.0]
* 1.6.43 16 10643 16.so.16.43[.0]
*
* Henceforth the source version will match the shared-library major and
* minor numbers; the shared-library major version number will be used for
@ -255,9 +255,6 @@
* to the info_ptr or png_ptr members through png.h, and the compiled
* application is loaded with a different version of the library.
*
* DLLNUM will change each time there are forward or backward changes
* in binary compatibility (e.g., when a new feature is added).
*
* See libpng.txt or libpng.3 for more information. The PNG specification
* is available as a W3C Recommendation and as an ISO/IEC Standard; see
* <https://www.w3.org/TR/2003/REC-PNG-20031110/>
@ -278,19 +275,21 @@
*/
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.40"
#define PNG_HEADER_VERSION_STRING " libpng version 1.6.40 - June 21, 2023\n"
#define PNG_LIBPNG_VER_STRING "1.6.43"
#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
/* The versions of shared library builds should stay in sync, going forward */
#define PNG_LIBPNG_VER_SHAREDLIB 16
#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
#define PNG_LIBPNG_VER_RELEASE 40
#define PNG_LIBPNG_VER_RELEASE 43
/* This should be zero for a public release, or non-zero for a
* development version. [Deprecated]
* development version.
*/
#define PNG_LIBPNG_VER_BUILD 0
@ -318,7 +317,7 @@
* From version 1.0.1 it is:
* XXYYZZ, where XX=major, YY=minor, ZZ=release
*/
#define PNG_LIBPNG_VER 10640 /* 1.6.40 */
#define PNG_LIBPNG_VER 10643 /* 1.6.43 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@ -428,7 +427,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
typedef char* png_libpng_version_1_6_40;
typedef char* png_libpng_version_1_6_43;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
@ -849,7 +848,7 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */
/* Added to libpng-1.5.4 */
#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */
#if INT_MAX >= 0x8000 /* else this might break */
#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */
#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */
#endif
@ -908,15 +907,15 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
* PNG file. Returns zero if the supplied bytes match the 8-byte PNG
* signature, and non-zero otherwise. Having num_to_check == 0 or
* start > 7 will always fail (ie return non-zero).
* start > 7 will always fail (i.e. return non-zero).
*/
PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start,
size_t num_to_check));
/* Simple signature checking function. This is the same as calling
* png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
* png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0).
*/
#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */
/* Allocate and initialize png_ptr struct for reading, and any other memory. */
PNG_EXPORTA(4, png_structp, png_create_read_struct,
@ -1730,12 +1729,9 @@ PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
png_inforp info_ptr, png_uint_32 free_me, int num));
/* Reassign responsibility for freeing existing data, whether allocated
/* Reassign the responsibility for freeing existing data, whether allocated
* by libpng or by the application; this works on the png_info structure passed
* in, it does not change the state for other png_info structures.
*
* It is unlikely that this function works correctly as of 1.6.0 and using it
* may result either in memory leaks or double free of allocated data.
* in, without changing the state for other png_info structures.
*/
PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr,
png_inforp info_ptr, int freer, png_uint_32 mask));
@ -3207,11 +3203,18 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
#ifdef PNG_MIPS_MSA_API_SUPPORTED
# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */
#endif
#define PNG_IGNORE_ADLER32 8
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */
#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */
#endif
#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions
* supported */
#endif
#ifdef PNG_MIPS_MMI_API_SUPPORTED
# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */
#endif
#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */
/* Return values: NOTE: there are four values and 'off' is *not* zero */
#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */

View File

@ -1,9 +1,9 @@
/* pngconf.h - machine-configurable file for libpng
*
* libpng version 1.6.40
* libpng version 1.6.43
*
* Copyright (c) 2018-2022 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.

View File

@ -1,7 +1,7 @@
/* pngerror.c - stub functions for i/o and memory allocation
*
* Copyright (c) 2018 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -255,7 +255,7 @@ void
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
png_alloc_size_t value)
{
char buffer[PNG_NUMBER_BUFFER_SIZE];
char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
}
@ -265,7 +265,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format,
{
png_alloc_size_t u;
png_charp str;
char buffer[PNG_NUMBER_BUFFER_SIZE];
char buffer[PNG_NUMBER_BUFFER_SIZE] = {0};
/* Avoid overflow by doing the negate in a png_alloc_size_t: */
u = (png_alloc_size_t)value;
@ -858,7 +858,7 @@ png_get_error_ptr(png_const_structrp png_ptr)
if (png_ptr == NULL)
return NULL;
return ((png_voidp)png_ptr->error_ptr);
return (png_voidp)png_ptr->error_ptr;
}
@ -933,31 +933,25 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
#endif
int /* PRIVATE */
png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg)
{
volatile png_imagep image = image_in;
volatile int result;
volatile png_voidp saved_error_buf;
png_voidp saved_error_buf = image->opaque->error_buf;
jmp_buf safe_jmpbuf;
int result;
/* Safely execute function(arg) with png_error returning to this function. */
saved_error_buf = image->opaque->error_buf;
result = setjmp(safe_jmpbuf) == 0;
if (result != 0)
/* Safely execute function(arg), with png_error returning back here. */
if (setjmp(safe_jmpbuf) == 0)
{
image->opaque->error_buf = safe_jmpbuf;
result = function(arg);
image->opaque->error_buf = saved_error_buf;
return result;
}
/* On png_error, return via longjmp, pop the jmpbuf, and free the image. */
image->opaque->error_buf = saved_error_buf;
/* And do the cleanup prior to any failure return. */
if (result == 0)
png_image_free(image);
return result;
png_image_free(image);
return 0;
}
#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
#endif /* READ || WRITE */

View File

@ -1,7 +1,7 @@
/* pngget.c - retrieval of values from info struct
*
* Copyright (c) 2018-2023 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -28,22 +28,22 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
* valid tRNS chunk in this case.
*/
if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0)
return(0);
return 0;
#endif
return(info_ptr->valid & flag);
return info_ptr->valid & flag;
}
return(0);
return 0;
}
size_t PNGAPI
png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->rowbytes);
return info_ptr->rowbytes;
return(0);
return 0;
}
#ifdef PNG_INFO_IMAGE_SUPPORTED
@ -51,9 +51,9 @@ png_bytepp PNGAPI
png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->row_pointers);
return info_ptr->row_pointers;
return(0);
return 0;
}
#endif
@ -65,7 +65,7 @@ png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->width;
return (0);
return 0;
}
png_uint_32 PNGAPI
@ -74,7 +74,7 @@ png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->height;
return (0);
return 0;
}
png_byte PNGAPI
@ -83,7 +83,7 @@ png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->bit_depth;
return (0);
return 0;
}
png_byte PNGAPI
@ -92,7 +92,7 @@ png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->color_type;
return (0);
return 0;
}
png_byte PNGAPI
@ -101,7 +101,7 @@ png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->filter_type;
return (0);
return 0;
}
png_byte PNGAPI
@ -110,7 +110,7 @@ png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->interlace_type;
return (0);
return 0;
}
png_byte PNGAPI
@ -119,7 +119,7 @@ png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return info_ptr->compression_type;
return (0);
return 0;
}
png_uint_32 PNGAPI
@ -127,21 +127,20 @@ png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
png_debug(1, "in png_get_x_pixels_per_meter");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
png_debug1(1, "in %s retrieval function",
"png_get_x_pixels_per_meter");
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
return (info_ptr->x_pixels_per_unit);
}
{
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
return info_ptr->x_pixels_per_unit;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return (0);
return 0;
}
png_uint_32 PNGAPI
@ -149,42 +148,41 @@ png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
png_debug(1, "in png_get_y_pixels_per_meter");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
png_debug1(1, "in %s retrieval function",
"png_get_y_pixels_per_meter");
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
return (info_ptr->y_pixels_per_unit);
return info_ptr->y_pixels_per_unit;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return (0);
return 0;
}
png_uint_32 PNGAPI
png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_pHYs_SUPPORTED
png_debug(1, "in png_get_pixels_per_meter");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
return (info_ptr->x_pixels_per_unit);
return info_ptr->x_pixels_per_unit;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return (0);
return 0;
}
#ifdef PNG_FLOATING_POINT_SUPPORTED
@ -193,21 +191,21 @@ png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
info_ptr)
{
#ifdef PNG_READ_pHYs_SUPPORTED
png_debug(1, "in png_get_pixel_aspect_ratio");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
if (info_ptr->x_pixels_per_unit != 0)
return ((float)((float)info_ptr->y_pixels_per_unit
/(float)info_ptr->x_pixels_per_unit));
return (float)info_ptr->y_pixels_per_unit
/ (float)info_ptr->x_pixels_per_unit;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return ((float)0.0);
return (float)0.0;
}
#endif
@ -217,6 +215,8 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
png_const_inforp info_ptr)
{
#ifdef PNG_READ_pHYs_SUPPORTED
png_debug(1, "in png_get_pixel_aspect_ratio_fixed");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0 &&
info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 &&
@ -225,8 +225,6 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
{
png_fixed_point res;
png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
/* The following casts work because a PNG 4 byte integer only has a valid
* range of 0..2^31-1; otherwise the cast might overflow.
*/
@ -247,80 +245,80 @@ png_int_32 PNGAPI
png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
png_debug(1, "in png_get_x_offset_microns");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
return (info_ptr->x_offset);
return info_ptr->x_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return (0);
return 0;
}
png_int_32 PNGAPI
png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
png_debug(1, "in png_get_y_offset_microns");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
return (info_ptr->y_offset);
return info_ptr->y_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return (0);
return 0;
}
png_int_32 PNGAPI
png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
png_debug(1, "in png_get_x_offset_pixels");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
return (info_ptr->x_offset);
return info_ptr->x_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return (0);
return 0;
}
png_int_32 PNGAPI
png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
#ifdef PNG_oFFs_SUPPORTED
png_debug(1, "in png_get_y_offset_pixels");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_oFFs) != 0)
{
png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
return (info_ptr->y_offset);
return info_ptr->y_offset;
}
#else
PNG_UNUSED(png_ptr)
PNG_UNUSED(info_ptr)
#endif
return (0);
return 0;
}
#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
@ -434,11 +432,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
png_uint_32 retval = 0;
png_debug1(1, "in %s retrieval function", "pHYs");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_pHYs) != 0)
{
png_debug1(1, "in %s retrieval function", "pHYs");
if (res_x != NULL)
{
*res_x = info_ptr->x_pixels_per_unit;
@ -464,7 +462,7 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
}
}
return (retval);
return retval;
}
#endif /* pHYs */
#endif /* INCH_CONVERSIONS */
@ -478,9 +476,9 @@ png_byte PNGAPI
png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->channels);
return info_ptr->channels;
return (0);
return 0;
}
#ifdef PNG_READ_SUPPORTED
@ -488,9 +486,9 @@ png_const_bytep PNGAPI
png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->signature);
return info_ptr->signature;
return (NULL);
return NULL;
}
#endif
@ -499,17 +497,17 @@ png_uint_32 PNGAPI
png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
png_color_16p *background)
{
png_debug1(1, "in %s retrieval function", "bKGD");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_bKGD) != 0 &&
background != NULL)
{
png_debug1(1, "in %s retrieval function", "bKGD");
*background = &(info_ptr->background);
return (PNG_INFO_bKGD);
return PNG_INFO_bKGD;
}
return (0);
return 0;
}
#endif
@ -524,6 +522,8 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
double *white_x, double *white_y, double *red_x, double *red_y,
double *green_x, double *green_y, double *blue_x, double *blue_y)
{
png_debug1(1, "in %s retrieval function", "cHRM");
/* Quiet API change: this code used to only return the end points if a cHRM
* chunk was present, but the end points can also come from iCCP or sRGB
* chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
@ -533,8 +533,6 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
png_debug1(1, "in %s retrieval function", "cHRM");
if (white_x != NULL)
*white_x = png_float(png_ptr,
info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
@ -559,10 +557,10 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (blue_y != NULL)
*blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
"cHRM blue Y");
return (PNG_INFO_cHRM);
return PNG_INFO_cHRM;
}
return (0);
return 0;
}
png_uint_32 PNGAPI
@ -571,11 +569,11 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
double *blue_Z)
{
png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
if (red_X != NULL)
*red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
"cHRM red X");
@ -603,10 +601,10 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
if (blue_Z != NULL)
*blue_Z = png_float(png_ptr,
info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
return (PNG_INFO_cHRM);
return PNG_INFO_cHRM;
}
return (0);
return 0;
}
# endif
@ -619,11 +617,11 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
png_fixed_point *int_blue_Z)
{
png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
{
png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
if (int_red_X != NULL)
*int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
if (int_red_Y != NULL)
@ -642,10 +640,10 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
if (int_blue_Z != NULL)
*int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
return (PNG_INFO_cHRM);
return PNG_INFO_cHRM;
}
return (0);
return 0;
}
png_uint_32 PNGAPI
@ -675,10 +673,10 @@ png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*blue_x = info_ptr->colorspace.end_points_xy.bluex;
if (blue_y != NULL)
*blue_y = info_ptr->colorspace.end_points_xy.bluey;
return (PNG_INFO_cHRM);
return PNG_INFO_cHRM;
}
return (0);
return 0;
}
# endif
#endif
@ -696,10 +694,10 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
file_gamma != NULL)
{
*file_gamma = info_ptr->colorspace.gamma;
return (PNG_INFO_gAMA);
return PNG_INFO_gAMA;
}
return (0);
return 0;
}
# endif
@ -716,10 +714,10 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
*file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
"png_get_gAMA");
return (PNG_INFO_gAMA);
return PNG_INFO_gAMA;
}
return (0);
return 0;
}
# endif
#endif
@ -735,10 +733,10 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
(info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL)
{
*file_srgb_intent = info_ptr->colorspace.rendering_intent;
return (PNG_INFO_sRGB);
return PNG_INFO_sRGB;
}
return (0);
return 0;
}
#endif
@ -762,10 +760,10 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
*/
if (compression_type != NULL)
*compression_type = PNG_COMPRESSION_TYPE_BASE;
return (PNG_INFO_iCCP);
return PNG_INFO_iCCP;
}
return (0);
return 0;
}
#endif
@ -775,13 +773,15 @@ int PNGAPI
png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
png_sPLT_tpp spalettes)
{
png_debug1(1, "in %s retrieval function", "sPLT");
if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
{
*spalettes = info_ptr->splt_palettes;
return info_ptr->splt_palettes_num;
}
return (0);
return 0;
}
#endif
@ -807,10 +807,10 @@ png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr,
{
*num_exif = info_ptr->num_exif;
*exif = info_ptr->exif;
return (PNG_INFO_eXIf);
return PNG_INFO_eXIf;
}
return (0);
return 0;
}
#endif
@ -825,10 +825,10 @@ png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
(info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL)
{
*hist = info_ptr->hist;
return (PNG_INFO_hIST);
return PNG_INFO_hIST;
}
return (0);
return 0;
}
#endif
@ -841,7 +841,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
png_debug1(1, "in %s retrieval function", "IHDR");
if (png_ptr == NULL || info_ptr == NULL)
return (0);
return 0;
if (width != NULL)
*width = info_ptr->width;
@ -873,7 +873,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
info_ptr->compression_type, info_ptr->filter_type);
return (1);
return 1;
}
#ifdef PNG_oFFs_SUPPORTED
@ -890,10 +890,10 @@ png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
*offset_x = info_ptr->x_offset;
*offset_y = info_ptr->y_offset;
*unit_type = (int)info_ptr->offset_unit_type;
return (PNG_INFO_oFFs);
return PNG_INFO_oFFs;
}
return (0);
return 0;
}
#endif
@ -917,10 +917,10 @@ png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
*nparams = (int)info_ptr->pcal_nparams;
*units = info_ptr->pcal_units;
*params = info_ptr->pcal_params;
return (PNG_INFO_pCAL);
return PNG_INFO_pCAL;
}
return (0);
return 0;
}
#endif
@ -932,6 +932,8 @@ png_uint_32 PNGAPI
png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, png_fixed_point *width, png_fixed_point *height)
{
png_debug1(1, "in %s retrieval function", "sCAL");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL) != 0)
{
@ -943,10 +945,10 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
*width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
*height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
"sCAL height");
return (PNG_INFO_sCAL);
return PNG_INFO_sCAL;
}
return(0);
return 0;
}
# endif /* FLOATING_ARITHMETIC */
# endif /* FIXED_POINT */
@ -955,32 +957,36 @@ png_uint_32 PNGAPI
png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, double *width, double *height)
{
png_debug1(1, "in %s retrieval function", "sCAL(float)");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL) != 0)
{
*unit = info_ptr->scal_unit;
*width = atof(info_ptr->scal_s_width);
*height = atof(info_ptr->scal_s_height);
return (PNG_INFO_sCAL);
return PNG_INFO_sCAL;
}
return(0);
return 0;
}
# endif /* FLOATING POINT */
png_uint_32 PNGAPI
png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
int *unit, png_charpp width, png_charpp height)
{
png_debug1(1, "in %s retrieval function", "sCAL(str)");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_sCAL) != 0)
{
*unit = info_ptr->scal_unit;
*width = info_ptr->scal_s_width;
*height = info_ptr->scal_s_height;
return (PNG_INFO_sCAL);
return PNG_INFO_sCAL;
}
return(0);
return 0;
}
#endif /* sCAL */
@ -1015,7 +1021,7 @@ png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
}
}
return (retval);
return retval;
}
#endif /* pHYs */
@ -1031,10 +1037,10 @@ png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
*palette = info_ptr->palette;
*num_palette = info_ptr->num_palette;
png_debug1(3, "num_palette = %d", *num_palette);
return (PNG_INFO_PLTE);
return PNG_INFO_PLTE;
}
return (0);
return 0;
}
#ifdef PNG_sBIT_SUPPORTED
@ -1048,10 +1054,10 @@ png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
(info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL)
{
*sig_bit = &(info_ptr->sig_bit);
return (PNG_INFO_sBIT);
return PNG_INFO_sBIT;
}
return (0);
return 0;
}
#endif
@ -1062,7 +1068,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
{
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
{
png_debug1(1, "in 0x%lx retrieval function",
png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx",
(unsigned long)png_ptr->chunk_name);
if (text_ptr != NULL)
@ -1077,7 +1083,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
if (num_text != NULL)
*num_text = 0;
return(0);
return 0;
}
#endif
@ -1092,10 +1098,10 @@ png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
(info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL)
{
*mod_time = &(info_ptr->mod_time);
return (PNG_INFO_tIME);
return PNG_INFO_tIME;
}
return (0);
return 0;
}
#endif
@ -1105,11 +1111,12 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
{
png_uint_32 retval = 0;
png_debug1(1, "in %s retrieval function", "tRNS");
if (png_ptr != NULL && info_ptr != NULL &&
(info_ptr->valid & PNG_INFO_tRNS) != 0)
{
png_debug1(1, "in %s retrieval function", "tRNS");
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
if (trans_alpha != NULL)
@ -1141,7 +1148,7 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
}
}
return (retval);
return retval;
}
#endif
@ -1156,7 +1163,7 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
return info_ptr->unknown_chunks_num;
}
return (0);
return 0;
}
#endif
@ -1252,7 +1259,7 @@ png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
if (png_ptr != NULL && info_ptr != NULL)
return png_ptr->num_palette_max;
return (-1);
return -1;
}
# endif
#endif

View File

@ -1,8 +1,8 @@
/* pnglibconf.h - library build configuration */
/* libpng version 1.6.40 */
/* libpng version 1.6.43 */
/* Copyright (c) 2018-2023 Cosmin Truta */
/* Copyright (c) 2018-2024 Cosmin Truta */
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
@ -27,6 +27,7 @@
#define PNG_COLORSPACE_SUPPORTED
#define PNG_CONSOLE_IO_SUPPORTED
#define PNG_CONVERT_tIME_SUPPORTED
/*#undef PNG_DISABLE_ADLER32_CHECK_SUPPORTED*/
#define PNG_EASY_ACCESS_SUPPORTED
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
#define PNG_ERROR_TEXT_SUPPORTED
@ -41,6 +42,10 @@
#define PNG_INCH_CONVERSIONS_SUPPORTED
#define PNG_INFO_IMAGE_SUPPORTED
#define PNG_IO_STATE_SUPPORTED
/*#undef PNG_MIPS_MMI_API_SUPPORTED*/
/*#undef PNG_MIPS_MMI_CHECK_SUPPORTED*/
/*#undef PNG_MIPS_MSA_API_SUPPORTED*/
/*#undef PNG_MIPS_MSA_CHECK_SUPPORTED*/
#define PNG_MNG_FEATURES_SUPPORTED
#define PNG_POINTER_INDEXING_SUPPORTED
/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/

View File

@ -1,7 +1,7 @@
/* pngpread.c - read a png file in push mode
*
* Copyright (c) 2018 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -145,10 +145,10 @@ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
num_to_check);
png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
{
if (num_checked < 4 &&
png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
png_error(png_ptr, "Not a PNG file");
else
@ -294,6 +294,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
}
#endif
#ifdef PNG_READ_eXIf_SUPPORTED
else if (png_ptr->chunk_name == png_eXIf)
{
PNG_PUSH_SAVE_BUFFER_IF_FULL
png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length);
}
#endif
#ifdef PNG_READ_sRGB_SUPPORTED
else if (chunk_name == png_sRGB)
@ -1089,7 +1097,7 @@ png_voidp PNGAPI
png_get_progressive_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
return NULL;
return png_ptr->io_ptr;
}

View File

@ -1,7 +1,7 @@
/* pngpriv.h - private declarations for use inside libpng
*
* Copyright (c) 2018-2023 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -36,7 +36,7 @@
* still required (as of 2011-05-02.)
*/
#ifndef _POSIX_SOURCE
# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
#endif
#ifndef PNG_VERSION_INFO_ONLY
@ -190,13 +190,27 @@
#endif /* PNG_ARM_NEON_OPT > 0 */
#ifndef PNG_MIPS_MSA_OPT
# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \
defined(PNG_ALIGNED_MEMORY_SUPPORTED)
# define PNG_MIPS_MSA_OPT 2
# else
# define PNG_MIPS_MSA_OPT 0
# endif
#endif
#ifndef PNG_MIPS_MMI_OPT
# ifdef PNG_MIPS_MMI
# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \
defined(PNG_ALIGNED_MEMORY_SUPPORTED)
# define PNG_MIPS_MMI_OPT 1
# else
# define PNG_MIPS_MMI_OPT 0
# endif
# else
# define PNG_MIPS_MMI_OPT 0
# endif
#endif
#ifndef PNG_POWERPC_VSX_OPT
# if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__)
# define PNG_POWERPC_VSX_OPT 2
@ -205,13 +219,21 @@
# endif
#endif
#ifndef PNG_LOONGARCH_LSX_OPT
# if defined(__loongarch_sx)
# define PNG_LOONGARCH_LSX_OPT 1
# else
# define PNG_LOONGARCH_LSX_OPT 0
# endif
#endif
#ifndef PNG_INTEL_SSE_OPT
# ifdef PNG_INTEL_SSE
/* Only check for SSE if the build configuration has been modified to
* enable SSE optimizations. This means that these optimizations will
* be off by default. See contrib/intel for more details.
*/
# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \
defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \
(defined(_M_IX86_FP) && _M_IX86_FP >= 2)
# define PNG_INTEL_SSE_OPT 1
@ -248,7 +270,6 @@
#endif
#if PNG_MIPS_MSA_OPT > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa
# ifndef PNG_MIPS_MSA_IMPLEMENTATION
# if defined(__mips_msa)
# if defined(__clang__)
@ -264,11 +285,28 @@
# ifndef PNG_MIPS_MSA_IMPLEMENTATION
# define PNG_MIPS_MSA_IMPLEMENTATION 1
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
# endif
#else
# define PNG_MIPS_MSA_IMPLEMENTATION 0
#endif /* PNG_MIPS_MSA_OPT > 0 */
#if PNG_MIPS_MMI_OPT > 0
# ifndef PNG_MIPS_MMI_IMPLEMENTATION
# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64)
# define PNG_MIPS_MMI_IMPLEMENTATION 2
# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */
# define PNG_MIPS_MMI_IMPLEMENTATION 0
# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */
# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */
# if PNG_MIPS_MMI_IMPLEMENTATION > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips
# endif
#else
# define PNG_MIPS_MMI_IMPLEMENTATION 0
#endif /* PNG_MIPS_MMI_OPT > 0 */
#if PNG_POWERPC_VSX_OPT > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx
# define PNG_POWERPC_VSX_IMPLEMENTATION 1
@ -276,6 +314,12 @@
# define PNG_POWERPC_VSX_IMPLEMENTATION 0
#endif
#if PNG_LOONGARCH_LSX_OPT > 0
# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx
# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1
#else
# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0
#endif
/* Is this a build of a DLL where compilation of the object modules requires
* different preprocessor settings to those required for a simple library? If
@ -514,18 +558,8 @@
*/
# include <float.h>
# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
/* We need to check that <math.h> hasn't already been included earlier
* as it seems it doesn't agree with <fp.h>, yet we should really use
* <fp.h> if possible.
*/
# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
# include <fp.h>
# endif
# else
# include <math.h>
# endif
# include <math.h>
# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
/* Amiga SAS/C: We must include builtin FPU functions when compiling using
* MATH=68881
@ -1306,7 +1340,7 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_MIPS_MSA_OPT > 0
#if PNG_MIPS_MSA_IMPLEMENTATION == 1
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop
@ -1323,6 +1357,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_MIPS_MMI_IMPLEMENTATION > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_POWERPC_VSX_OPT > 0
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info,
png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
@ -1355,6 +1406,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop
row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
#endif
/* Choose the best filter to use and filter the row data */
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
png_row_infop row_info),PNG_EMPTY);
@ -2094,17 +2162,27 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif
#if PNG_MIPS_MSA_OPT > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa,
#if PNG_MIPS_MSA_IMPLEMENTATION == 1
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif
# if PNG_MIPS_MMI_IMPLEMENTATION > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
# endif
# if PNG_INTEL_SSE_IMPLEMENTATION > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
# endif
#endif
#if PNG_LOONGARCH_LSX_OPT > 0
PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx,
(png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
#endif
PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr,
png_const_charp key, png_bytep new_key), PNG_EMPTY);

View File

@ -1,7 +1,7 @@
/* pngread.c - read a PNG file
*
* Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -568,7 +568,11 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
#endif
#ifdef PNG_READ_TRANSFORMS_SUPPORTED
if (png_ptr->transformations)
if (png_ptr->transformations
# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
|| png_ptr->num_palette_max >= 0
# endif
)
png_do_read_transformations(png_ptr, &row_info);
#endif
@ -785,7 +789,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Report invalid palette index; added at libng-1.5.10 */
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
png_ptr->num_palette_max > png_ptr->num_palette)
png_ptr->num_palette_max >= png_ptr->num_palette)
png_benign_error(png_ptr, "Read palette index exceeding num_palette");
#endif
@ -1049,6 +1053,8 @@ void PNGAPI
png_read_png(png_structrp png_ptr, png_inforp info_ptr,
int transforms, voidp params)
{
png_debug(1, "in png_read_png");
if (png_ptr == NULL || info_ptr == NULL)
return;

View File

@ -1,7 +1,7 @@
/* pngrtran.c - transforms the data in a row for PNG readers
*
* Copyright (c) 2018-2019 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -290,21 +290,20 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
int compose = 0;
png_fixed_point file_gamma;
png_debug(1, "in png_set_alpha_mode");
png_debug(1, "in png_set_alpha_mode_fixed");
if (png_rtran_ok(png_ptr, 0) == 0)
return;
output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
/* Validate the value to ensure it is in a reasonable range. The value
/* Validate the value to ensure it is in a reasonable range. The value
* is expected to be 1 or greater, but this range test allows for some
* viewing correction values. The intent is to weed out users of this API
* who use the inverse of the gamma value accidentally! Since some of these
* values are reasonable this may have to be changed:
* viewing correction values. The intent is to weed out the API users
* who might use the inverse of the gamma value accidentally!
*
* 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit
* gamma of 36, and its reciprocal.)
* In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate
* the optimal 16-bit gamma of 36 and its reciprocal.
*/
if (output_gamma < 1000 || output_gamma > 10000000)
png_error(png_ptr, "output gamma out of expected range");
@ -441,7 +440,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
int i;
png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
(png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
(png_alloc_size_t)num_palette);
for (i = 0; i < num_palette; i++)
png_ptr->quantize_index[i] = (png_byte)i;
}
@ -458,7 +457,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize an array to sort colors */
png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
(png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
(png_alloc_size_t)num_palette);
/* Initialize the quantize_sort array */
for (i = 0; i < num_palette; i++)
@ -592,11 +591,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize palette index arrays */
png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
(png_alloc_size_t)((png_uint_32)num_palette *
(sizeof (png_byte))));
(png_alloc_size_t)num_palette);
png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
(png_alloc_size_t)((png_uint_32)num_palette *
(sizeof (png_byte))));
(png_alloc_size_t)num_palette);
/* Initialize the sort array */
for (i = 0; i < num_palette; i++)
@ -761,12 +758,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
size_t num_entries = ((size_t)1 << total_bits);
png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
(png_alloc_size_t)(num_entries * (sizeof (png_byte))));
(png_alloc_size_t)(num_entries));
distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
(sizeof (png_byte))));
distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries);
memset(distance, 0xff, num_entries * (sizeof (png_byte)));
memset(distance, 0xff, num_entries);
for (i = 0; i < num_palette; i++)
{
@ -970,7 +966,7 @@ void PNGFAPI
png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
png_fixed_point red, png_fixed_point green)
{
png_debug(1, "in png_set_rgb_to_gray");
png_debug(1, "in png_set_rgb_to_gray_fixed");
/* Need the IHDR here because of the check on color_type below. */
/* TODO: fix this */

View File

@ -1,7 +1,7 @@
/* pngrutil.c - utilities to read a PNG file
*
* Copyright (c) 2018-2022 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -26,7 +26,7 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
if (uval > PNG_UINT_31_MAX)
png_error(png_ptr, "PNG unsigned integer out of range");
return (uval);
return uval;
}
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
@ -140,7 +140,7 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0)
{
if (num_checked < 4 &&
png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0)
png_error(png_ptr, "Not a PNG file");
else
png_error(png_ptr, "PNG file corrupted by ASCII conversion");
@ -171,7 +171,7 @@ png_read_chunk_header(png_structrp png_ptr)
/* Put the chunk name into png_ptr->chunk_name. */
png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
png_debug2(0, "Reading %lx chunk, length = %lu",
png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu",
(unsigned long)png_ptr->chunk_name, (unsigned long)length);
/* Reset the crc and run it over the chunk name. */
@ -238,10 +238,10 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
else
png_chunk_error(png_ptr, "CRC error");
return (1);
return 1;
}
return (0);
return 0;
}
/* Compare the CRC stored in the PNG file with that calculated by libpng from
@ -277,11 +277,11 @@ png_crc_error(png_structrp png_ptr)
if (need_crc != 0)
{
crc = png_get_uint_32(crc_bytes);
return ((int)(crc != png_ptr->crc));
return crc != png_ptr->crc;
}
else
return (0);
return 0;
}
#if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\
@ -421,8 +421,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
}
#if ZLIB_VERNUM >= 0x1290 && \
defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32)
#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON)
/* Turn off validation of the ADLER32 checksum in IDAT chunks */
ret = inflateValidate(&png_ptr->zstream, 0);

View File

@ -1,7 +1,7 @@
/* pngset.c - storage of image information into info struct
*
* Copyright (c) 2018-2023 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -763,11 +763,11 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
{
int i;
png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U :
(unsigned long)png_ptr->chunk_name);
png_debug1(1, "in text storage function, chunk typeid = 0x%lx",
png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name);
if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
return(0);
return 0;
/* Make sure we have enough space in the "text" array in info_struct
* to hold all of the incoming text_ptr objects. This compare can't overflow
@ -947,7 +947,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
}
return(0);
return 0;
}
#endif
@ -1063,6 +1063,8 @@ png_set_sPLT(png_const_structrp png_ptr,
{
png_sPLT_tp np;
png_debug1(1, "in %s storage function", "sPLT");
if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
return;
@ -1537,7 +1539,7 @@ void PNGAPI
png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
png_bytepp row_pointers)
{
png_debug1(1, "in %s storage function", "rows");
png_debug(1, "in png_set_rows");
if (png_ptr == NULL || info_ptr == NULL)
return;
@ -1556,6 +1558,8 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
void PNGAPI
png_set_compression_buffer_size(png_structrp png_ptr, size_t size)
{
png_debug(1, "in png_set_compression_buffer_size");
if (png_ptr == NULL)
return;
@ -1627,6 +1631,8 @@ void PNGAPI
png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
png_uint_32 user_height_max)
{
png_debug(1, "in png_set_user_limits");
/* Images with dimensions larger than these limits will be
* rejected by png_set_IHDR(). To accept any PNG datastream
* regardless of dimensions, set both limits to 0x7fffffff.
@ -1642,6 +1648,8 @@ png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max,
void PNGAPI
png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
{
png_debug(1, "in png_set_chunk_cache_max");
if (png_ptr != NULL)
png_ptr->user_chunk_cache_max = user_chunk_cache_max;
}
@ -1651,6 +1659,8 @@ void PNGAPI
png_set_chunk_malloc_max(png_structrp png_ptr,
png_alloc_size_t user_chunk_malloc_max)
{
png_debug(1, "in png_set_chunk_malloc_max");
if (png_ptr != NULL)
png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
}

View File

@ -1,7 +1,7 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
* Copyright (c) 2018 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -103,10 +103,10 @@ png_set_interlace_handling(png_structrp png_ptr)
if (png_ptr != 0 && png_ptr->interlaced != 0)
{
png_ptr->transformations |= PNG_INTERLACE;
return (7);
return 7;
}
return (1);
return 1;
}
#endif
@ -498,6 +498,8 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
png_bytep dp = row; /* destination pointer */
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
png_debug(1, "in png_do_strip_channel");
/* At the start sp will point to the first byte to copy and dp to where
* it is copied to. ep always points just beyond the end of the row, so
* the loop simply copies (channels-1) channels until sp reaches ep.
@ -698,6 +700,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
void /* PRIVATE */
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
{
png_debug(1, "in png_do_check_palette_indexes");
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
{
@ -708,7 +712,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
* forms produced on either GCC or MSVC.
*/
int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
switch (row_info->bit_depth)
{
@ -833,7 +837,7 @@ png_voidp PNGAPI
png_get_user_transform_ptr(png_const_structrp png_ptr)
{
if (png_ptr == NULL)
return (NULL);
return NULL;
return png_ptr->user_transform_ptr;
}

View File

@ -1,7 +1,7 @@
/* pngwrite.c - general routines to write a PNG file
*
* Copyright (c) 2018-2023 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -369,7 +369,8 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
png_error(png_ptr, "No IDATs written into file");
#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
if (png_ptr->num_palette_max > png_ptr->num_palette)
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
png_ptr->num_palette_max >= png_ptr->num_palette)
png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
#endif
@ -714,12 +715,12 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
/* 1.5.6: moved from png_struct to be a local structure: */
png_row_info row_info;
if (png_ptr == NULL)
return;
png_debug2(1, "in png_write_row (row %u, pass %d)",
png_ptr->row_number, png_ptr->pass);
if (png_ptr == NULL)
return;
/* Initialize transformations and other stuff if first time */
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{
@ -1210,6 +1211,8 @@ png_set_compression_strategy(png_structrp png_ptr, int strategy)
void PNGAPI
png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
{
png_debug(1, "in png_set_compression_window_bits");
if (png_ptr == NULL)
return;
@ -1293,6 +1296,8 @@ png_set_text_compression_strategy(png_structrp png_ptr, int strategy)
void PNGAPI
png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)
{
png_debug(1, "in png_set_text_compression_window_bits");
if (png_ptr == NULL)
return;
@ -1330,6 +1335,8 @@ png_set_text_compression_method(png_structrp png_ptr, int method)
void PNGAPI
png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
{
png_debug(1, "in png_set_write_status_fn");
if (png_ptr == NULL)
return;
@ -1357,6 +1364,8 @@ void PNGAPI
png_write_png(png_structrp png_ptr, png_inforp info_ptr,
int transforms, voidp params)
{
png_debug(1, "in png_write_png");
if (png_ptr == NULL || info_ptr == NULL)
return;

View File

@ -1,7 +1,7 @@
/* pngwutil.c - utilities to write a PNG file
*
* Copyright (c) 2018-2022 Cosmin Truta
* Copyright (c) 2018-2024 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
* Copyright (c) 1996-1997 Andreas Dilger
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@ -2311,7 +2311,7 @@ png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp,
break;
}
return (sum);
return sum;
}
static void /* PRIVATE */
@ -2361,7 +2361,7 @@ png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins)
break;
}
return (sum);
return sum;
}
static void /* PRIVATE */
png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes)
@ -2417,7 +2417,7 @@ png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp,
break;
}
return (sum);
return sum;
}
static void /* PRIVATE */
png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp,
@ -2500,7 +2500,7 @@ png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp,
break;
}
return (sum);
return sum;
}
static void /* PRIVATE */
png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp,

View File

@ -6,13 +6,13 @@
"Description": "libpng is the official PNG reference library.",
"Homepage": "http://www.libpng.org/pub/png/libpng.html",
"Version": "1.6.40",
"DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.40.tar.xz",
"Version": "1.6.43",
"DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.43.tar.xz",
"License": "libpng License and PNG Reference Library version 2",
"LicenseId": "Libpng AND libpng-2.0",
"LicenseFile": "LICENSE",
"Copyright": "Copyright (c) 1995-2023 The PNG Reference Library Authors
Copyright (c) 2000-2023 Cosmin Truta
"Copyright": "Copyright (c) 1995-2024 The PNG Reference Library Authors
Copyright (c) 2000-2024 Cosmin Truta
Copyright (c) 1998-2018 Glenn Randers-Pehrson
Copyright (c) 1996-1997 Andreas Dilger
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.

View File

@ -1,40 +0,0 @@
diff --git a/src/3rdparty/md4c/md4c.c b/src/3rdparty/md4c/md4c.c
index 6aeef112e5..9d0d1b7d7b 100644
--- a/src/3rdparty/md4c/md4c.c
+++ b/src/3rdparty/md4c/md4c.c
@@ -916,7 +916,7 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines,
}
if(off >= end) {
- *p_size = ptr - buffer;
+ *p_size = (MD_SIZE)(ptr - buffer);
return;
}
@@ -2229,7 +2229,7 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines,
if(beg_line != end_line) {
MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line,
- n_lines - (beg_line - lines), _T(' '), &label, &label_size));
+ (int)(n_lines - (beg_line - lines)), _T(' '), &label, &label_size));
} else {
label = (CHAR*) STR(beg);
label_size = end - beg;
@@ -4265,7 +4265,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines)
MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'),
(opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A),
STR(dest_mark->beg), dest_mark->end - dest_mark->beg, FALSE,
- md_mark_get_ptr(ctx, title_mark - ctx->marks), title_mark->prev));
+ md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), title_mark->prev));
/* link/image closer may span multiple lines. */
if(mark->ch == ']') {
@@ -4908,7 +4908,7 @@ md_push_block_bytes(MD_CTX* ctx, int n_bytes)
/* Fix the ->current_block after the reallocation. */
if(ctx->current_block != NULL) {
- OFF off_current_block = (char*) ctx->current_block - (char*) ctx->block_bytes;
+ OFF off_current_block = (OFF)((char*) ctx->current_block - (char*) ctx->block_bytes);
ctx->current_block = (MD_BLOCK*) ((char*) new_block_bytes + off_current_block);
}

View File

@ -1,7 +1,7 @@
# The MIT License (MIT)
Copyright © 2016-2020 Martin Mitáš
Copyright © 2016-2024 Martin Mitáš
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the “Software”),

1498
src/3rdparty/md4c/md4c.c vendored

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* MD4C: Markdown parser for C
* (http://github.com/mity/md4c)
*
* Copyright (c) 2016-2020 Martin Mitas
* Copyright (c) 2016-2024 Martin Mitáš
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@ -284,6 +284,7 @@ typedef struct MD_BLOCK_TD_DETAIL {
typedef struct MD_SPAN_A_DETAIL {
MD_ATTRIBUTE href;
MD_ATTRIBUTE title;
int is_autolink; /* nonzero if this is an autolink */
} MD_SPAN_A_DETAIL;
/* Detailed info for MD_SPAN_IMG. */
@ -316,6 +317,7 @@ typedef struct MD_SPAN_WIKILINK {
#define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */
#define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */
#define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */
#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */
#define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS)
#define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS)

View File

@ -9,7 +9,7 @@
"License": "MIT License",
"LicenseId": "MIT",
"LicenseFile": "LICENSE.md",
"Version": "0.4.8",
"DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.4.8",
"Copyright": "Copyright © 2016-2020 Martin Mitáš"
"Version": "0.5.2",
"DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.5.2",
"Copyright": "Copyright © 2016-2024 Martin Mitáš"
}

View File

@ -8,7 +8,7 @@ Email domain: gmail.com
Retired from University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2022 University of Cambridge
Copyright (c) 1997-2024 University of Cambridge
All rights reserved
@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
Copyright(c) 2010-2022 Zoltan Herczeg
Copyright(c) 2010-2024 Zoltan Herczeg
All rights reserved.
@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
Copyright(c) 2009-2022 Zoltan Herczeg
Copyright(c) 2009-2024 Zoltan Herczeg
All rights reserved.
####

View File

@ -12,6 +12,7 @@ qt_internal_add_3rdparty_library(BundledPcre2
src/pcre2.h
src/pcre2_auto_possess.c
src/pcre2_chartables.c
src/pcre2_chkdint.c
src/pcre2_compile.c
src/pcre2_config.c
src/pcre2_context.c

View File

@ -26,7 +26,7 @@ Email domain: gmail.com
Retired from University of Cambridge Computing Service,
Cambridge, England.
Copyright (c) 1997-2022 University of Cambridge
Copyright (c) 1997-2024 University of Cambridge
All rights reserved.
@ -37,7 +37,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2010-2022 Zoltan Herczeg
Copyright(c) 2010-2024 Zoltan Herczeg
All rights reserved.
@ -48,7 +48,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
Copyright(c) 2009-2022 Zoltan Herczeg
Copyright(c) 2009-2024 Zoltan Herczeg
All rights reserved.

View File

@ -83,6 +83,7 @@ FILES="
LICENCE
src/pcre2_auto_possess.c
src/pcre2_chkdint.c
src/pcre2_compile.c
src/pcre2_config.c
src/pcre2_context.c
@ -115,9 +116,9 @@ FILES="
src/pcre2_ucptables.c
src/pcre2_valid_utf.c
src/pcre2_xclass.c
src/sljit/sljitConfigCPU.h
src/sljit/sljitConfig.h
src/sljit/sljitConfigInternal.h
src/sljit/sljitExecAllocator.c
src/sljit/sljitLir.c
src/sljit/sljitLir.h
src/sljit/sljitNativeARM_32.c
@ -136,9 +137,15 @@ FILES="
src/sljit/sljitNativeX86_32.c
src/sljit/sljitNativeX86_64.c
src/sljit/sljitNativeX86_common.c
src/sljit/sljitProtExecAllocator.c
src/sljit/sljitUtils.c
src/sljit/sljitWXExecAllocator.c
src/sljit/allocator_src/sljitExecAllocatorPosix.c
src/sljit/allocator_src/sljitProtExecAllocatorPosix.c
src/sljit/allocator_src/sljitWXExecAllocatorPosix.c
src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c
src/sljit/allocator_src/sljitExecAllocatorWindows.c
src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c
src/sljit/allocator_src/sljitExecAllocatorApple.c
src/sljit/allocator_src/sljitWXExecAllocatorWindows.c
src/sljit/allocator_src/sljitExecAllocatorCore.c
"
for i in $FILES; do

View File

@ -7,13 +7,13 @@
"Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.",
"Homepage": "http://www.pcre.org/",
"Version": "10.42",
"DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2",
"License": "BSD 3-clause \"New\" or \"Revised\" License",
"LicenseId": "BSD-3-Clause",
"Version": "10.43",
"DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.tar.bz2",
"License": "BSD 3-clause \"New\" or \"Revised\" License with PCRE2 binary-like Packages Exception",
"LicenseId": "LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception",
"LicenseFile": "LICENCE",
"Copyright": "Copyright (c) 1997-2022 University of Cambridge
Copyright (c) 2010-2022 Zoltan Herczeg"
"Copyright": "Copyright (c) 1997-2024 University of Cambridge
Copyright (c) 2010-2024 Zoltan Herczeg"
},
{
"Id": "pcre2-sljit",
@ -24,11 +24,11 @@ Copyright (c) 2010-2022 Zoltan Herczeg"
"Path": "src/sljit",
"Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.",
"Homepage": "http://www.pcre.org/",
"Version": "10.42",
"DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2",
"Version": "10.43",
"DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.tar.bz2",
"License": "BSD 2-clause \"Simplified\" License",
"LicenseId": "BSD-2-Clause",
"LicenseFile": "LICENCE-SLJIT",
"Copyright": "Copyright (c) 2009-2022 Zoltan Herczeg"
"Copyright": "Copyright (c) 2009-2024 Zoltan Herczeg"
}
]

View File

@ -14,13 +14,15 @@
#define MAX_NAME_SIZE 32
#define NEWLINE_DEFAULT 2
#define PARENS_NEST_LIMIT 250
#define MAX_VARLOOKBEHIND 255
#define SUPPORT_UNICODE
#define PCRE2_EXPORT
/*
man 3 pcre2jit for a list of supported platforms;
as PCRE2 10.22, stable JIT support is available for:
- ARM 32-bit (v5, v7, and Thumb2)
as PCRE2 10.43, stable JIT support is available for:
- ARM 32-bit (v7 and Thumb2)
- ARM 64-bit
- Intel x86 32-bit and 64-bit
- MIPS 32-bit and 64-bit
@ -32,7 +34,7 @@
#if !defined(PCRE2_DISABLE_JIT) && (\
/* ARM */ \
(defined(__GNUC__) \
&& (defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__))) \
&& (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__aarch64__))) \
/* x86 32/64 */ \
|| defined(__i386) || defined(__i386__) || defined(_M_IX86) \
|| defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) \

View File

@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, second API, to be
#included by applications that call PCRE2 functions.
Copyright (c) 2016-2021 University of Cambridge
Copyright (c) 2016-2024 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE2_MAJOR 10
#define PCRE2_MINOR 42
#define PCRE2_MINOR 43
#define PCRE2_PRERELEASE
#define PCRE2_DATE 2022-12-11
#define PCRE2_DATE 2024-02-16
/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE2, the appropriate
@ -153,6 +153,12 @@ D is inspected during pcre2_dfa_match() execution
#define PCRE2_EXTRA_ESCAPED_CR_IS_LF 0x00000010u /* C */
#define PCRE2_EXTRA_ALT_BSUX 0x00000020u /* C */
#define PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK 0x00000040u /* C */
#define PCRE2_EXTRA_CASELESS_RESTRICT 0x00000080u /* C */
#define PCRE2_EXTRA_ASCII_BSD 0x00000100u /* C */
#define PCRE2_EXTRA_ASCII_BSS 0x00000200u /* C */
#define PCRE2_EXTRA_ASCII_BSW 0x00000400u /* C */
#define PCRE2_EXTRA_ASCII_POSIX 0x00000800u /* C */
#define PCRE2_EXTRA_ASCII_DIGIT 0x00001000u /* C */
/* These are for pcre2_jit_compile(). */
@ -180,11 +186,12 @@ pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */
#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u /* pcre2_substitute() only */
#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u /* pcre2_substitute() only */
#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u /* pcre2_substitute() only */
#define PCRE2_NO_JIT 0x00002000u /* Not for pcre2_dfa_match() */
#define PCRE2_NO_JIT 0x00002000u /* not for pcre2_dfa_match() */
#define PCRE2_COPY_MATCHED_SUBJECT 0x00004000u
#define PCRE2_SUBSTITUTE_LITERAL 0x00008000u /* pcre2_substitute() only */
#define PCRE2_SUBSTITUTE_MATCHED 0x00010000u /* pcre2_substitute() only */
#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u /* pcre2_substitute() only */
#define PCRE2_DISABLE_RECURSELOOP_CHECK 0x00040000u /* not for pcre2_dfa_match() or pcre2_jit_match() */
/* Options for pcre2_pattern_convert(). */
@ -399,6 +406,7 @@ released, the numbers must not be changed. */
#define PCRE2_ERROR_CONVERT_SYNTAX (-64)
#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65)
#define PCRE2_ERROR_DFA_UINVALID_UTF (-66)
#define PCRE2_ERROR_INVALIDOFFSET (-67)
/* Request types for pcre2_pattern_info() */
@ -575,7 +583,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *);
PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \
pcre2_general_context_copy(pcre2_general_context *); \
PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \
pcre2_general_context_create(void *(*)(PCRE2_SIZE, void *), \
pcre2_general_context_create(void *(*)(size_t, void *), \
void (*)(void *, void *), void *); \
PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
pcre2_general_context_free(pcre2_general_context *);
@ -595,6 +603,8 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_max_varlookbehind(pcre2_compile_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_newline(pcre2_compile_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
@ -628,7 +638,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_recursion_memory_management(pcre2_match_context *, \
void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *);
void *(*)(size_t, void *), void (*)(void *, void *), void *);
#define PCRE2_CONVERT_CONTEXT_FUNCTIONS \
PCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \
@ -687,6 +697,8 @@ PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \
pcre2_get_mark(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
pcre2_get_match_data_size(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
pcre2_get_match_data_heapframes_size(pcre2_match_data *); \
PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \
pcre2_get_ovector_count(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SIZE *PCRE2_CALL_CONVENTION \
@ -722,7 +734,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \
PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
pcre2_substring_list_free(PCRE2_SPTR *); \
pcre2_substring_list_free(PCRE2_UCHAR **); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **);
@ -771,7 +783,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
pcre2_jit_free_unused_memory(pcre2_general_context *); \
PCRE2_EXP_DECL pcre2_jit_stack *PCRE2_CALL_CONVENTION \
pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, pcre2_general_context *); \
pcre2_jit_stack_create(size_t, size_t, pcre2_general_context *); \
PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \
PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
@ -851,6 +863,7 @@ pcre2_compile are called by application code. */
#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_)
#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_)
#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_)
#define pcre2_get_match_data_heapframes_size PCRE2_SUFFIX(pcre2_get_match_data_heapframes_size_)
#define pcre2_get_match_data_size PCRE2_SUFFIX(pcre2_get_match_data_size_)
#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_)
#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_)
@ -886,6 +899,7 @@ pcre2_compile are called by application code. */
#define pcre2_set_glob_separator PCRE2_SUFFIX(pcre2_set_glob_separator_)
#define pcre2_set_heap_limit PCRE2_SUFFIX(pcre2_set_heap_limit_)
#define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_)
#define pcre2_set_max_varlookbehind PCRE2_SUFFIX(pcre2_set_max_varlookbehind_)
#define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_)
#define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_)
#define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)

View File

@ -560,6 +560,8 @@ matches to an empty string (also represented by a non-zero value). */
for(;;)
{
PCRE2_SPTR bracode;
/* All operations move the code pointer forward.
Therefore infinite recursions are not possible. */
@ -617,7 +619,8 @@ for(;;)
recursions. (This could be improved by keeping a list of group numbers that
are called by recursion.) */
switch(*(code - GET(code, 1)))
bracode = code - GET(code, 1);
switch(*bracode)
{
case OP_CBRA:
case OP_SCBRA:
@ -636,16 +639,19 @@ for(;;)
break;
/* Atomic sub-patterns and assertions can always auto-possessify their
last iterator. However, if the group was entered as a result of checking
a previous iterator, this is not possible. */
last iterator except for variable length lookbehinds. However, if the
group was entered as a result of checking a previous iterator, this is
not possible. */
case OP_ASSERT:
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
case OP_ONCE:
return !entered_a_group;
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
return (bracode[1+LINK_SIZE] == OP_VREVERSE)? FALSE : !entered_a_group;
/* Non-atomic assertions - don't possessify last iterator. This needs
more thought. */

View File

@ -5,7 +5,8 @@
/* This file was automatically written by the pcre2_dftables auxiliary
program. It contains character tables that are used when no external
tables are passed to PCRE2 by the application that calls it. The tables
are used only for characters whose code values are less than 256. */
are used only for characters whose code values are less than 256, and
only relevant if not in UCP mode. */
/* This set of tables was written in the C locale. */
@ -18,13 +19,6 @@ PCRE2 is configured with --enable-rebuild-chartables. However, you can run
pcre2_dftables manually with the -L option to build tables using the LC_ALL
locale. */
/* The following #include is present because without it gcc 4.x may remove
the array definition from the final binary if PCRE2 is built into a static
library and dead code stripping is activated. This leads to link errors.
Pulling in the header ensures that the array gets flagged as "someone
outside this compilation unit might reference this" and so it will always
be supplied to the linker. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -163,7 +157,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */
0x02 letter
0x04 lower case letter
0x08 decimal digit
0x10 alphanumeric or '_'
0x10 word (alphanumeric or '_')
*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */

96
src/3rdparty/pcre2/src/pcre2_chkdint.c vendored Normal file
View File

@ -0,0 +1,96 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Copyright (c) 2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
/* This file contains functions to implement checked integer operation */
#ifndef PCRE2_PCRE2TEST
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcre2_internal.h"
#endif
/*************************************************
* Checked Integer Multiplication *
*************************************************/
/*
Arguments:
r A pointer to PCRE2_SIZE to store the answer
a, b Two integers
Returns: Bool indicating if the operation overflows
It is modeled after C23's <stdckdint.h> interface
The INT64_OR_DOUBLE type is a 64-bit integer type when available,
otherwise double. */
BOOL
PRIV(ckd_smul)(PCRE2_SIZE *r, int a, int b)
{
#ifdef HAVE_BUILTIN_MUL_OVERFLOW
PCRE2_SIZE m;
if (__builtin_mul_overflow(a, b, &m)) return TRUE;
*r = m;
#else
INT64_OR_DOUBLE m;
#ifdef PCRE2_DEBUG
if (a < 0 || b < 0) abort();
#endif
m = (INT64_OR_DOUBLE)a * (INT64_OR_DOUBLE)b;
#if defined INT64_MAX || defined int64_t
if (sizeof(m) > sizeof(*r) && m > (INT64_OR_DOUBLE)PCRE2_SIZE_MAX) return TRUE;
*r = (PCRE2_SIZE)m;
#else
if (m > PCRE2_SIZE_MAX) return TRUE;
*r = m;
#endif
#endif
return FALSE;
}
/* End of pcre_chkdint.c */

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2022 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -139,7 +139,9 @@ const pcre2_compile_context PRIV(default_compile_context) = {
BSR_DEFAULT, /* Backslash R default */
NEWLINE_DEFAULT, /* Newline convention */
PARENS_NEST_LIMIT, /* As it says */
0 }; /* Extra options */
0, /* Extra options */
MAX_VARLOOKBEHIND /* As it says */
};
/* The create function copies the default into the new memory, but must
override the default memory handling functions if a gcontext was provided. */
@ -228,49 +230,48 @@ return ccontext;
PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
pcre2_general_context_copy(pcre2_general_context *gcontext)
{
pcre2_general_context *new =
pcre2_general_context *newcontext =
gcontext->memctl.malloc(sizeof(pcre2_real_general_context),
gcontext->memctl.memory_data);
if (new == NULL) return NULL;
memcpy(new, gcontext, sizeof(pcre2_real_general_context));
return new;
if (newcontext == NULL) return NULL;
memcpy(newcontext, gcontext, sizeof(pcre2_real_general_context));
return newcontext;
}
PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION
pcre2_compile_context_copy(pcre2_compile_context *ccontext)
{
pcre2_compile_context *new =
pcre2_compile_context *newcontext =
ccontext->memctl.malloc(sizeof(pcre2_real_compile_context),
ccontext->memctl.memory_data);
if (new == NULL) return NULL;
memcpy(new, ccontext, sizeof(pcre2_real_compile_context));
return new;
if (newcontext == NULL) return NULL;
memcpy(newcontext, ccontext, sizeof(pcre2_real_compile_context));
return newcontext;
}
PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION
pcre2_match_context_copy(pcre2_match_context *mcontext)
{
pcre2_match_context *new =
pcre2_match_context *newcontext =
mcontext->memctl.malloc(sizeof(pcre2_real_match_context),
mcontext->memctl.memory_data);
if (new == NULL) return NULL;
memcpy(new, mcontext, sizeof(pcre2_real_match_context));
return new;
if (newcontext == NULL) return NULL;
memcpy(newcontext, mcontext, sizeof(pcre2_real_match_context));
return newcontext;
}
PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION
pcre2_convert_context_copy(pcre2_convert_context *ccontext)
{
pcre2_convert_context *new =
pcre2_convert_context *newcontext =
ccontext->memctl.malloc(sizeof(pcre2_real_convert_context),
ccontext->memctl.memory_data);
if (new == NULL) return NULL;
memcpy(new, ccontext, sizeof(pcre2_real_convert_context));
return new;
if (newcontext == NULL) return NULL;
memcpy(newcontext, ccontext, sizeof(pcre2_real_convert_context));
return newcontext;
}
@ -370,6 +371,13 @@ switch(newline)
}
}
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_set_max_varlookbehind(pcre2_compile_context *ccontext, uint32_t limit)
{
ccontext->max_varlookbehind = limit;
return 0;
}
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit)
{

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2022 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -168,7 +168,7 @@ static const uint8_t coptable[] = {
0, /* KetRmax */
0, /* KetRmin */
0, /* KetRpos */
0, /* Reverse */
0, 0, /* Reverse, Vreverse */
0, /* Assert */
0, /* Assert not */
0, /* Assert behind */
@ -187,7 +187,8 @@ static const uint8_t coptable[] = {
0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
0, 0, /* COMMIT, COMMIT_ARG */
0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */
0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */
0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */
0, 0 /* \B and \b in UCP mode */
};
/* This table identifies those opcodes that inspect a character. It is used to
@ -245,7 +246,7 @@ static const uint8_t poptable[] = {
0, /* KetRmax */
0, /* KetRmin */
0, /* KetRpos */
0, /* Reverse */
0, 0, /* Reverse, Vreverse */
0, /* Assert */
0, /* Assert not */
0, /* Assert behind */
@ -264,7 +265,8 @@ static const uint8_t poptable[] = {
0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */
0, 0, /* COMMIT, COMMIT_ARG */
0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */
0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */
0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */
1, 1 /* \B and \b in UCP mode */
};
/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
@ -426,7 +428,7 @@ overflow. */
else
{
uint32_t newsize = (rws->size >= UINT32_MAX/2)? UINT32_MAX/2 : rws->size * 2;
uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2;
uint32_t newsizeK = newsize/(1024/sizeof(int));
if (newsizeK + mb->heap_used > mb->heap_limit)
@ -589,7 +591,7 @@ if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)
end_code = this_start_code;
do
{
size_t back = (size_t)GET(end_code, 2+LINK_SIZE);
size_t back = (size_t)GET2(end_code, 2+LINK_SIZE);
if (back > max_back) max_back = back;
end_code += GET(end_code, 1);
}
@ -633,8 +635,8 @@ if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT)
end_code = this_start_code;
do
{
uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + LINK_SIZE : 0;
size_t back = (revlen == 0)? 0 : (size_t)GET(end_code, 2+LINK_SIZE);
uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + IMM2_SIZE : 0;
size_t back = (revlen == 0)? 0 : (size_t)GET2(end_code, 2+LINK_SIZE);
if (back <= gone_back)
{
int bstate = (int)(end_code - start_code + 1 + LINK_SIZE + revlen);
@ -1100,6 +1102,8 @@ for (;;)
/*-----------------------------------------------------------------*/
case OP_WORD_BOUNDARY:
case OP_NOT_WORD_BOUNDARY:
case OP_NOT_UCP_WORD_BOUNDARY:
case OP_UCP_WORD_BOUNDARY:
{
int left_word, right_word;
@ -1112,13 +1116,13 @@ for (;;)
#endif
GETCHARTEST(d, temp);
#ifdef SUPPORT_UNICODE
if ((mb->poptions & PCRE2_UCP) != 0)
if (codevalue == OP_UCP_WORD_BOUNDARY ||
codevalue == OP_NOT_UCP_WORD_BOUNDARY)
{
if (d == '_') left_word = TRUE; else
{
uint32_t cat = UCD_CATEGORY(d);
left_word = (cat == ucp_L || cat == ucp_N);
}
int chartype = UCD_CHARTYPE(d);
int category = PRIV(ucp_gentype)[chartype];
left_word = (category == ucp_L || category == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc);
}
else
#endif
@ -1137,13 +1141,13 @@ for (;;)
mb->last_used_ptr = temp;
}
#ifdef SUPPORT_UNICODE
if ((mb->poptions & PCRE2_UCP) != 0)
if (codevalue == OP_UCP_WORD_BOUNDARY ||
codevalue == OP_NOT_UCP_WORD_BOUNDARY)
{
if (c == '_') right_word = TRUE; else
{
uint32_t cat = UCD_CATEGORY(c);
right_word = (cat == ucp_L || cat == ucp_N);
}
int chartype = UCD_CHARTYPE(c);
int category = PRIV(ucp_gentype)[chartype];
right_word = (category == ucp_L || category == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc);
}
else
#endif
@ -1151,7 +1155,9 @@ for (;;)
}
else right_word = FALSE;
if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
if ((left_word == right_word) ==
(codevalue == OP_NOT_WORD_BOUNDARY ||
codevalue == OP_NOT_UCP_WORD_BOUNDARY))
{ ADD_ACTIVE(state_offset + 1, 0); }
}
break;
@ -1168,6 +1174,7 @@ for (;;)
if (clen > 0)
{
BOOL OK;
int chartype;
const uint32_t *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[1])
@ -1177,8 +1184,9 @@ for (;;)
break;
case PT_LAMP:
OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
prop->chartype == ucp_Lt;
chartype = prop->chartype;
OK = chartype == ucp_Lu || chartype == ucp_Ll ||
chartype == ucp_Lt;
break;
case PT_GC:
@ -1201,8 +1209,9 @@ for (;;)
/* These are specials for combination cases. */
case PT_ALNUM:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N;
break;
/* Perl space used to exclude VT, but from Perl 5.18 it is included,
@ -1225,12 +1234,20 @@ for (;;)
break;
case PT_WORD:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc;
break;
case PT_CLIST:
#if PCRE2_CODE_UNIT_WIDTH == 32
if (c > MAX_UTF_CODE_POINT)
{
OK = FALSE;
break;
}
#endif
cp = PRIV(ucd_caseless_sets) + code[2];
for (;;)
{
@ -1440,6 +1457,7 @@ for (;;)
if (clen > 0)
{
BOOL OK;
int chartype;
const uint32_t *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[2])
@ -1449,8 +1467,8 @@ for (;;)
break;
case PT_LAMP:
OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
prop->chartype == ucp_Lt;
chartype = prop->chartype;
OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
break;
case PT_GC:
@ -1473,8 +1491,9 @@ for (;;)
/* These are specials for combination cases. */
case PT_ALNUM:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N;
break;
/* Perl space used to exclude VT, but from Perl 5.18 it is included,
@ -1497,12 +1516,20 @@ for (;;)
break;
case PT_WORD:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc;
break;
case PT_CLIST:
#if PCRE2_CODE_UNIT_WIDTH == 32
if (c > MAX_UTF_CODE_POINT)
{
OK = FALSE;
break;
}
#endif
cp = PRIV(ucd_caseless_sets) + code[3];
for (;;)
{
@ -1695,6 +1722,7 @@ for (;;)
if (clen > 0)
{
BOOL OK;
int chartype;
const uint32_t *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[2])
@ -1704,8 +1732,8 @@ for (;;)
break;
case PT_LAMP:
OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
prop->chartype == ucp_Lt;
chartype = prop->chartype;
OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
break;
case PT_GC:
@ -1728,8 +1756,9 @@ for (;;)
/* These are specials for combination cases. */
case PT_ALNUM:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N;
break;
/* Perl space used to exclude VT, but from Perl 5.18 it is included,
@ -1752,12 +1781,20 @@ for (;;)
break;
case PT_WORD:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc;
break;
case PT_CLIST:
#if PCRE2_CODE_UNIT_WIDTH == 32
if (c > MAX_UTF_CODE_POINT)
{
OK = FALSE;
break;
}
#endif
cp = PRIV(ucd_caseless_sets) + code[3];
for (;;)
{
@ -1975,6 +2012,7 @@ for (;;)
if (clen > 0)
{
BOOL OK;
int chartype;
const uint32_t *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[1 + IMM2_SIZE + 1])
@ -1984,8 +2022,8 @@ for (;;)
break;
case PT_LAMP:
OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
prop->chartype == ucp_Lt;
chartype = prop->chartype;
OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
break;
case PT_GC:
@ -2009,8 +2047,9 @@ for (;;)
/* These are specials for combination cases. */
case PT_ALNUM:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N;
break;
/* Perl space used to exclude VT, but from Perl 5.18 it is included,
@ -2033,12 +2072,20 @@ for (;;)
break;
case PT_WORD:
OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
c == CHAR_UNDERSCORE;
chartype = prop->chartype;
OK = PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc;
break;
case PT_CLIST:
#if PCRE2_CODE_UNIT_WIDTH == 32
if (c > MAX_UTF_CODE_POINT)
{
OK = FALSE;
break;
}
#endif
cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
for (;;)
{
@ -2894,7 +2941,6 @@ for (;;)
int *local_workspace;
PCRE2_SIZE *local_offsets;
RWS_anchor *rws = (RWS_anchor *)RWS;
dfa_recursion_info *ri;
PCRE2_SPTR callpat = start_code + GET(code, 1);
uint32_t recno = (callpat == mb->start_code)? 0 :
GET2(callpat, 1 + LINK_SIZE);
@ -2911,18 +2957,24 @@ for (;;)
rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE;
/* Check for repeating a recursion without advancing the subject
pointer. This should catch convoluted mutual recursions. (Some simple
cases are caught at compile time.) */
pointer or last used character. This should catch convoluted mutual
recursions. (Some simple cases are caught at compile time.) */
for (ri = mb->recursive; ri != NULL; ri = ri->prevrec)
if (recno == ri->group_num && ptr == ri->subject_position)
for (dfa_recursion_info *ri = mb->recursive;
ri != NULL;
ri = ri->prevrec)
{
if (recno == ri->group_num && ptr == ri->subject_position &&
mb->last_used_ptr == ri->last_used_ptr)
return PCRE2_ERROR_RECURSELOOP;
}
/* Remember this recursion and where we started it so as to
catch infinite loops. */
new_recursive.group_num = recno;
new_recursive.subject_position = ptr;
new_recursive.last_used_ptr = mb->last_used_ptr;
new_recursive.prevrec = mb->recursive;
mb->recursive = &new_recursive;
@ -3424,7 +3476,7 @@ anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 ||
where to start. */
startline = (re->flags & PCRE2_STARTLINE) != 0;
firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0;
bumpalong_limit = end_subject;
/* Initialize and set up the fixed fields in the callout block, with a pointer
@ -3994,8 +4046,9 @@ for (;;)
match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);
match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);
}
match_data->subject_length = length;
match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject);
match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject);
match_data->startchar = (PCRE2_SIZE)(start_match - subject);
match_data->rc = rc;

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2021 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -82,7 +82,7 @@ static const unsigned char compile_error_texts[] =
"missing closing parenthesis\0"
/* 15 */
"reference to non-existent subpattern\0"
"pattern passed as NULL\0"
"pattern passed as NULL with non-zero length\0"
"unrecognised compile-time option bit(s)\0"
"missing ) after (?# comment\0"
"parentheses are too deeply nested\0"
@ -93,7 +93,7 @@ static const unsigned char compile_error_texts[] =
"internal error: code overflow\0"
"missing closing parenthesis for condition\0"
/* 25 */
"lookbehind assertion is not fixed length\0"
"length of lookbehind assertion is not limited\0"
"a relative value of zero is not allowed\0"
"conditional subpattern contains more than two branches\0"
"assertion expected after (?( or (?(?C)\0"
@ -187,6 +187,8 @@ static const unsigned char compile_error_texts[] =
"too many capturing groups (maximum 65535)\0"
"atomic assertion expected after (?( or (?(?C)\0"
"\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\0"
/* 100 */
"branch too long in variable-length lookbehind assertion\0"
;
/* Match-time and UTF error texts are in the same format. */
@ -272,6 +274,7 @@ static const unsigned char match_error_texts[] =
/* 65 */
"internal error - duplicate substitution match\0"
"PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0"
"INTERNAL ERROR: invalid substring offset\0"
;

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2018 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -41,9 +41,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* This module contains a single function that scans through a compiled pattern
until it finds a capturing bracket with the given number, or, if the number is
negative, an instance of OP_REVERSE for a lookbehind. The function is called
from pcre2_compile.c and also from pcre2_study.c when finding the minimum
matching length. */
negative, an instance of OP_REVERSE or OP_VREVERSE for a lookbehind. The
function is called from pcre2_compile.c and also from pcre2_study.c when
finding the minimum matching length. */
#ifdef HAVE_CONFIG_H
@ -85,7 +85,7 @@ for (;;)
/* Handle lookbehind */
else if (c == OP_REVERSE)
else if (c == OP_REVERSE || c == OP_VREVERSE)
{
if (number < 0) return (PCRE2_UCHAR *)code;
code += PRIV(OP_lengths)[c];

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2022 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -51,6 +51,24 @@ pcre2test.c with CODE_UNIT_WIDTH == 0. */
#error The use of both EBCDIC and SUPPORT_UNICODE is not supported.
#endif
/* When compiling one of the libraries, the value of PCRE2_CODE_UNIT_WIDTH must
be 8, 16, or 32. AutoTools and CMake ensure that this is always the case, but
other other building methods may not, so here is a check. It is cut out when
building pcre2test, bcause that sets the value to zero. No other source should
be including this file. There is no explicit way of forcing a compile to be
abandoned, but trying to include a non-existent file seems cleanest. Otherwise
there will be many irrelevant consequential errors. */
#if (!defined PCRE2_BUILDING_PCRE2TEST && !defined PCRE2_DFTABLES) && \
(!defined PCRE2_CODE_UNIT_WIDTH || \
(PCRE2_CODE_UNIT_WIDTH != 8 && \
PCRE2_CODE_UNIT_WIDTH != 16 && \
PCRE2_CODE_UNIT_WIDTH != 32))
#error PCRE2_CODE_UNIT_WIDTH must be defined as 8, 16, or 32.
#include <AbandonCompile>
#endif
/* Standard C headers */
#include <ctype.h>
@ -119,20 +137,20 @@ only if it is not already set. */
#ifndef PCRE2_EXP_DECL
# ifdef _WIN32
# ifndef PCRE2_STATIC
# define PCRE2_EXP_DECL extern __declspec(dllexport)
# define PCRE2_EXP_DEFN __declspec(dllexport)
# define PCRE2_EXP_DECL extern __declspec(dllexport)
# define PCRE2_EXP_DEFN __declspec(dllexport)
# else
# define PCRE2_EXP_DECL extern
# define PCRE2_EXP_DECL extern PCRE2_EXPORT
# define PCRE2_EXP_DEFN
# endif
# else
# ifdef __cplusplus
# define PCRE2_EXP_DECL extern "C"
# define PCRE2_EXP_DECL extern "C" PCRE2_EXPORT
# else
# define PCRE2_EXP_DECL extern
# define PCRE2_EXP_DECL extern PCRE2_EXPORT
# endif
# ifndef PCRE2_EXP_DEFN
# define PCRE2_EXP_DEFN PCRE2_EXP_DECL
# define PCRE2_EXP_DEFN PCRE2_EXP_DECL
# endif
# endif
#endif
@ -156,8 +174,8 @@ pcre2_match() because of the way it backtracks. */
#define PCRE2_SPTR CUSTOM_SUBJECT_PTR
#endif
/* When checking for integer overflow in pcre2_compile(), we need to handle
large integers. If a 64-bit integer type is available, we can use that.
/* When checking for integer overflow, we need to handle large integers.
If a 64-bit integer type is available, we can use that.
Otherwise we have to cast to double, which of course requires floating point
arithmetic. Handle this by defining a macro for the appropriate type. */
@ -1281,7 +1299,7 @@ match. */
#define PT_ALNUM 6 /* Alphanumeric - the union of L and N */
#define PT_SPACE 7 /* Perl space - general category Z plus 9,10,12,13 */
#define PT_PXSPACE 8 /* POSIX space - Z plus 9,10,11,12,13 */
#define PT_WORD 9 /* Word - L plus N plus underscore */
#define PT_WORD 9 /* Word - L, N, Mn, or Pc */
#define PT_CLIST 10 /* Pseudo-property: match character list */
#define PT_UCNC 11 /* Universal Character nameable character */
#define PT_BIDICL 12 /* Specified bidi class */
@ -1297,6 +1315,7 @@ table. */
#define PT_PXGRAPH 14 /* [:graph:] - characters that mark the paper */
#define PT_PXPRINT 15 /* [:print:] - [:graph:] plus non-control spaces */
#define PT_PXPUNCT 16 /* [:punct:] - punctuation characters */
#define PT_PXXDIGIT 17 /* [:xdigit:] - hex digits */
/* This value is used when parsing \p and \P escapes to indicate that neither
\p{script:...} nor \p{scx:...} has been encountered. */
@ -1327,6 +1346,12 @@ mode rather than an escape sequence. It is also used for [^] in JavaScript
compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves
like \N.
ESC_ub is a special return from check_escape() when, in BSUX mode, \u{ is not
followed by hex digits and }, in which case it should mean a literal "u"
followed by a literal "{". This hack is necessary for cases like \u{ 12}
because without it, this is interpreted as u{12} now that spaces are allowed in
quantifiers.
Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in
check_escape(). There are tests in the code for an escape greater than ESC_b
and less than ESC_Z to detect the types that may be repeated. These are the
@ -1336,7 +1361,7 @@ consume a character, that code will have to change. */
enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z,
ESC_E, ESC_Q, ESC_g, ESC_k };
ESC_E, ESC_Q, ESC_g, ESC_k, ESC_ub };
/********************** Opcode definitions ******************/
@ -1372,8 +1397,8 @@ enum {
OP_SOD, /* 1 Start of data: \A */
OP_SOM, /* 2 Start of match (subject + offset): \G */
OP_SET_SOM, /* 3 Set start of match (\K) */
OP_NOT_WORD_BOUNDARY, /* 4 \B */
OP_WORD_BOUNDARY, /* 5 \b */
OP_NOT_WORD_BOUNDARY, /* 4 \B -- see also OP_NOT_UCP_WORD_BOUNDARY */
OP_WORD_BOUNDARY, /* 5 \b -- see also OP_UCP_WORD_BOUNDARY */
OP_NOT_DIGIT, /* 6 \D */
OP_DIGIT, /* 7 \d */
OP_NOT_WHITESPACE, /* 8 \S */
@ -1547,78 +1572,85 @@ enum {
/* The assertions must come before BRA, CBRA, ONCE, and COND. */
OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */
OP_ASSERT, /* 126 Positive lookahead */
OP_ASSERT_NOT, /* 127 Negative lookahead */
OP_ASSERTBACK, /* 128 Positive lookbehind */
OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */
OP_ASSERT_NA, /* 130 Positive non-atomic lookahead */
OP_ASSERTBACK_NA, /* 131 Positive non-atomic lookbehind */
OP_VREVERSE, /* 126 Move pointer back - variable */
OP_ASSERT, /* 127 Positive lookahead */
OP_ASSERT_NOT, /* 128 Negative lookahead */
OP_ASSERTBACK, /* 129 Positive lookbehind */
OP_ASSERTBACK_NOT, /* 130 Negative lookbehind */
OP_ASSERT_NA, /* 131 Positive non-atomic lookahead */
OP_ASSERTBACK_NA, /* 132 Positive non-atomic lookbehind */
/* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come
immediately after the assertions, with ONCE first, as there's a test for >=
ONCE for a subpattern that isn't an assertion. The POS versions must
immediately follow the non-POS versions in each case. */
OP_ONCE, /* 132 Atomic group, contains captures */
OP_SCRIPT_RUN, /* 133 Non-capture, but check characters' scripts */
OP_BRA, /* 134 Start of non-capturing bracket */
OP_BRAPOS, /* 135 Ditto, with unlimited, possessive repeat */
OP_CBRA, /* 136 Start of capturing bracket */
OP_CBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */
OP_COND, /* 138 Conditional group */
OP_ONCE, /* 133 Atomic group, contains captures */
OP_SCRIPT_RUN, /* 134 Non-capture, but check characters' scripts */
OP_BRA, /* 135 Start of non-capturing bracket */
OP_BRAPOS, /* 136 Ditto, with unlimited, possessive repeat */
OP_CBRA, /* 137 Start of capturing bracket */
OP_CBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */
OP_COND, /* 139 Conditional group */
/* These five must follow the previous five, in the same order. There's a
check for >= SBRA to distinguish the two sets. */
OP_SBRA, /* 139 Start of non-capturing bracket, check empty */
OP_SBRAPOS, /* 149 Ditto, with unlimited, possessive repeat */
OP_SCBRA, /* 141 Start of capturing bracket, check empty */
OP_SCBRAPOS, /* 142 Ditto, with unlimited, possessive repeat */
OP_SCOND, /* 143 Conditional group, check empty */
OP_SBRA, /* 140 Start of non-capturing bracket, check empty */
OP_SBRAPOS, /* 141 Ditto, with unlimited, possessive repeat */
OP_SCBRA, /* 142 Start of capturing bracket, check empty */
OP_SCBRAPOS, /* 143 Ditto, with unlimited, possessive repeat */
OP_SCOND, /* 144 Conditional group, check empty */
/* The next two pairs must (respectively) be kept together. */
OP_CREF, /* 144 Used to hold a capture number as condition */
OP_DNCREF, /* 145 Used to point to duplicate names as a condition */
OP_RREF, /* 146 Used to hold a recursion number as condition */
OP_DNRREF, /* 147 Used to point to duplicate names as a condition */
OP_FALSE, /* 148 Always false (used by DEFINE and VERSION) */
OP_TRUE, /* 149 Always true (used by VERSION) */
OP_CREF, /* 145 Used to hold a capture number as condition */
OP_DNCREF, /* 146 Used to point to duplicate names as a condition */
OP_RREF, /* 147 Used to hold a recursion number as condition */
OP_DNRREF, /* 148 Used to point to duplicate names as a condition */
OP_FALSE, /* 149 Always false (used by DEFINE and VERSION) */
OP_TRUE, /* 150 Always true (used by VERSION) */
OP_BRAZERO, /* 150 These two must remain together and in this */
OP_BRAMINZERO, /* 151 order. */
OP_BRAPOSZERO, /* 152 */
OP_BRAZERO, /* 151 These two must remain together and in this */
OP_BRAMINZERO, /* 152 order. */
OP_BRAPOSZERO, /* 153 */
/* These are backtracking control verbs */
OP_MARK, /* 153 always has an argument */
OP_PRUNE, /* 154 */
OP_PRUNE_ARG, /* 155 same, but with argument */
OP_SKIP, /* 156 */
OP_SKIP_ARG, /* 157 same, but with argument */
OP_THEN, /* 158 */
OP_THEN_ARG, /* 159 same, but with argument */
OP_COMMIT, /* 160 */
OP_COMMIT_ARG, /* 161 same, but with argument */
OP_MARK, /* 154 always has an argument */
OP_PRUNE, /* 155 */
OP_PRUNE_ARG, /* 156 same, but with argument */
OP_SKIP, /* 157 */
OP_SKIP_ARG, /* 158 same, but with argument */
OP_THEN, /* 159 */
OP_THEN_ARG, /* 160 same, but with argument */
OP_COMMIT, /* 161 */
OP_COMMIT_ARG, /* 162 same, but with argument */
/* These are forced failure and success verbs. FAIL and ACCEPT do accept an
argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL)
without the need for a special opcode. */
OP_FAIL, /* 162 */
OP_ACCEPT, /* 163 */
OP_ASSERT_ACCEPT, /* 164 Used inside assertions */
OP_CLOSE, /* 165 Used before OP_ACCEPT to close open captures */
OP_FAIL, /* 163 */
OP_ACCEPT, /* 164 */
OP_ASSERT_ACCEPT, /* 165 Used inside assertions */
OP_CLOSE, /* 166 Used before OP_ACCEPT to close open captures */
/* This is used to skip a subpattern with a {0} quantifier */
OP_SKIPZERO, /* 166 */
OP_SKIPZERO, /* 167 */
/* This is used to identify a DEFINE group during compilation so that it can
be checked for having only one branch. It is changed to OP_FALSE before
compilation finishes. */
OP_DEFINE, /* 167 */
OP_DEFINE, /* 168 */
/* These opcodes replace their normal counterparts in UCP mode when
PCRE2_EXTRA_ASCII_BSW is not set. */
OP_NOT_UCP_WORD_BOUNDARY, /* 169 */
OP_UCP_WORD_BOUNDARY, /* 170 */
/* This is not an opcode, but is used to check that tables indexed by opcode
are the correct length, in order to catch updating errors - there have been
@ -1664,7 +1696,7 @@ some cases doesn't actually use these names at all). */
"class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \
"Recurse", "Callout", "CalloutStr", \
"Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
"Reverse", "Assert", "Assert not", \
"Reverse", "VReverse", "Assert", "Assert not", \
"Assert back", "Assert back not", \
"Non-atomic assert", "Non-atomic assert back", \
"Once", \
@ -1679,7 +1711,7 @@ some cases doesn't actually use these names at all). */
"*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \
"*THEN", "*THEN", "*COMMIT", "*COMMIT", "*FAIL", \
"*ACCEPT", "*ASSERT_ACCEPT", \
"Close", "Skip zero", "Define"
"Close", "Skip zero", "Define", "\\B (ucp)", "\\b (ucp)"
/* This macro defines the length of fixed length operations in the compiled
@ -1746,7 +1778,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */
1+LINK_SIZE, /* KetRmax */ \
1+LINK_SIZE, /* KetRmin */ \
1+LINK_SIZE, /* KetRpos */ \
1+LINK_SIZE, /* Reverse */ \
1+IMM2_SIZE, /* Reverse */ \
1+2*IMM2_SIZE, /* VReverse */ \
1+LINK_SIZE, /* Assert */ \
1+LINK_SIZE, /* Assert not */ \
1+LINK_SIZE, /* Assert behind */ \
@ -1775,7 +1808,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */
1, 3, /* COMMIT, COMMIT_ARG */ \
1, 1, 1, /* FAIL, ACCEPT, ASSERT_ACCEPT */ \
1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \
1 /* DEFINE */
1, /* DEFINE */ \
1, 1 /* \B and \b in UCP mode */
/* A magic value for OP_RREF to indicate the "any recursion" condition. */
@ -2042,6 +2076,9 @@ extern void * _pcre2_memmove(void *, const void *, size_t);
#endif
#endif /* PCRE2_CODE_UNIT_WIDTH */
extern BOOL PRIV(ckd_smul)(PCRE2_SIZE *, int, int);
#endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */
/* End of pcre2_internal.h */

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2022 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -572,6 +572,7 @@ typedef struct pcre2_real_compile_context {
uint16_t newline_convention;
uint32_t parens_nest_limit;
uint32_t extra_options;
uint32_t max_varlookbehind;
} pcre2_real_compile_context;
/* The real match context structure. */
@ -605,12 +606,12 @@ defined specially because it is required in pcre2_serialize_decode() when
copying the size from possibly unaligned memory into a variable of the same
type. Use a macro rather than a typedef to avoid compiler warnings when this
file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the
largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit
argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field
here.) */
largest lookbehind that is supported. (OP_REVERSE and OP_VREVERSE in a pattern
have 16-bit arguments in 8-bit and 16-bit modes, so we need no more than a
16-bit field here.) */
#undef CODE_BLOCKSIZE_TYPE
#define CODE_BLOCKSIZE_TYPE size_t
#define CODE_BLOCKSIZE_TYPE PCRE2_SIZE
#undef LOOKBEHIND_MAX
#define LOOKBEHIND_MAX UINT16_MAX
@ -658,6 +659,7 @@ typedef struct pcre2_real_match_data {
PCRE2_SPTR mark; /* Pointer to last mark */
struct heapframe *heapframes; /* Backtracking frames heap memory */
PCRE2_SIZE heapframes_size; /* Malloc-ed size */
PCRE2_SIZE subject_length; /* Subject length */
PCRE2_SIZE leftchar; /* Offset to leftmost code unit */
PCRE2_SIZE rightchar; /* Offset to rightmost code unit */
PCRE2_SIZE startchar; /* Offset to starting code unit */
@ -675,8 +677,8 @@ typedef struct pcre2_real_match_data {
#ifndef PCRE2_PCRE2TEST
/* Structures for checking for mutual recursion when scanning compiled or
parsed code. */
/* Structures for checking for mutual function recursion when scanning compiled
or parsed code. */
typedef struct recurse_check {
struct recurse_check *prev;
@ -688,7 +690,7 @@ typedef struct parsed_recurse_check {
uint32_t *groupptr;
} parsed_recurse_check;
/* Structure for building a cache when filling in recursion offsets. */
/* Structure for building a cache when filling in pattern recursion offsets. */
typedef struct recurse_cache {
PCRE2_SPTR group;
@ -734,7 +736,6 @@ typedef struct compile_block {
uint16_t name_entry_size; /* Size of each entry */
uint16_t parens_depth; /* Depth of nested parentheses */
uint16_t assert_depth; /* Depth of nested assertions */
open_capitem *open_caps; /* Chain of open capture items */
named_group *named_groups; /* Points to vector in pre-compile */
uint32_t named_group_list_size; /* Number of entries in the list */
uint32_t external_options; /* External (initial) options */
@ -752,10 +753,11 @@ typedef struct compile_block {
uint32_t class_range_end; /* Overall class range end */
PCRE2_UCHAR nl[4]; /* Newline string when fixed length */
uint32_t req_varyopt; /* "After variable item" flag for reqbyte */
int max_lookbehind; /* Maximum lookbehind (characters) */
uint32_t max_varlookbehind; /* Limit for variable lookbehinds */
int max_lookbehind; /* Maximum lookbehind encountered (characters) */
BOOL had_accept; /* (*ACCEPT) encountered */
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
BOOL had_recurse; /* Had a recursion or subroutine call */
BOOL had_recurse; /* Had a pattern recursion or subroutine call */
BOOL dupnames; /* Duplicate names exist */
} compile_block;
@ -773,6 +775,7 @@ call within the pattern when running pcre2_dfa_match(). */
typedef struct dfa_recursion_info {
struct dfa_recursion_info *prevrec;
PCRE2_SPTR subject_position;
PCRE2_SPTR last_used_ptr;
uint32_t group_num;
} dfa_recursion_info;
@ -793,7 +796,7 @@ typedef struct heapframe {
PCRE2_SIZE length; /* Used for character, string, or code lengths */
PCRE2_SIZE back_frame; /* Amount to subtract on RRETURN */
PCRE2_SIZE temp_size; /* Used for short-term PCRE2_SIZE values */
uint32_t rdepth; /* "Recursion" depth */
uint32_t rdepth; /* Function "recursion" depth within pcre2_match() */
uint32_t group_frame_type; /* Type information for group frames */
uint32_t temp_32[4]; /* Used for short-term 32-bit or BOOL values */
uint8_t return_id; /* Where to go on in internal "return" */
@ -826,14 +829,15 @@ typedef struct heapframe {
allows for exactly the right size ovector for the number of capturing
parentheses. (See also the comment for pcre2_real_match_data above.) */
PCRE2_SPTR eptr; /* MUST BE FIRST */
PCRE2_SPTR start_match; /* Can be adjusted by \K */
PCRE2_SPTR mark; /* Most recent mark on the success path */
uint32_t current_recurse; /* Current (deepest) recursion number */
uint32_t capture_last; /* Most recent capture */
PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */
PCRE2_SIZE offset_top; /* Offset after highest capture */
PCRE2_SIZE ovector[131072]; /* Must be last in the structure */
PCRE2_SPTR eptr; /* MUST BE FIRST */
PCRE2_SPTR start_match; /* Can be adjusted by \K */
PCRE2_SPTR mark; /* Most recent mark on the success path */
PCRE2_SPTR recurse_last_used; /* Last character used at time of pattern recursion */
uint32_t current_recurse; /* Group number of current (deepest) pattern recursion */
uint32_t capture_last; /* Most recent capture */
PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */
PCRE2_SIZE offset_top; /* Offset after highest capture */
PCRE2_SIZE ovector[131072]; /* Must be last in the structure */
} heapframe;
/* This typedef is a check that the size of the heapframe structure is a
@ -858,7 +862,7 @@ doing traditional NFA matching (pcre2_match() and friends). */
typedef struct match_block {
pcre2_memctl memctl; /* For general use */
PCRE2_SIZE heap_limit; /* As it says */
uint32_t heap_limit; /* As it says */
uint32_t match_limit; /* As it says */
uint32_t match_limit_depth; /* As it says */
uint32_t match_call_count; /* Number of times a new frame is created */
@ -875,10 +879,11 @@ typedef struct match_block {
uint16_t name_count; /* Number of names in name table */
uint16_t name_entry_size; /* Size of entry in names table */
PCRE2_SPTR name_table; /* Table of group names */
PCRE2_SPTR start_code; /* For use when recursing */
PCRE2_SPTR start_code; /* For use in pattern recursion */
PCRE2_SPTR start_subject; /* Start of the subject string */
PCRE2_SPTR check_subject; /* Where UTF-checked from */
PCRE2_SPTR end_subject; /* End of the subject string */
PCRE2_SPTR end_subject; /* Usable end of the subject string */
PCRE2_SPTR true_end_subject; /* Actual end of the subject string */
PCRE2_SPTR end_match_ptr; /* Subject position at end match */
PCRE2_SPTR start_used_ptr; /* Earliest consulted character */
PCRE2_SPTR last_used_ptr; /* Latest consulted character */
@ -886,7 +891,7 @@ typedef struct match_block {
PCRE2_SPTR nomatch_mark; /* Mark pointer to pass back on failure */
PCRE2_SPTR verb_ecode_ptr; /* For passing back info */
PCRE2_SPTR verb_skip_ptr; /* For passing back a (*SKIP) name */
uint32_t verb_current_recurse; /* Current recurse when (*VERB) happens */
uint32_t verb_current_recurse; /* Current recursion group when (*VERB) happens */
uint32_t moptions; /* Match options */
uint32_t poptions; /* Pattern options */
uint32_t skip_arg_count; /* For counting SKIP_ARGs */
@ -911,7 +916,7 @@ typedef struct dfa_match_block {
PCRE2_SPTR last_used_ptr; /* Latest consulted character */
const uint8_t *tables; /* Character tables */
PCRE2_SIZE start_offset; /* The start offset value */
PCRE2_SIZE heap_limit; /* As it says */
uint32_t heap_limit; /* As it says */
PCRE2_SIZE heap_used; /* As it says */
uint32_t match_limit; /* As it says */
uint32_t match_limit_depth; /* As it says */
@ -926,7 +931,7 @@ typedef struct dfa_match_block {
pcre2_callout_block *cb; /* Points to a callout block */
void *callout_data; /* To pass back to callouts */
int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */
dfa_recursion_info *recursive; /* Linked list of recursion data */
dfa_recursion_info *recursive; /* Linked list of pattern recursion data */
} dfa_match_block;
#endif /* PCRE2_PCRE2TEST */

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2018 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -42,6 +42,12 @@ POSSIBILITY OF SUCH DAMAGE.
#error This file must be included from pcre2_jit_compile.c.
#endif
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#include <sanitizer/msan_interface.h>
#endif /* __has_feature(memory_sanitizer) */
#endif /* defined(__has_feature) */
#ifdef SUPPORT_JIT
static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func)
@ -171,6 +177,7 @@ if (rc > (int)oveccount)
rc = 0;
match_data->code = re;
match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL;
match_data->subject_length = length;
match_data->rc = rc;
match_data->startchar = arguments.startchar_ptr - subject;
match_data->leftchar = 0;
@ -178,6 +185,13 @@ match_data->rightchar = 0;
match_data->mark = arguments.mark_ptr;
match_data->matchedby = PCRE2_MATCHEDBY_JIT;
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
if (rc > 0)
__msan_unpoison(match_data->ovector, 2 * rc * sizeof(match_data->ovector[0]));
#endif /* __has_feature(memory_sanitizer) */
#endif /* defined(__has_feature) */
return match_data->rc;
#endif /* SUPPORT_JIT */

View File

@ -82,7 +82,12 @@ POSSIBILITY OF SUCH DAMAGE.
# endif
# endif
static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars)
#if (defined(__GNUC__) && __SANITIZE_ADDRESS__) \
|| (defined(__clang__) \
&& ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3)))
__attribute__((no_sanitize_address))
#endif
static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 **str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars)
#undef FF_FUN
{
quad_word qw;
@ -171,7 +176,7 @@ else
}
# endif
str_ptr += IN_UCHARS(offs1);
*str_ptr += IN_UCHARS(offs1);
#endif
#if PCRE2_CODE_UNIT_WIDTH != 8
@ -183,13 +188,13 @@ restart:;
#endif
#if defined(FFCPS)
if (str_ptr >= str_end)
if (*str_ptr >= str_end)
return NULL;
sljit_u8 *p1 = str_ptr - diff;
sljit_u8 *p1 = *str_ptr - diff;
#endif
sljit_s32 align_offset = ((uint64_t)str_ptr & 0xf);
str_ptr = (sljit_u8 *) ((uint64_t)str_ptr & ~0xf);
vect_t data = VLD1Q(str_ptr);
sljit_s32 align_offset = ((uint64_t)*str_ptr & 0xf);
*str_ptr = (sljit_u8 *) ((uint64_t)*str_ptr & ~0xf);
vect_t data = VLD1Q(*str_ptr);
#if PCRE2_CODE_UNIT_WIDTH != 8
data = VANDQ(data, char_mask);
#endif
@ -212,9 +217,9 @@ vect_t prev_data = data;
# endif
vect_t data2;
if (p1 < str_ptr)
if (p1 < *str_ptr)
{
data2 = VLD1Q(str_ptr - diff);
data2 = VLD1Q(*str_ptr - diff);
#if PCRE2_CODE_UNIT_WIDTH != 8
data2 = VANDQ(data2, char_mask);
#endif
@ -242,12 +247,12 @@ if (align_offset < 8)
qw.dw[0] >>= align_offset * 8;
if (qw.dw[0])
{
str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8;
*str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8;
goto match;
}
if (qw.dw[1])
{
str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
*str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
goto match;
}
}
@ -256,15 +261,15 @@ else
qw.dw[1] >>= (align_offset - 8) * 8;
if (qw.dw[1])
{
str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8;
*str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8;
goto match;
}
}
str_ptr += 16;
*str_ptr += 16;
while (str_ptr < str_end)
while (*str_ptr < str_end)
{
vect_t orig_data = VLD1Q(str_ptr);
vect_t orig_data = VLD1Q(*str_ptr);
#if PCRE2_CODE_UNIT_WIDTH != 8
orig_data = VANDQ(orig_data, char_mask);
#endif
@ -287,7 +292,7 @@ while (str_ptr < str_end)
# if defined (FFCPS_DIFF1)
data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1);
# else
data2 = VLD1Q(str_ptr - diff);
data2 = VLD1Q(*str_ptr - diff);
# if PCRE2_CODE_UNIT_WIDTH != 8
data2 = VANDQ(data2, char_mask);
# endif
@ -312,11 +317,11 @@ while (str_ptr < str_end)
VST1Q(qw.mem, eq);
if (qw.dw[0])
str_ptr += __builtin_ctzll(qw.dw[0]) / 8;
*str_ptr += __builtin_ctzll(qw.dw[0]) / 8;
else if (qw.dw[1])
str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
*str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
else {
str_ptr += 16;
*str_ptr += 16;
#if defined (FFCPS_DIFF1)
prev_data = orig_data;
#endif
@ -324,24 +329,24 @@ while (str_ptr < str_end)
}
match:;
if (str_ptr >= str_end)
if (*str_ptr >= str_end)
/* Failed match. */
return NULL;
#if defined(FF_UTF)
if (utf_continue((PCRE2_SPTR)str_ptr - offs1))
if (utf_continue((PCRE2_SPTR)*str_ptr - offs1))
{
/* Not a match. */
str_ptr += IN_UCHARS(1);
*str_ptr += IN_UCHARS(1);
goto restart;
}
#endif
/* Match. */
#if defined (FFCPS)
str_ptr -= IN_UCHARS(offs1);
*str_ptr -= IN_UCHARS(offs1);
#endif
return str_ptr;
return *str_ptr;
}
/* Failed match. */

File diff suppressed because it is too large Load Diff

View File

@ -52,8 +52,6 @@ PCRE2_DFTABLES is defined. */
# include "pcre2_internal.h"
#endif
/*************************************************
* Create PCRE2 character tables *
*************************************************/
@ -98,7 +96,11 @@ for (i = 0; i < 256; i++) *p++ = tolower(i);
/* Next the case-flipping table */
for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
for (i = 0; i < 256; i++)
{
int c = islower(i)? toupper(i) : tolower(i);
*p++ = (c < 256)? c : i;
}
/* Then the character class tables. Don't try to be clever and save effort on
exclusive ones - in some locales things may be different.

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2015-2022 University of Cambridge
New API code Copyright (c) 2015-2024 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -43,6 +43,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "config.h"
#endif
#include "pcre2_internal.h"
/* These defines enable debugging code */
/* #define DEBUG_FRAMES_DISPLAY */
@ -53,6 +55,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdarg.h>
#endif
#ifdef DEBUG_SHOW_OPS
static const char *OP_names[] = { OP_NAME_LIST };
#endif
/* These defines identify the name of the block containing "static"
information, and fields within it. */
@ -60,8 +66,6 @@ information, and fields within it. */
#define PSSTART start_subject /* Field containing processed string start */
#define PSEND end_subject /* Field containing processed string end */
#include "pcre2_internal.h"
#define RECURSE_UNSET 0xffffffffu /* Bigger than max group number */
/* Masks for identifying the public options that are permitted at match time. */
@ -69,7 +73,8 @@ information, and fields within it. */
#define PUBLIC_MATCH_OPTIONS \
(PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT)
PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT| \
PCRE2_DISABLE_RECURSELOOP_CHECK)
#define PUBLIC_JIT_MATCH_OPTIONS \
(PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\
@ -150,7 +155,7 @@ changed, the code at RETURN_SWITCH below must be updated in sync. */
enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
RM31, RM32, RM33, RM34, RM35, RM36 };
RM31, RM32, RM33, RM34, RM35, RM36, RM37 };
#ifdef SUPPORT_WIDE_CHARS
enum { RM100=100, RM101 };
@ -597,11 +602,12 @@ heapframe *P = NULL;
heapframe *frames_top; /* End of frames vector */
heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */
PCRE2_SIZE heapframes_size; /* Usable size of frames vector */
PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */
/* Local variables that do not need to be preserved over calls to RRMATCH(). */
PCRE2_SPTR branch_end = NULL;
PCRE2_SPTR branch_start;
PCRE2_SPTR bracode; /* Temp pointer to start of group */
PCRE2_SIZE offset; /* Used for group offsets */
PCRE2_SIZE length; /* Used for various length calculations */
@ -635,13 +641,10 @@ copied when a new frame is created. */
frame_copy_size = frame_size - offsetof(heapframe, eptr);
/* Set up the first frame and the end of the frames vector. We set the local
heapframes_size to the usuable amount of the vector, that is, a whole number of
frames. */
/* Set up the first frame and the end of the frames vector. */
F = match_data->heapframes;
heapframes_size = (match_data->heapframes_size / frame_size) * frame_size;
frames_top = (heapframe *)((char *)F + heapframes_size);
frames_top = (heapframe *)((char *)F + match_data->heapframes_size);
Frdepth = 0; /* "Recursion" depth */
Fcapture_last = 0; /* Number of most recent capture */
@ -662,35 +665,54 @@ MATCH_RECURSE:
doubling the size, but constrained by the heap limit (which is in KiB). */
N = (heapframe *)((char *)F + frame_size);
if (N >= frames_top)
if ((heapframe *)((char *)N + frame_size) >= frames_top)
{
heapframe *new;
PCRE2_SIZE newsize = match_data->heapframes_size * 2;
PCRE2_SIZE newsize;
PCRE2_SIZE usedsize = (char *)N - (char *)(match_data->heapframes);
if (newsize > mb->heap_limit)
if (match_data->heapframes_size >= PCRE2_SIZE_MAX / 2)
{
PCRE2_SIZE maxsize = (mb->heap_limit/frame_size) * frame_size;
if (match_data->heapframes_size >= maxsize) return PCRE2_ERROR_HEAPLIMIT;
newsize = maxsize;
if (match_data->heapframes_size == PCRE2_SIZE_MAX - 1)
return PCRE2_ERROR_NOMEMORY;
newsize = PCRE2_SIZE_MAX - 1;
}
else
newsize = match_data->heapframes_size * 2;
if (newsize / 1024 >= mb->heap_limit)
{
PCRE2_SIZE old_size = match_data->heapframes_size / 1024;
if (mb->heap_limit <= old_size)
return PCRE2_ERROR_HEAPLIMIT;
else
{
PCRE2_SIZE max_delta = 1024 * (mb->heap_limit - old_size);
int over_bytes = match_data->heapframes_size % 1024;
if (over_bytes) max_delta -= (1024 - over_bytes);
newsize = match_data->heapframes_size + max_delta;
}
}
/* With a heap limit set, the permitted additional size may not be enough for
another frame, so do a final check. */
if (newsize - usedsize < frame_size) return PCRE2_ERROR_HEAPLIMIT;
new = match_data->memctl.malloc(newsize, match_data->memctl.memory_data);
if (new == NULL) return PCRE2_ERROR_NOMEMORY;
memcpy(new, match_data->heapframes, heapframes_size);
memcpy(new, match_data->heapframes, usedsize);
F = (heapframe *)((char *)new + ((char *)F - (char *)match_data->heapframes));
N = (heapframe *)((char *)F + frame_size);
N = (heapframe *)((char *)new + usedsize);
F = (heapframe *)((char *)N - frame_size);
match_data->memctl.free(match_data->heapframes, match_data->memctl.memory_data);
match_data->heapframes = new;
match_data->heapframes_size = newsize;
heapframes_size = (newsize / frame_size) * frame_size;
frames_top = (heapframe *)((char *)new + heapframes_size);
frames_top = (heapframe *)((char *)new + newsize);
}
#ifdef DEBUG_SHOW_RMATCH
fprintf(stderr, "++ RMATCH %2d frame=%d", Freturn_id, Frdepth + 1);
fprintf(stderr, "++ RMATCH %d frame=%d", Freturn_id, Frdepth + 1);
if (group_frame_type != 0)
{
fprintf(stderr, " type=%x ", group_frame_type);
@ -760,10 +782,16 @@ opcodes. */
if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
if (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "\n++ New frame: type=0x%x subject offset %ld\n",
GF_IDMASK(Fgroup_frame_type), Feptr - mb->start_subject);
#endif
for (;;)
{
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "++ op=%d\n", *Fecode);
fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
OP_names[*Fecode]);
#endif
Fop = (uint8_t)(*Fecode); /* Cast needed for 16-bit and 32-bit modes */
@ -811,15 +839,16 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
assert_accept_frame = F;
RRETURN(MATCH_ACCEPT);
/* If recursing, we have to find the most recent recursion. */
/* For ACCEPT within a recursion, we have to find the most recent
recursion. If not in a recursion, fall through to code that is common with
OP_END. */
case OP_ACCEPT:
case OP_END:
/* Handle end of a recursion. */
if (Fcurrent_recurse != RECURSE_UNSET)
{
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "++ Accept within recursion\n");
#endif
offset = Flast_group_offset;
for(;;)
{
@ -842,27 +871,49 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
Fecode += 1 + LINK_SIZE;
continue;
}
/* Fall through */
/* Not a recursion. Fail for an empty string match if either PCRE2_NOTEMPTY
is set, or if PCRE2_NOTEMPTY_ATSTART is set and we have matched at the
start of the subject. In both cases, backtracking will then try other
alternatives, if any. */
/* OP_END itself can never be reached within a recursion because that is
picked up when the OP_KET that always precedes OP_END is reached. */
case OP_END:
/* Fail for an empty string match if either PCRE2_NOTEMPTY is set, or if
PCRE2_NOTEMPTY_ATSTART is set and we have matched at the start of the
subject. In both cases, backtracking will then try other alternatives, if
any. */
if (Feptr == Fstart_match &&
((mb->moptions & PCRE2_NOTEMPTY) != 0 ||
((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 &&
Fstart_match == mb->start_subject + mb->start_offset)))
{
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "++ Backtrack because empty string\n");
#endif
RRETURN(MATCH_NOMATCH);
}
/* Also fail if PCRE2_ENDANCHORED is set and the end of the match is not
/* Fail if PCRE2_ENDANCHORED is set and the end of the match is not
the end of the subject. After (*ACCEPT) we fail the entire match (at this
position) but backtrack on reaching the end of the pattern. */
position) but backtrack if we've reached the end of the pattern. This
applies whether or not we are in a recursion. */
if (Feptr < mb->end_subject &&
((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)
{
if (Fop == OP_END) RRETURN(MATCH_NOMATCH);
return MATCH_NOMATCH;
if (Fop == OP_END)
{
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "++ Backtrack because not at end (endanchored set)\n");
#endif
RRETURN(MATCH_NOMATCH);
}
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "++ Failed ACCEPT not at end (endanchnored set)\n");
#endif
return MATCH_NOMATCH; /* (*ACCEPT) */
}
/* We have a successful match of the whole pattern. Record the result and
@ -2435,6 +2486,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
GETCHARINCTEST(fc, Feptr);
{
const uint32_t *cp;
uint32_t chartype;
const ucd_record *prop = GET_UCD(fc);
BOOL notmatch = Fop == OP_NOTPROP;
@ -2445,9 +2497,10 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
break;
case PT_LAMP:
if ((prop->chartype == ucp_Lu ||
prop->chartype == ucp_Ll ||
prop->chartype == ucp_Lt) == notmatch)
chartype = prop->chartype;
if ((chartype == ucp_Lu ||
chartype == ucp_Ll ||
chartype == ucp_Lt) == notmatch)
RRETURN(MATCH_NOMATCH);
break;
@ -2477,8 +2530,9 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* These are specials */
case PT_ALNUM:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N) == notmatch)
chartype = prop->chartype;
if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N) == notmatch)
RRETURN(MATCH_NOMATCH);
break;
@ -2503,13 +2557,22 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
break;
case PT_WORD:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
fc == CHAR_UNDERSCORE) == notmatch)
chartype = prop->chartype;
if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N ||
chartype == ucp_Mn ||
chartype == ucp_Pc) == notmatch)
RRETURN(MATCH_NOMATCH);
break;
case PT_CLIST:
#if PCRE2_CODE_UNIT_WIDTH == 32
if (fc > MAX_UTF_CODE_POINT)
{
if (notmatch) break;;
RRETURN(MATCH_NOMATCH);
}
#endif
cp = PRIV(ucd_caseless_sets) + Fecode[2];
for (;;)
{
@ -2805,16 +2868,17 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case PT_WORD:
for (i = 1; i <= Lmin; i++)
{
int category;
int chartype, category;
if (Feptr >= mb->end_subject)
{
SCHECK_PARTIAL();
RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(fc, Feptr);
category = UCD_CATEGORY(fc);
chartype = UCD_CHARTYPE(fc);
category = PRIV(ucp_gentype)[chartype];
if ((category == ucp_L || category == ucp_N ||
fc == CHAR_UNDERSCORE) == notmatch)
chartype == ucp_Mn || chartype == ucp_Pc) == notmatch)
RRETURN(MATCH_NOMATCH);
}
break;
@ -2829,6 +2893,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(fc, Feptr);
#if PCRE2_CODE_UNIT_WIDTH == 32
if (fc > MAX_UTF_CODE_POINT)
{
if (notmatch) continue;
RRETURN(MATCH_NOMATCH);
}
#endif
cp = PRIV(ucd_caseless_sets) + Lpropvalue;
for (;;)
{
@ -3609,7 +3680,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case PT_WORD:
for (;;)
{
int category;
int chartype, category;
RMATCH(Fecode, RM215);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
@ -3619,10 +3690,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(fc, Feptr);
category = UCD_CATEGORY(fc);
chartype = UCD_CHARTYPE(fc);
category = PRIV(ucp_gentype)[chartype];
if ((category == ucp_L ||
category == ucp_N ||
fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP))
chartype == ucp_Mn ||
chartype == ucp_Pc) == (Lctype == OP_NOTPROP))
RRETURN(MATCH_NOMATCH);
}
/* Control never gets here */
@ -3640,6 +3713,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
RRETURN(MATCH_NOMATCH);
}
GETCHARINCTEST(fc, Feptr);
#if PCRE2_CODE_UNIT_WIDTH == 32
if (fc > MAX_UTF_CODE_POINT)
{
if (Lctype == OP_NOTPROP) continue;
RRETURN(MATCH_NOMATCH);
}
#endif
cp = PRIV(ucd_caseless_sets) + Lpropvalue;
for (;;)
{
@ -4190,7 +4270,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case PT_WORD:
for (i = Lmin; i < Lmax; i++)
{
int category;
int chartype, category;
int len = 1;
if (Feptr >= mb->end_subject)
{
@ -4198,9 +4278,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
break;
}
GETCHARLENTEST(fc, Feptr, len);
category = UCD_CATEGORY(fc);
if ((category == ucp_L || category == ucp_N ||
fc == CHAR_UNDERSCORE) == notmatch)
chartype = UCD_CHARTYPE(fc);
category = PRIV(ucp_gentype)[chartype];
if ((category == ucp_L ||
category == ucp_N ||
chartype == ucp_Mn ||
chartype == ucp_Pc) == notmatch)
break;
Feptr+= len;
}
@ -4217,14 +4300,24 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
break;
}
GETCHARLENTEST(fc, Feptr, len);
cp = PRIV(ucd_caseless_sets) + Lpropvalue;
for (;;)
#if PCRE2_CODE_UNIT_WIDTH == 32
if (fc > MAX_UTF_CODE_POINT)
{
if (fc < *cp)
{ if (notmatch) break; else goto GOT_MAX; }
if (fc == *cp++)
{ if (notmatch) goto GOT_MAX; else break; }
if (!notmatch) goto GOT_MAX;
}
else
#endif
{
cp = PRIV(ucd_caseless_sets) + Lpropvalue;
for (;;)
{
if (fc < *cp)
{ if (notmatch) break; else goto GOT_MAX; }
if (fc == *cp++)
{ if (notmatch) goto GOT_MAX; else break; }
}
}
Feptr += len;
}
GOT_MAX:
@ -5322,9 +5415,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* ===================================================================== */
/* Recursion either matches the current regex, or some subexpression. The
offset data is the offset to the starting bracket from the start of the
whole pattern. (This is so that it works from duplicated subpatterns.) */
/* Pattern recursion either matches the current regex, or some
subexpression. The offset data is the offset to the starting bracket from
the start of the whole pattern. This is so that it works from duplicated
subpatterns. For a whole-pattern recursion, we have to infer the number
zero. */
#define Lframe_type F->temp_32[0]
#define Lstart_branch F->temp_sptr[0]
@ -5333,9 +5428,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
bracode = mb->start_code + GET(Fecode, 1);
number = (bracode == mb->start_code)? 0 : GET2(bracode, 1 + LINK_SIZE);
/* If we are already in a recursion, check for repeating the same one
without advancing the subject pointer. This should catch convoluted mutual
recursions. (Some simple cases are caught at compile time.) */
/* If we are already in a pattern recursion, check for repeating the same
one without changing the subject pointer or the last referenced character
in the subject. This should catch convoluted mutual recursions; some
simple cases are caught at compile time. However, there are rare cases when
this check needs to be turned off. In this case, actual recursion loops
will be caught by the match or heap limits. */
if (Fcurrent_recurse != RECURSE_UNSET)
{
@ -5346,15 +5444,19 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
P = (heapframe *)((char *)N - frame_size);
if (N->group_frame_type == (GF_RECURSE | number))
{
if (Feptr == P->eptr) return PCRE2_ERROR_RECURSELOOP;
if (Feptr == P->eptr && mb->last_used_ptr == P->recurse_last_used &&
(mb->moptions & PCRE2_DISABLE_RECURSELOOP_CHECK) == 0)
return PCRE2_ERROR_RECURSELOOP;
break;
}
offset = P->last_group_offset;
}
}
/* Now run the recursion, branch by branch. */
/* Remember the current last referenced character and then run the
recursion branch by branch. */
F->recurse_last_used = mb->last_used_ptr;
Lstart_branch = bracode;
Lframe_type = GF_RECURSE | number;
@ -5683,13 +5785,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* ===================================================================== */
/* Move the subject pointer back. This occurs only at the start of each
branch of a lookbehind assertion. If we are too close to the start to move
back, fail. When working with UTF-8 we move back a number of characters,
not bytes. */
/* Move the subject pointer back by one fixed amount. This occurs at the
start of each branch that has a fixed length in a lookbehind assertion. If
we are too close to the start to move back, fail. When working with UTF-8
we move back a number of characters, not bytes. */
case OP_REVERSE:
number = GET(Fecode, 1);
number = GET2(Fecode, 1);
#ifdef SUPPORT_UNICODE
if (utf)
{
@ -5703,7 +5805,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
else
#endif
/* No UTF-8 support, or not in UTF-8 mode: count is code unit count */
/* No UTF support, or not in UTF mode: count is code unit count */
{
if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH);
@ -5713,15 +5815,84 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* Save the earliest consulted character, then skip to next opcode */
if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr;
Fecode += 1 + LINK_SIZE;
Fecode += 1 + IMM2_SIZE;
break;
/* ===================================================================== */
/* Move the subject pointer back by a variable amount. This occurs at the
start of each branch of a lookbehind assertion when the branch has a
variable, but limited, length. A loop is needed to try matching the branch
after moving back different numbers of characters. If we are too close to
the start to move back even the minimum amount, fail. When working with
UTF-8 we move back a number of characters, not bytes. */
#define Lmin F->temp_32[0]
#define Lmax F->temp_32[1]
#define Leptr F->temp_sptr[0]
case OP_VREVERSE:
Lmin = GET2(Fecode, 1);
Lmax = GET2(Fecode, 1 + IMM2_SIZE);
Leptr = Feptr;
/* Move back by the maximum branch length and then work forwards. This
ensures that items such as \d{3,5} get the maximum length, which is
relevant for captures, and makes for Perl compatibility. */
#ifdef SUPPORT_UNICODE
if (utf)
{
for (i = 0; i < Lmax; i++)
{
if (Feptr == mb->start_subject)
{
if (i < Lmin) RRETURN(MATCH_NOMATCH);
Lmax = i;
break;
}
Feptr--;
BACKCHAR(Feptr);
}
}
else
#endif
/* No UTF support or not in UTF mode */
{
ptrdiff_t diff = Feptr - mb->start_subject;
uint32_t available = (diff > 65535)? 65535 : ((diff > 0)? diff : 0);
if (Lmin > available) RRETURN(MATCH_NOMATCH);
if (Lmax > available) Lmax = available;
Feptr -= Lmax;
}
/* Now try matching, moving forward one character on failure, until we
reach the mimimum back length. */
for (;;)
{
RMATCH(Fecode + 1 + 2 * IMM2_SIZE, RM37);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
if (Lmax-- <= Lmin) RRETURN(MATCH_NOMATCH);
Feptr++;
#ifdef SUPPORT_UNICODE
if (utf) { FORWARDCHARTEST(Feptr, mb->end_subject); }
#endif
}
/* Control never reaches here */
#undef Lmin
#undef Lmax
#undef Leptr
/* ===================================================================== */
/* An alternation is the end of a branch; scan along to find the end of the
bracketed group. */
case OP_ALT:
branch_end = Fecode;
do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);
break;
@ -5729,7 +5900,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* ===================================================================== */
/* The end of a parenthesized group. For all but OP_BRA and OP_COND, the
starting frame was added to the chained frames in order to remember the
starting subject position for the group. */
starting subject position for the group. (Not true for OP_BRA when it's a
whole pattern recursion, but that is handled separately below.)*/
case OP_KET:
case OP_KETRMIN:
@ -5738,8 +5910,14 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
bracode = Fecode - GET(Fecode, 1);
/* Point N to the frame at the start of the most recent group.
Remember the subject pointer at the start of the group. */
if (branch_end == NULL) branch_end = Fecode;
branch_start = bracode;
while (branch_start + GET(branch_start, 1) != branch_end)
branch_start += GET(branch_start, 1);
branch_end = NULL;
/* Point N to the frame at the start of the most recent group, and P to its
predecessor. Remember the subject pointer at the start of the group. */
if (*bracode != OP_BRA && *bracode != OP_COND)
{
@ -5775,27 +5953,64 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
switch (*bracode)
{
case OP_BRA: /* No need to do anything for these */
case OP_COND:
/* Whole pattern recursion is handled as a recursion into group 0, but
the entire pattern is wrapped in OP_BRA/OP_KET rather than a capturing
group - a design mistake: it should perhaps have been capture group 0.
Anyway, that means the end of such recursion must be handled here. It is
detected by checking for an immediately following OP_END when we are
recursing in group 0. If this is not the end of a whole-pattern
recursion, there is nothing to be done. */
case OP_BRA:
if (Fcurrent_recurse != 0 || Fecode[1+LINK_SIZE] != OP_END) break;
/* It is the end of whole-pattern recursion. */
offset = Flast_group_offset;
if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
N = (heapframe *)((char *)match_data->heapframes + offset);
P = (heapframe *)((char *)N - frame_size);
Flast_group_offset = P->last_group_offset;
/* Reinstate the previous set of captures and then carry on after the
recursion call. */
memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
Foffset_top * sizeof(PCRE2_SIZE));
Foffset_top = P->offset_top;
Fcapture_last = P->capture_last;
Fcurrent_recurse = P->current_recurse;
Fecode = P->ecode + 1 + LINK_SIZE;
continue; /* With next opcode */
case OP_COND: /* No need to do anything for these */
case OP_SCOND:
break;
/* Non-atomic positive assertions are like OP_BRA, except that the
subject pointer must be put back to where it was at the start of the
assertion. */
assertion. For a variable lookbehind, check its end point. */
case OP_ASSERTBACK_NA:
if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
RRETURN(MATCH_NOMATCH);
/* Fall through */
case OP_ASSERT_NA:
case OP_ASSERTBACK_NA:
if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
Feptr = P->eptr;
break;
/* Atomic positive assertions are like OP_ONCE, except that in addition
the subject pointer must be put back to where it was at the start of the
assertion. */
assertion. For a variable lookbehind, check its end point. */
case OP_ASSERTBACK:
if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
RRETURN(MATCH_NOMATCH);
/* Fall through */
case OP_ASSERT:
case OP_ASSERTBACK:
if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
Feptr = P->eptr;
/* Fall through */
@ -5816,10 +6031,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
break;
/* A matching negative assertion returns MATCH, which is turned into
NOMATCH at the assertion level. */
NOMATCH at the assertion level. For a variable lookbehind, check its end
point. */
case OP_ASSERTBACK_NOT:
if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
RRETURN(MATCH_NOMATCH);
/* Fall through */
case OP_ASSERT_NOT:
case OP_ASSERTBACK_NOT:
RRETURN(MATCH_MATCH);
/* At the end of a script run, apply the script-checking rules. This code
@ -5830,9 +6050,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH);
break;
/* Whole-pattern recursion is coded as a recurse into group 0, so it
won't be picked up here. Instead, we catch it when the OP_END is reached.
Other recursion is handled here. */
/* Whole-pattern recursion is coded as a recurse into group 0, and is
handled with OP_BRA above. Other recursion is handled here. */
case OP_CBRA:
case OP_CBRAPOS:
@ -5847,7 +6066,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
{
P = (heapframe *)((char *)N - frame_size);
memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
P->offset_top * sizeof(PCRE2_SIZE));
Foffset_top * sizeof(PCRE2_SIZE));
Foffset_top = P->offset_top;
Fcapture_last = P->capture_last;
Fcurrent_recurse = P->current_recurse;
@ -5930,10 +6149,10 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;
/* Fall through */
/* Unconditional end of subject assertion (\z) */
/* Unconditional end of subject assertion (\z). */
case OP_EOD:
if (Feptr < mb->end_subject) RRETURN(MATCH_NOMATCH);
if (Feptr < mb->true_end_subject) RRETURN(MATCH_NOMATCH);
if (mb->partial != 0)
{
mb->hitend = TRUE;
@ -6045,6 +6264,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case OP_NOT_WORD_BOUNDARY:
case OP_WORD_BOUNDARY:
case OP_NOT_UCP_WORD_BOUNDARY:
case OP_UCP_WORD_BOUNDARY:
if (Feptr == mb->check_subject) prev_is_word = FALSE; else
{
PCRE2_SPTR lastptr = Feptr - 1;
@ -6059,13 +6280,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
fc = *lastptr;
if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr;
#ifdef SUPPORT_UNICODE
if ((mb->poptions & PCRE2_UCP) != 0)
if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY)
{
if (fc == '_') prev_is_word = TRUE; else
{
int cat = UCD_CATEGORY(fc);
prev_is_word = (cat == ucp_L || cat == ucp_N);
}
int chartype = UCD_CHARTYPE(fc);
int category = PRIV(ucp_gentype)[chartype];
prev_is_word = (category == ucp_L || category == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc);
}
else
#endif /* SUPPORT_UNICODE */
@ -6093,13 +6313,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
fc = *Feptr;
if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr;
#ifdef SUPPORT_UNICODE
if ((mb->poptions & PCRE2_UCP) != 0)
if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY)
{
if (fc == '_') cur_is_word = TRUE; else
{
int cat = UCD_CATEGORY(fc);
cur_is_word = (cat == ucp_L || cat == ucp_N);
}
int chartype = UCD_CHARTYPE(fc);
int category = PRIV(ucp_gentype)[chartype];
cur_is_word = (category == ucp_L || category == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc);
}
else
#endif /* SUPPORT_UNICODE */
@ -6108,7 +6327,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* Now see if the situation is what we want */
if ((*Fecode++ == OP_WORD_BOUNDARY)?
if ((*Fecode++ == OP_WORD_BOUNDARY || Fop == OP_UCP_WORD_BOUNDARY)?
cur_is_word == prev_is_word : cur_is_word != prev_is_word)
RRETURN(MATCH_NOMATCH);
break;
@ -6254,7 +6473,7 @@ F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */
mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */
#ifdef DEBUG_SHOW_RMATCH
fprintf(stderr, "++ RETURN %d to %d\n", rrc, Freturn_id);
fprintf(stderr, "++ RETURN %d to RM%d\n", rrc, Freturn_id);
#endif
switch (Freturn_id)
@ -6263,7 +6482,7 @@ switch (Freturn_id)
LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16)
LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)
LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)
LBL(33) LBL(34) LBL(35) LBL(36)
LBL(33) LBL(34) LBL(35) LBL(36) LBL(37)
#ifdef SUPPORT_WIDE_CHARS
LBL(100) LBL(101)
@ -6551,6 +6770,7 @@ if (use_jit)
match_data, mcontext);
if (rc != PCRE2_ERROR_JIT_BADOPTION)
{
match_data->subject_length = length;
if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
{
length = CU2BYTES(length + was_zero_terminated);
@ -6719,7 +6939,7 @@ if (mcontext == NULL)
else mb->memctl = mcontext->memctl;
anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0;
firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0;
startline = (re->flags & PCRE2_STARTLINE) != 0;
bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?
true_end_subject : subject + mcontext->offset_limit;
@ -6742,6 +6962,7 @@ mb->callout_data = mcontext->callout_data;
mb->start_subject = subject;
mb->start_offset = start_offset;
mb->end_subject = end_subject;
mb->true_end_subject = true_end_subject;
mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;
mb->allowemptypartial = (re->max_lookbehind > 0) ||
(re->flags & PCRE2_MATCH_EMPTY) != 0;
@ -6801,7 +7022,7 @@ the pattern. It is not used at all if there are no capturing parentheses.
frame_size is the total size of each frame
match_data->heapframes is the pointer to the frames vector
match_data->heapframes_size is the total size of the vector
match_data->heapframes_size is the allocated size of the vector
We must pad the frame_size for alignment to ensure subsequent frames are as
aligned as heapframe. Whilst ovector is word-aligned due to being a PCRE2_SIZE
@ -6816,7 +7037,7 @@ frame_size = (offsetof(heapframe, ovector) +
smaller. */
mb->heap_limit = ((mcontext->heap_limit < re->limit_heap)?
mcontext->heap_limit : re->limit_heap) * 1024;
mcontext->heap_limit : re->limit_heap);
mb->match_limit = (mcontext->match_limit < re->limit_match)?
mcontext->match_limit : re->limit_match;
@ -6827,19 +7048,19 @@ mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
/* If a pattern has very many capturing parentheses, the frame size may be very
large. Set the initial frame vector size to ensure that there are at least 10
available frames, but enforce a minimum of START_FRAMES_SIZE. If this is
greater than the heap limit, get as large a vector as possible. Always round
the size to a multiple of the frame size. */
greater than the heap limit, get as large a vector as possible. */
heapframes_size = frame_size * 10;
if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE;
if (heapframes_size > mb->heap_limit)
if (heapframes_size / 1024 > mb->heap_limit)
{
if (frame_size > mb->heap_limit ) return PCRE2_ERROR_HEAPLIMIT;
heapframes_size = mb->heap_limit;
PCRE2_SIZE max_size = 1024 * mb->heap_limit;
if (max_size < frame_size) return PCRE2_ERROR_HEAPLIMIT;
heapframes_size = max_size;
}
/* If an existing frame vector in the match_data block is large enough, we can
use it.Otherwise, free any pre-existing vector and get a new one. */
use it. Otherwise, free any pre-existing vector and get a new one. */
if (match_data->heapframes_size < heapframes_size)
{
@ -7286,9 +7507,17 @@ for(;;)
mb->end_offset_top = 0;
mb->skip_arg_count = 0;
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "++ Calling match()\n");
#endif
rc = match(start_match, mb->start_code, re->top_bracket, frame_size,
match_data, mb);
#ifdef DEBUG_SHOW_OPS
fprintf(stderr, "++ match() returned %d\n\n", rc);
#endif
if (mb->hitend && start_partial == NULL)
{
start_partial = mb->start_used_ptr;
@ -7436,6 +7665,7 @@ if (utf && end_subject != true_end_subject &&
if (start_match >= true_end_subject)
{
rc = MATCH_NOMATCH; /* In case it was partial */
match_partial = NULL;
break;
}
@ -7485,6 +7715,7 @@ if (rc == MATCH_MATCH)
{
match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)?
0 : (int)mb->end_offset_top/2 + 1;
match_data->subject_length = length;
match_data->startchar = start_match - subject;
match_data->leftchar = mb->start_used_ptr - subject;
match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?
@ -7499,6 +7730,7 @@ if (rc == MATCH_MATCH)
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
}
else match_data->subject = subject;
return match_data->rc;
}
@ -7520,6 +7752,7 @@ PCRE2_ERROR_PARTIAL. */
else if (match_partial != NULL)
{
match_data->subject = subject;
match_data->subject_length = length;
match_data->ovector[0] = match_partial - subject;
match_data->ovector[1] = end_subject - subject;
match_data->startchar = match_partial - subject;

View File

@ -170,4 +170,16 @@ return offsetof(pcre2_match_data, ovector) +
2 * (match_data->oveccount) * sizeof(PCRE2_SIZE);
}
/*************************************************
* Get heapframes size *
*************************************************/
PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION
pcre2_get_match_data_heapframes_size(pcre2_match_data *match_data)
{
return match_data->heapframes_size;
}
/* End of pcre2_match_data.c */

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2021 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -256,6 +256,7 @@ for (;;)
/* Skip over things that don't match chars */
case OP_REVERSE:
case OP_VREVERSE:
case OP_CREF:
case OP_DNCREF:
case OP_RREF:
@ -273,6 +274,8 @@ for (;;)
case OP_DOLLM:
case OP_NOT_WORD_BOUNDARY:
case OP_WORD_BOUNDARY:
case OP_NOT_UCP_WORD_BOUNDARY:
case OP_UCP_WORD_BOUNDARY:
cc += PRIV(OP_lengths)[*cc];
break;
@ -976,6 +979,7 @@ do
while (try_next) /* Loop for items in this branch */
{
int rc;
PCRE2_SPTR ncode;
uint8_t *classmap = NULL;
#ifdef SUPPORT_WIDE_CHARS
PCRE2_UCHAR xclassflags;
@ -1054,6 +1058,7 @@ do
case OP_REF:
case OP_REFI:
case OP_REVERSE:
case OP_VREVERSE:
case OP_RREF:
case OP_SCOND:
case OP_SET_SOM:
@ -1101,13 +1106,100 @@ do
case OP_WORD_BOUNDARY:
case OP_NOT_WORD_BOUNDARY:
case OP_UCP_WORD_BOUNDARY:
case OP_NOT_UCP_WORD_BOUNDARY:
tcode++;
break;
/* If we hit a bracket or a positive lookahead assertion, recurse to set
bits from within the subpattern. If it can't find anything, we have to
give up. If it finds some mandatory character(s), we are done for this
branch. Otherwise, carry on scanning after the subpattern. */
/* For a positive lookahead assertion, inspect what immediately follows,
ignoring intermediate assertions and callouts. If the next item is one
that sets a mandatory character, skip this assertion. Otherwise, treat it
the same as other bracket groups. */
case OP_ASSERT:
case OP_ASSERT_NA:
ncode = tcode + GET(tcode, 1);
while (*ncode == OP_ALT) ncode += GET(ncode, 1);
ncode += 1 + LINK_SIZE;
/* Skip irrelevant items */
for (BOOL done = FALSE; !done;)
{
switch (*ncode)
{
case OP_ASSERT:
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
case OP_ASSERT_NA:
case OP_ASSERTBACK_NA:
ncode += GET(ncode, 1);
while (*ncode == OP_ALT) ncode += GET(ncode, 1);
ncode += 1 + LINK_SIZE;
break;
case OP_WORD_BOUNDARY:
case OP_NOT_WORD_BOUNDARY:
case OP_UCP_WORD_BOUNDARY:
case OP_NOT_UCP_WORD_BOUNDARY:
ncode++;
break;
case OP_CALLOUT:
ncode += PRIV(OP_lengths)[OP_CALLOUT];
break;
case OP_CALLOUT_STR:
ncode += GET(ncode, 1 + 2*LINK_SIZE);
break;
default:
done = TRUE;
break;
}
}
/* Now check the next significant item. */
switch(*ncode)
{
default:
break;
case OP_PROP:
if (ncode[1] != PT_CLIST) break;
/* Fall through */
case OP_ANYNL:
case OP_CHAR:
case OP_CHARI:
case OP_EXACT:
case OP_EXACTI:
case OP_HSPACE:
case OP_MINPLUS:
case OP_MINPLUSI:
case OP_PLUS:
case OP_PLUSI:
case OP_POSPLUS:
case OP_POSPLUSI:
case OP_VSPACE:
/* Note that these types will only be present in non-UCP mode. */
case OP_DIGIT:
case OP_NOT_DIGIT:
case OP_WORDCHAR:
case OP_NOT_WORDCHAR:
case OP_WHITESPACE:
case OP_NOT_WHITESPACE:
tcode = ncode;
continue; /* With the following significant opcode */
}
/* Fall through */
/* For a group bracket or a positive assertion without an immediately
following mandatory setting, recurse to set bits from within the
subpattern. If it can't find anything, we have to give up. If it finds
some mandatory character(s), we are done for this branch. Otherwise,
carry on scanning after the subpattern. */
case OP_BRA:
case OP_SBRA:
@ -1119,8 +1211,6 @@ do
case OP_SCBRAPOS:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_ASSERT:
case OP_ASSERT_NA:
rc = set_start_bits(re, tcode, utf, ucp, depthptr);
if (rc == SSB_DONE)
{

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2018 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -309,6 +309,7 @@ Returns: if successful: 0
PCRE2_ERROR_NOSUBSTRING: no such substring
PCRE2_ERROR_UNAVAILABLE: ovector is too small
PCRE2_ERROR_UNSET: substring is not set
PCRE2_ERROR_INVALIDOFFSET: internal error, should not occur
*/
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
@ -341,6 +342,8 @@ else /* Matched using pcre2_dfa_match() */
left = match_data->ovector[stringnumber*2];
right = match_data->ovector[stringnumber*2+1];
if (left > match_data->subject_length || right > match_data->subject_length)
return PCRE2_ERROR_INVALIDOFFSET;
if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left;
return 0;
}
@ -442,7 +445,7 @@ Returns: nothing
*/
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
pcre2_substring_list_free(PCRE2_SPTR *list)
pcre2_substring_list_free(PCRE2_UCHAR **list)
{
if (list != NULL)
{

File diff suppressed because it is too large Load Diff

View File

@ -166,29 +166,29 @@ enum {
/* These are the bidi class values. */
enum {
ucp_bidiAL, /* Arabic letter */
ucp_bidiAN, /* Arabic number */
ucp_bidiB, /* Paragraph separator */
ucp_bidiBN, /* Boundary neutral */
ucp_bidiCS, /* Common separator */
ucp_bidiEN, /* European number */
ucp_bidiES, /* European separator */
ucp_bidiET, /* European terminator */
ucp_bidiFSI, /* First strong isolate */
ucp_bidiL, /* Left to right */
ucp_bidiLRE, /* Left to right embedding */
ucp_bidiLRI, /* Left to right isolate */
ucp_bidiLRO, /* Left to right override */
ucp_bidiNSM, /* Non-spacing mark */
ucp_bidiON, /* Other neutral */
ucp_bidiPDF, /* Pop directional format */
ucp_bidiPDI, /* Pop directional isolate */
ucp_bidiR, /* Right to left */
ucp_bidiRLE, /* Right to left embedding */
ucp_bidiRLI, /* Right to left isolate */
ucp_bidiRLO, /* Right to left override */
ucp_bidiS, /* Segment separator */
ucp_bidiWS, /* White space */
ucp_bidiAL, /* Arabic_Letter */
ucp_bidiAN, /* Arabic_Number */
ucp_bidiB, /* Paragraph_Separator */
ucp_bidiBN, /* Boundary_Neutral */
ucp_bidiCS, /* Common_Separator */
ucp_bidiEN, /* European_Number */
ucp_bidiES, /* European_Separator */
ucp_bidiET, /* European_Terminator */
ucp_bidiFSI, /* First_Strong_Isolate */
ucp_bidiL, /* Left_To_Right */
ucp_bidiLRE, /* Left_To_Right_Embedding */
ucp_bidiLRI, /* Left_To_Right_Isolate */
ucp_bidiLRO, /* Left_To_Right_Override */
ucp_bidiNSM, /* Nonspacing_Mark */
ucp_bidiON, /* Other_Neutral */
ucp_bidiPDF, /* Pop_Directional_Format */
ucp_bidiPDI, /* Pop_Directional_Isolate */
ucp_bidiR, /* Right_To_Left */
ucp_bidiRLE, /* Right_To_Left_Embedding */
ucp_bidiRLI, /* Right_To_Left_Isolate */
ucp_bidiRLO, /* Right_To_Left_Override */
ucp_bidiS, /* Segment_Separator */
ucp_bidiWS, /* White_Space */
};
/* These are grapheme break properties. The Extended Pictographic property
@ -380,6 +380,8 @@ enum {
ucp_Tangsa,
ucp_Toto,
ucp_Vithkuqi,
ucp_Kawi,
ucp_Nag_Mundari,
/* This must be last */
ucp_Script_Count

View File

@ -265,6 +265,7 @@ the "loose matching" rules that Unicode advises and Perl uses. */
#define STRING_kana0 STR_k STR_a STR_n STR_a "\0"
#define STRING_kannada0 STR_k STR_a STR_n STR_n STR_a STR_d STR_a "\0"
#define STRING_katakana0 STR_k STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
#define STRING_kawi0 STR_k STR_a STR_w STR_i "\0"
#define STRING_kayahli0 STR_k STR_a STR_y STR_a STR_h STR_l STR_i "\0"
#define STRING_khar0 STR_k STR_h STR_a STR_r "\0"
#define STRING_kharoshthi0 STR_k STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
@ -347,6 +348,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */
#define STRING_mymr0 STR_m STR_y STR_m STR_r "\0"
#define STRING_n0 STR_n "\0"
#define STRING_nabataean0 STR_n STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0"
#define STRING_nagm0 STR_n STR_a STR_g STR_m "\0"
#define STRING_nagmundari0 STR_n STR_a STR_g STR_m STR_u STR_n STR_d STR_a STR_r STR_i "\0"
#define STRING_nand0 STR_n STR_a STR_n STR_d "\0"
#define STRING_nandinagari0 STR_n STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i "\0"
#define STRING_narb0 STR_n STR_a STR_r STR_b "\0"
@ -753,6 +756,7 @@ const char PRIV(utt_names)[] =
STRING_kana0
STRING_kannada0
STRING_katakana0
STRING_kawi0
STRING_kayahli0
STRING_khar0
STRING_kharoshthi0
@ -835,6 +839,8 @@ const char PRIV(utt_names)[] =
STRING_mymr0
STRING_n0
STRING_nabataean0
STRING_nagm0
STRING_nagmundari0
STRING_nand0
STRING_nandinagari0
STRING_narb0
@ -1241,280 +1247,283 @@ const ucp_type_table PRIV(utt)[] = {
{ 1665, PT_SCX, ucp_Katakana },
{ 1670, PT_SCX, ucp_Kannada },
{ 1678, PT_SCX, ucp_Katakana },
{ 1687, PT_SCX, ucp_Kayah_Li },
{ 1695, PT_SC, ucp_Kharoshthi },
{ 1687, PT_SC, ucp_Kawi },
{ 1692, PT_SCX, ucp_Kayah_Li },
{ 1700, PT_SC, ucp_Kharoshthi },
{ 1711, PT_SC, ucp_Khitan_Small_Script },
{ 1729, PT_SC, ucp_Khmer },
{ 1735, PT_SC, ucp_Khmer },
{ 1740, PT_SCX, ucp_Khojki },
{ 1705, PT_SC, ucp_Kharoshthi },
{ 1716, PT_SC, ucp_Khitan_Small_Script },
{ 1734, PT_SC, ucp_Khmer },
{ 1740, PT_SC, ucp_Khmer },
{ 1745, PT_SCX, ucp_Khojki },
{ 1752, PT_SCX, ucp_Khudawadi },
{ 1762, PT_SC, ucp_Khitan_Small_Script },
{ 1767, PT_SCX, ucp_Kannada },
{ 1772, PT_SCX, ucp_Kaithi },
{ 1777, PT_GC, ucp_L },
{ 1779, PT_LAMP, 0 },
{ 1782, PT_SC, ucp_Tai_Tham },
{ 1787, PT_SC, ucp_Lao },
{ 1791, PT_SC, ucp_Lao },
{ 1796, PT_SCX, ucp_Latin },
{ 1802, PT_SCX, ucp_Latin },
{ 1807, PT_LAMP, 0 },
{ 1810, PT_SC, ucp_Lepcha },
{ 1750, PT_SCX, ucp_Khojki },
{ 1757, PT_SCX, ucp_Khudawadi },
{ 1767, PT_SC, ucp_Khitan_Small_Script },
{ 1772, PT_SCX, ucp_Kannada },
{ 1777, PT_SCX, ucp_Kaithi },
{ 1782, PT_GC, ucp_L },
{ 1784, PT_LAMP, 0 },
{ 1787, PT_SC, ucp_Tai_Tham },
{ 1792, PT_SC, ucp_Lao },
{ 1796, PT_SC, ucp_Lao },
{ 1801, PT_SCX, ucp_Latin },
{ 1807, PT_SCX, ucp_Latin },
{ 1812, PT_LAMP, 0 },
{ 1815, PT_SC, ucp_Lepcha },
{ 1822, PT_SCX, ucp_Limbu },
{ 1820, PT_SC, ucp_Lepcha },
{ 1827, PT_SCX, ucp_Limbu },
{ 1833, PT_SCX, ucp_Linear_A },
{ 1838, PT_SCX, ucp_Linear_B },
{ 1843, PT_SCX, ucp_Linear_A },
{ 1851, PT_SCX, ucp_Linear_B },
{ 1859, PT_SC, ucp_Lisu },
{ 1864, PT_PC, ucp_Ll },
{ 1867, PT_PC, ucp_Lm },
{ 1870, PT_PC, ucp_Lo },
{ 1873, PT_BOOL, ucp_Logical_Order_Exception },
{ 1877, PT_BOOL, ucp_Logical_Order_Exception },
{ 1899, PT_BOOL, ucp_Lowercase },
{ 1905, PT_BOOL, ucp_Lowercase },
{ 1915, PT_PC, ucp_Lt },
{ 1918, PT_PC, ucp_Lu },
{ 1921, PT_SC, ucp_Lycian },
{ 1832, PT_SCX, ucp_Limbu },
{ 1838, PT_SCX, ucp_Linear_A },
{ 1843, PT_SCX, ucp_Linear_B },
{ 1848, PT_SCX, ucp_Linear_A },
{ 1856, PT_SCX, ucp_Linear_B },
{ 1864, PT_SC, ucp_Lisu },
{ 1869, PT_PC, ucp_Ll },
{ 1872, PT_PC, ucp_Lm },
{ 1875, PT_PC, ucp_Lo },
{ 1878, PT_BOOL, ucp_Logical_Order_Exception },
{ 1882, PT_BOOL, ucp_Logical_Order_Exception },
{ 1904, PT_BOOL, ucp_Lowercase },
{ 1910, PT_BOOL, ucp_Lowercase },
{ 1920, PT_PC, ucp_Lt },
{ 1923, PT_PC, ucp_Lu },
{ 1926, PT_SC, ucp_Lycian },
{ 1933, PT_SC, ucp_Lydian },
{ 1931, PT_SC, ucp_Lycian },
{ 1938, PT_SC, ucp_Lydian },
{ 1945, PT_GC, ucp_M },
{ 1947, PT_SCX, ucp_Mahajani },
{ 1956, PT_SCX, ucp_Mahajani },
{ 1961, PT_SC, ucp_Makasar },
{ 1943, PT_SC, ucp_Lydian },
{ 1950, PT_GC, ucp_M },
{ 1952, PT_SCX, ucp_Mahajani },
{ 1961, PT_SCX, ucp_Mahajani },
{ 1966, PT_SC, ucp_Makasar },
{ 1974, PT_SCX, ucp_Malayalam },
{ 1984, PT_SCX, ucp_Mandaic },
{ 1971, PT_SC, ucp_Makasar },
{ 1979, PT_SCX, ucp_Malayalam },
{ 1989, PT_SCX, ucp_Mandaic },
{ 1997, PT_SCX, ucp_Manichaean },
{ 1994, PT_SCX, ucp_Mandaic },
{ 2002, PT_SCX, ucp_Manichaean },
{ 2013, PT_SC, ucp_Marchen },
{ 2007, PT_SCX, ucp_Manichaean },
{ 2018, PT_SC, ucp_Marchen },
{ 2026, PT_SCX, ucp_Masaram_Gondi },
{ 2039, PT_BOOL, ucp_Math },
{ 2044, PT_PC, ucp_Mc },
{ 2047, PT_PC, ucp_Me },
{ 2050, PT_SC, ucp_Medefaidrin },
{ 2062, PT_SC, ucp_Medefaidrin },
{ 2067, PT_SC, ucp_Meetei_Mayek },
{ 2079, PT_SC, ucp_Mende_Kikakui },
{ 2023, PT_SC, ucp_Marchen },
{ 2031, PT_SCX, ucp_Masaram_Gondi },
{ 2044, PT_BOOL, ucp_Math },
{ 2049, PT_PC, ucp_Mc },
{ 2052, PT_PC, ucp_Me },
{ 2055, PT_SC, ucp_Medefaidrin },
{ 2067, PT_SC, ucp_Medefaidrin },
{ 2072, PT_SC, ucp_Meetei_Mayek },
{ 2084, PT_SC, ucp_Mende_Kikakui },
{ 2097, PT_SC, ucp_Meroitic_Cursive },
{ 2102, PT_SC, ucp_Meroitic_Hieroglyphs },
{ 2107, PT_SC, ucp_Meroitic_Cursive },
{ 2123, PT_SC, ucp_Meroitic_Hieroglyphs },
{ 2143, PT_SC, ucp_Miao },
{ 2148, PT_SCX, ucp_Malayalam },
{ 2153, PT_PC, ucp_Mn },
{ 2156, PT_SCX, ucp_Modi },
{ 2161, PT_SCX, ucp_Mongolian },
{ 2089, PT_SC, ucp_Mende_Kikakui },
{ 2102, PT_SC, ucp_Meroitic_Cursive },
{ 2107, PT_SC, ucp_Meroitic_Hieroglyphs },
{ 2112, PT_SC, ucp_Meroitic_Cursive },
{ 2128, PT_SC, ucp_Meroitic_Hieroglyphs },
{ 2148, PT_SC, ucp_Miao },
{ 2153, PT_SCX, ucp_Malayalam },
{ 2158, PT_PC, ucp_Mn },
{ 2161, PT_SCX, ucp_Modi },
{ 2166, PT_SCX, ucp_Mongolian },
{ 2176, PT_SC, ucp_Mro },
{ 2180, PT_SC, ucp_Mro },
{ 2185, PT_SC, ucp_Meetei_Mayek },
{ 2190, PT_SCX, ucp_Multani },
{ 2171, PT_SCX, ucp_Mongolian },
{ 2181, PT_SC, ucp_Mro },
{ 2185, PT_SC, ucp_Mro },
{ 2190, PT_SC, ucp_Meetei_Mayek },
{ 2195, PT_SCX, ucp_Multani },
{ 2203, PT_SCX, ucp_Myanmar },
{ 2211, PT_SCX, ucp_Myanmar },
{ 2216, PT_GC, ucp_N },
{ 2218, PT_SC, ucp_Nabataean },
{ 2228, PT_SCX, ucp_Nandinagari },
{ 2233, PT_SCX, ucp_Nandinagari },
{ 2245, PT_SC, ucp_Old_North_Arabian },
{ 2250, PT_SC, ucp_Nabataean },
{ 2255, PT_BOOL, ucp_Noncharacter_Code_Point },
{ 2261, PT_PC, ucp_Nd },
{ 2264, PT_SC, ucp_Newa },
{ 2269, PT_SC, ucp_New_Tai_Lue },
{ 2279, PT_SCX, ucp_Nko },
{ 2283, PT_SCX, ucp_Nko },
{ 2288, PT_PC, ucp_Nl },
{ 2291, PT_PC, ucp_No },
{ 2294, PT_BOOL, ucp_Noncharacter_Code_Point },
{ 2316, PT_SC, ucp_Nushu },
{ 2321, PT_SC, ucp_Nushu },
{ 2327, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
{ 2348, PT_SC, ucp_Ogham },
{ 2353, PT_SC, ucp_Ogham },
{ 2359, PT_SC, ucp_Ol_Chiki },
{ 2367, PT_SC, ucp_Ol_Chiki },
{ 2372, PT_SC, ucp_Old_Hungarian },
{ 2385, PT_SC, ucp_Old_Italic },
{ 2395, PT_SC, ucp_Old_North_Arabian },
{ 2411, PT_SCX, ucp_Old_Permic },
{ 2421, PT_SC, ucp_Old_Persian },
{ 2432, PT_SC, ucp_Old_Sogdian },
{ 2443, PT_SC, ucp_Old_South_Arabian },
{ 2459, PT_SC, ucp_Old_Turkic },
{ 2469, PT_SCX, ucp_Old_Uyghur },
{ 2479, PT_SCX, ucp_Oriya },
{ 2485, PT_SC, ucp_Old_Turkic },
{ 2490, PT_SCX, ucp_Oriya },
{ 2495, PT_SC, ucp_Osage },
{ 2501, PT_SC, ucp_Osage },
{ 2506, PT_SC, ucp_Osmanya },
{ 2511, PT_SC, ucp_Osmanya },
{ 2519, PT_SCX, ucp_Old_Uyghur },
{ 2524, PT_GC, ucp_P },
{ 2526, PT_SC, ucp_Pahawh_Hmong },
{ 2538, PT_SC, ucp_Palmyrene },
{ 2543, PT_SC, ucp_Palmyrene },
{ 2553, PT_BOOL, ucp_Pattern_Syntax },
{ 2560, PT_BOOL, ucp_Pattern_Syntax },
{ 2574, PT_BOOL, ucp_Pattern_White_Space },
{ 2592, PT_BOOL, ucp_Pattern_White_Space },
{ 2598, PT_SC, ucp_Pau_Cin_Hau },
{ 2603, PT_SC, ucp_Pau_Cin_Hau },
{ 2613, PT_PC, ucp_Pc },
{ 2616, PT_BOOL, ucp_Prepended_Concatenation_Mark },
{ 2620, PT_PC, ucp_Pd },
{ 2623, PT_PC, ucp_Pe },
{ 2626, PT_SCX, ucp_Old_Permic },
{ 2631, PT_PC, ucp_Pf },
{ 2634, PT_SCX, ucp_Phags_Pa },
{ 2639, PT_SCX, ucp_Phags_Pa },
{ 2647, PT_SC, ucp_Inscriptional_Pahlavi },
{ 2652, PT_SCX, ucp_Psalter_Pahlavi },
{ 2657, PT_SC, ucp_Phoenician },
{ 2662, PT_SC, ucp_Phoenician },
{ 2673, PT_PC, ucp_Pi },
{ 2676, PT_SC, ucp_Miao },
{ 2681, PT_PC, ucp_Po },
{ 2684, PT_BOOL, ucp_Prepended_Concatenation_Mark },
{ 2711, PT_SC, ucp_Inscriptional_Parthian },
{ 2716, PT_PC, ucp_Ps },
{ 2719, PT_SCX, ucp_Psalter_Pahlavi },
{ 2734, PT_SCX, ucp_Coptic },
{ 2739, PT_SC, ucp_Inherited },
{ 2744, PT_BOOL, ucp_Quotation_Mark },
{ 2750, PT_BOOL, ucp_Quotation_Mark },
{ 2764, PT_BOOL, ucp_Radical },
{ 2772, PT_BOOL, ucp_Regional_Indicator },
{ 2790, PT_SC, ucp_Rejang },
{ 2797, PT_BOOL, ucp_Regional_Indicator },
{ 2800, PT_SC, ucp_Rejang },
{ 2805, PT_SCX, ucp_Hanifi_Rohingya },
{ 2810, PT_SC, ucp_Runic },
{ 2816, PT_SC, ucp_Runic },
{ 2821, PT_GC, ucp_S },
{ 2823, PT_SC, ucp_Samaritan },
{ 2833, PT_SC, ucp_Samaritan },
{ 2838, PT_SC, ucp_Old_South_Arabian },
{ 2843, PT_SC, ucp_Saurashtra },
{ 2848, PT_SC, ucp_Saurashtra },
{ 2859, PT_PC, ucp_Sc },
{ 2862, PT_BOOL, ucp_Soft_Dotted },
{ 2865, PT_BOOL, ucp_Sentence_Terminal },
{ 2882, PT_SC, ucp_SignWriting },
{ 2887, PT_SCX, ucp_Sharada },
{ 2895, PT_SC, ucp_Shavian },
{ 2903, PT_SC, ucp_Shavian },
{ 2200, PT_SCX, ucp_Multani },
{ 2208, PT_SCX, ucp_Myanmar },
{ 2216, PT_SCX, ucp_Myanmar },
{ 2221, PT_GC, ucp_N },
{ 2223, PT_SC, ucp_Nabataean },
{ 2233, PT_SC, ucp_Nag_Mundari },
{ 2238, PT_SC, ucp_Nag_Mundari },
{ 2249, PT_SCX, ucp_Nandinagari },
{ 2254, PT_SCX, ucp_Nandinagari },
{ 2266, PT_SC, ucp_Old_North_Arabian },
{ 2271, PT_SC, ucp_Nabataean },
{ 2276, PT_BOOL, ucp_Noncharacter_Code_Point },
{ 2282, PT_PC, ucp_Nd },
{ 2285, PT_SC, ucp_Newa },
{ 2290, PT_SC, ucp_New_Tai_Lue },
{ 2300, PT_SCX, ucp_Nko },
{ 2304, PT_SCX, ucp_Nko },
{ 2309, PT_PC, ucp_Nl },
{ 2312, PT_PC, ucp_No },
{ 2315, PT_BOOL, ucp_Noncharacter_Code_Point },
{ 2337, PT_SC, ucp_Nushu },
{ 2342, PT_SC, ucp_Nushu },
{ 2348, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
{ 2369, PT_SC, ucp_Ogham },
{ 2374, PT_SC, ucp_Ogham },
{ 2380, PT_SC, ucp_Ol_Chiki },
{ 2388, PT_SC, ucp_Ol_Chiki },
{ 2393, PT_SC, ucp_Old_Hungarian },
{ 2406, PT_SC, ucp_Old_Italic },
{ 2416, PT_SC, ucp_Old_North_Arabian },
{ 2432, PT_SCX, ucp_Old_Permic },
{ 2442, PT_SC, ucp_Old_Persian },
{ 2453, PT_SC, ucp_Old_Sogdian },
{ 2464, PT_SC, ucp_Old_South_Arabian },
{ 2480, PT_SC, ucp_Old_Turkic },
{ 2490, PT_SCX, ucp_Old_Uyghur },
{ 2500, PT_SCX, ucp_Oriya },
{ 2506, PT_SC, ucp_Old_Turkic },
{ 2511, PT_SCX, ucp_Oriya },
{ 2516, PT_SC, ucp_Osage },
{ 2522, PT_SC, ucp_Osage },
{ 2527, PT_SC, ucp_Osmanya },
{ 2532, PT_SC, ucp_Osmanya },
{ 2540, PT_SCX, ucp_Old_Uyghur },
{ 2545, PT_GC, ucp_P },
{ 2547, PT_SC, ucp_Pahawh_Hmong },
{ 2559, PT_SC, ucp_Palmyrene },
{ 2564, PT_SC, ucp_Palmyrene },
{ 2574, PT_BOOL, ucp_Pattern_Syntax },
{ 2581, PT_BOOL, ucp_Pattern_Syntax },
{ 2595, PT_BOOL, ucp_Pattern_White_Space },
{ 2613, PT_BOOL, ucp_Pattern_White_Space },
{ 2619, PT_SC, ucp_Pau_Cin_Hau },
{ 2624, PT_SC, ucp_Pau_Cin_Hau },
{ 2634, PT_PC, ucp_Pc },
{ 2637, PT_BOOL, ucp_Prepended_Concatenation_Mark },
{ 2641, PT_PC, ucp_Pd },
{ 2644, PT_PC, ucp_Pe },
{ 2647, PT_SCX, ucp_Old_Permic },
{ 2652, PT_PC, ucp_Pf },
{ 2655, PT_SCX, ucp_Phags_Pa },
{ 2660, PT_SCX, ucp_Phags_Pa },
{ 2668, PT_SC, ucp_Inscriptional_Pahlavi },
{ 2673, PT_SCX, ucp_Psalter_Pahlavi },
{ 2678, PT_SC, ucp_Phoenician },
{ 2683, PT_SC, ucp_Phoenician },
{ 2694, PT_PC, ucp_Pi },
{ 2697, PT_SC, ucp_Miao },
{ 2702, PT_PC, ucp_Po },
{ 2705, PT_BOOL, ucp_Prepended_Concatenation_Mark },
{ 2732, PT_SC, ucp_Inscriptional_Parthian },
{ 2737, PT_PC, ucp_Ps },
{ 2740, PT_SCX, ucp_Psalter_Pahlavi },
{ 2755, PT_SCX, ucp_Coptic },
{ 2760, PT_SC, ucp_Inherited },
{ 2765, PT_BOOL, ucp_Quotation_Mark },
{ 2771, PT_BOOL, ucp_Quotation_Mark },
{ 2785, PT_BOOL, ucp_Radical },
{ 2793, PT_BOOL, ucp_Regional_Indicator },
{ 2811, PT_SC, ucp_Rejang },
{ 2818, PT_BOOL, ucp_Regional_Indicator },
{ 2821, PT_SC, ucp_Rejang },
{ 2826, PT_SCX, ucp_Hanifi_Rohingya },
{ 2831, PT_SC, ucp_Runic },
{ 2837, PT_SC, ucp_Runic },
{ 2842, PT_GC, ucp_S },
{ 2844, PT_SC, ucp_Samaritan },
{ 2854, PT_SC, ucp_Samaritan },
{ 2859, PT_SC, ucp_Old_South_Arabian },
{ 2864, PT_SC, ucp_Saurashtra },
{ 2869, PT_SC, ucp_Saurashtra },
{ 2880, PT_PC, ucp_Sc },
{ 2883, PT_BOOL, ucp_Soft_Dotted },
{ 2886, PT_BOOL, ucp_Sentence_Terminal },
{ 2903, PT_SC, ucp_SignWriting },
{ 2908, PT_SCX, ucp_Sharada },
{ 2913, PT_SC, ucp_Siddham },
{ 2918, PT_SC, ucp_Siddham },
{ 2926, PT_SC, ucp_SignWriting },
{ 2938, PT_SCX, ucp_Khudawadi },
{ 2943, PT_SCX, ucp_Sinhala },
{ 2948, PT_SCX, ucp_Sinhala },
{ 2956, PT_PC, ucp_Sk },
{ 2959, PT_PC, ucp_Sm },
{ 2962, PT_PC, ucp_So },
{ 2965, PT_BOOL, ucp_Soft_Dotted },
{ 2976, PT_SCX, ucp_Sogdian },
{ 2981, PT_SCX, ucp_Sogdian },
{ 2989, PT_SC, ucp_Old_Sogdian },
{ 2994, PT_SC, ucp_Sora_Sompeng },
{ 2999, PT_SC, ucp_Sora_Sompeng },
{ 3011, PT_SC, ucp_Soyombo },
{ 3016, PT_SC, ucp_Soyombo },
{ 3024, PT_BOOL, ucp_White_Space },
{ 3030, PT_BOOL, ucp_Sentence_Terminal },
{ 3036, PT_SC, ucp_Sundanese },
{ 3041, PT_SC, ucp_Sundanese },
{ 3051, PT_SCX, ucp_Syloti_Nagri },
{ 3056, PT_SCX, ucp_Syloti_Nagri },
{ 3068, PT_SCX, ucp_Syriac },
{ 3073, PT_SCX, ucp_Syriac },
{ 3080, PT_SCX, ucp_Tagalog },
{ 3088, PT_SCX, ucp_Tagbanwa },
{ 3093, PT_SCX, ucp_Tagbanwa },
{ 3102, PT_SCX, ucp_Tai_Le },
{ 3108, PT_SC, ucp_Tai_Tham },
{ 3116, PT_SC, ucp_Tai_Viet },
{ 3124, PT_SCX, ucp_Takri },
{ 3129, PT_SCX, ucp_Takri },
{ 3135, PT_SCX, ucp_Tai_Le },
{ 3140, PT_SC, ucp_New_Tai_Lue },
{ 3145, PT_SCX, ucp_Tamil },
{ 3151, PT_SCX, ucp_Tamil },
{ 3156, PT_SC, ucp_Tangut },
{ 3161, PT_SC, ucp_Tangsa },
{ 3168, PT_SC, ucp_Tangut },
{ 3175, PT_SC, ucp_Tai_Viet },
{ 3180, PT_SCX, ucp_Telugu },
{ 3185, PT_SCX, ucp_Telugu },
{ 3192, PT_BOOL, ucp_Terminal_Punctuation },
{ 3197, PT_BOOL, ucp_Terminal_Punctuation },
{ 3217, PT_SC, ucp_Tifinagh },
{ 3222, PT_SCX, ucp_Tagalog },
{ 3227, PT_SCX, ucp_Thaana },
{ 3232, PT_SCX, ucp_Thaana },
{ 3239, PT_SC, ucp_Thai },
{ 3244, PT_SC, ucp_Tibetan },
{ 3252, PT_SC, ucp_Tibetan },
{ 3257, PT_SC, ucp_Tifinagh },
{ 3266, PT_SCX, ucp_Tirhuta },
{ 3271, PT_SCX, ucp_Tirhuta },
{ 3279, PT_SC, ucp_Tangsa },
{ 3284, PT_SC, ucp_Toto },
{ 3289, PT_SC, ucp_Ugaritic },
{ 3294, PT_SC, ucp_Ugaritic },
{ 3303, PT_BOOL, ucp_Unified_Ideograph },
{ 3309, PT_BOOL, ucp_Unified_Ideograph },
{ 3326, PT_SC, ucp_Unknown },
{ 3334, PT_BOOL, ucp_Uppercase },
{ 3340, PT_BOOL, ucp_Uppercase },
{ 3350, PT_SC, ucp_Vai },
{ 3354, PT_SC, ucp_Vai },
{ 3359, PT_BOOL, ucp_Variation_Selector },
{ 3377, PT_SC, ucp_Vithkuqi },
{ 3382, PT_SC, ucp_Vithkuqi },
{ 3391, PT_BOOL, ucp_Variation_Selector },
{ 3394, PT_SC, ucp_Wancho },
{ 3401, PT_SC, ucp_Warang_Citi },
{ 3406, PT_SC, ucp_Warang_Citi },
{ 3417, PT_SC, ucp_Wancho },
{ 3422, PT_BOOL, ucp_White_Space },
{ 3433, PT_BOOL, ucp_White_Space },
{ 3440, PT_ALNUM, 0 },
{ 3444, PT_BOOL, ucp_XID_Continue },
{ 3449, PT_BOOL, ucp_XID_Continue },
{ 3461, PT_BOOL, ucp_XID_Start },
{ 3466, PT_BOOL, ucp_XID_Start },
{ 3475, PT_SC, ucp_Old_Persian },
{ 3480, PT_PXSPACE, 0 },
{ 3484, PT_SPACE, 0 },
{ 3488, PT_SC, ucp_Cuneiform },
{ 3493, PT_UCNC, 0 },
{ 3497, PT_WORD, 0 },
{ 3501, PT_SCX, ucp_Yezidi },
{ 3506, PT_SCX, ucp_Yezidi },
{ 3513, PT_SCX, ucp_Yi },
{ 3516, PT_SCX, ucp_Yi },
{ 3521, PT_GC, ucp_Z },
{ 3523, PT_SC, ucp_Zanabazar_Square },
{ 3539, PT_SC, ucp_Zanabazar_Square },
{ 3544, PT_SC, ucp_Inherited },
{ 3549, PT_PC, ucp_Zl },
{ 3552, PT_PC, ucp_Zp },
{ 3555, PT_PC, ucp_Zs },
{ 3558, PT_SC, ucp_Common },
{ 3563, PT_SC, ucp_Unknown }
{ 2916, PT_SC, ucp_Shavian },
{ 2924, PT_SC, ucp_Shavian },
{ 2929, PT_SCX, ucp_Sharada },
{ 2934, PT_SC, ucp_Siddham },
{ 2939, PT_SC, ucp_Siddham },
{ 2947, PT_SC, ucp_SignWriting },
{ 2959, PT_SCX, ucp_Khudawadi },
{ 2964, PT_SCX, ucp_Sinhala },
{ 2969, PT_SCX, ucp_Sinhala },
{ 2977, PT_PC, ucp_Sk },
{ 2980, PT_PC, ucp_Sm },
{ 2983, PT_PC, ucp_So },
{ 2986, PT_BOOL, ucp_Soft_Dotted },
{ 2997, PT_SCX, ucp_Sogdian },
{ 3002, PT_SCX, ucp_Sogdian },
{ 3010, PT_SC, ucp_Old_Sogdian },
{ 3015, PT_SC, ucp_Sora_Sompeng },
{ 3020, PT_SC, ucp_Sora_Sompeng },
{ 3032, PT_SC, ucp_Soyombo },
{ 3037, PT_SC, ucp_Soyombo },
{ 3045, PT_BOOL, ucp_White_Space },
{ 3051, PT_BOOL, ucp_Sentence_Terminal },
{ 3057, PT_SC, ucp_Sundanese },
{ 3062, PT_SC, ucp_Sundanese },
{ 3072, PT_SCX, ucp_Syloti_Nagri },
{ 3077, PT_SCX, ucp_Syloti_Nagri },
{ 3089, PT_SCX, ucp_Syriac },
{ 3094, PT_SCX, ucp_Syriac },
{ 3101, PT_SCX, ucp_Tagalog },
{ 3109, PT_SCX, ucp_Tagbanwa },
{ 3114, PT_SCX, ucp_Tagbanwa },
{ 3123, PT_SCX, ucp_Tai_Le },
{ 3129, PT_SC, ucp_Tai_Tham },
{ 3137, PT_SC, ucp_Tai_Viet },
{ 3145, PT_SCX, ucp_Takri },
{ 3150, PT_SCX, ucp_Takri },
{ 3156, PT_SCX, ucp_Tai_Le },
{ 3161, PT_SC, ucp_New_Tai_Lue },
{ 3166, PT_SCX, ucp_Tamil },
{ 3172, PT_SCX, ucp_Tamil },
{ 3177, PT_SC, ucp_Tangut },
{ 3182, PT_SC, ucp_Tangsa },
{ 3189, PT_SC, ucp_Tangut },
{ 3196, PT_SC, ucp_Tai_Viet },
{ 3201, PT_SCX, ucp_Telugu },
{ 3206, PT_SCX, ucp_Telugu },
{ 3213, PT_BOOL, ucp_Terminal_Punctuation },
{ 3218, PT_BOOL, ucp_Terminal_Punctuation },
{ 3238, PT_SC, ucp_Tifinagh },
{ 3243, PT_SCX, ucp_Tagalog },
{ 3248, PT_SCX, ucp_Thaana },
{ 3253, PT_SCX, ucp_Thaana },
{ 3260, PT_SC, ucp_Thai },
{ 3265, PT_SC, ucp_Tibetan },
{ 3273, PT_SC, ucp_Tibetan },
{ 3278, PT_SC, ucp_Tifinagh },
{ 3287, PT_SCX, ucp_Tirhuta },
{ 3292, PT_SCX, ucp_Tirhuta },
{ 3300, PT_SC, ucp_Tangsa },
{ 3305, PT_SC, ucp_Toto },
{ 3310, PT_SC, ucp_Ugaritic },
{ 3315, PT_SC, ucp_Ugaritic },
{ 3324, PT_BOOL, ucp_Unified_Ideograph },
{ 3330, PT_BOOL, ucp_Unified_Ideograph },
{ 3347, PT_SC, ucp_Unknown },
{ 3355, PT_BOOL, ucp_Uppercase },
{ 3361, PT_BOOL, ucp_Uppercase },
{ 3371, PT_SC, ucp_Vai },
{ 3375, PT_SC, ucp_Vai },
{ 3380, PT_BOOL, ucp_Variation_Selector },
{ 3398, PT_SC, ucp_Vithkuqi },
{ 3403, PT_SC, ucp_Vithkuqi },
{ 3412, PT_BOOL, ucp_Variation_Selector },
{ 3415, PT_SC, ucp_Wancho },
{ 3422, PT_SC, ucp_Warang_Citi },
{ 3427, PT_SC, ucp_Warang_Citi },
{ 3438, PT_SC, ucp_Wancho },
{ 3443, PT_BOOL, ucp_White_Space },
{ 3454, PT_BOOL, ucp_White_Space },
{ 3461, PT_ALNUM, 0 },
{ 3465, PT_BOOL, ucp_XID_Continue },
{ 3470, PT_BOOL, ucp_XID_Continue },
{ 3482, PT_BOOL, ucp_XID_Start },
{ 3487, PT_BOOL, ucp_XID_Start },
{ 3496, PT_SC, ucp_Old_Persian },
{ 3501, PT_PXSPACE, 0 },
{ 3505, PT_SPACE, 0 },
{ 3509, PT_SC, ucp_Cuneiform },
{ 3514, PT_UCNC, 0 },
{ 3518, PT_WORD, 0 },
{ 3522, PT_SCX, ucp_Yezidi },
{ 3527, PT_SCX, ucp_Yezidi },
{ 3534, PT_SCX, ucp_Yi },
{ 3537, PT_SCX, ucp_Yi },
{ 3542, PT_GC, ucp_Z },
{ 3544, PT_SC, ucp_Zanabazar_Square },
{ 3560, PT_SC, ucp_Zanabazar_Square },
{ 3565, PT_SC, ucp_Inherited },
{ 3570, PT_PC, ucp_Zl },
{ 3573, PT_PC, ucp_Zp },
{ 3576, PT_PC, ucp_Zs },
{ 3579, PT_SC, ucp_Common },
{ 3584, PT_SC, ucp_Unknown }
};
const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);

View File

@ -171,7 +171,7 @@ for (p = string; length > 0; p++)
if (((d = *(++p)) & 0xc0) != 0x80)
{
*erroroffset = (int)(p - string) - 1;
*erroroffset = (PCRE2_SIZE)(p - string) - 1;
return PCRE2_ERROR_UTF8_ERR6;
}
@ -186,7 +186,7 @@ for (p = string; length > 0; p++)
case 1: if ((c & 0x3e) == 0)
{
*erroroffset = (int)(p - string) - 1;
*erroroffset = (PCRE2_SIZE)(p - string) - 1;
return PCRE2_ERROR_UTF8_ERR15;
}
break;
@ -198,17 +198,17 @@ for (p = string; length > 0; p++)
case 2:
if ((*(++p) & 0xc0) != 0x80) /* Third byte */
{
*erroroffset = (int)(p - string) - 2;
*erroroffset = (PCRE2_SIZE)(p - string) - 2;
return PCRE2_ERROR_UTF8_ERR7;
}
if (c == 0xe0 && (d & 0x20) == 0)
{
*erroroffset = (int)(p - string) - 2;
*erroroffset = (PCRE2_SIZE)(p - string) - 2;
return PCRE2_ERROR_UTF8_ERR16;
}
if (c == 0xed && d >= 0xa0)
{
*erroroffset = (int)(p - string) - 2;
*erroroffset = (PCRE2_SIZE)(p - string) - 2;
return PCRE2_ERROR_UTF8_ERR14;
}
break;
@ -220,22 +220,22 @@ for (p = string; length > 0; p++)
case 3:
if ((*(++p) & 0xc0) != 0x80) /* Third byte */
{
*erroroffset = (int)(p - string) - 2;
*erroroffset = (PCRE2_SIZE)(p - string) - 2;
return PCRE2_ERROR_UTF8_ERR7;
}
if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
{
*erroroffset = (int)(p - string) - 3;
*erroroffset = (PCRE2_SIZE)(p - string) - 3;
return PCRE2_ERROR_UTF8_ERR8;
}
if (c == 0xf0 && (d & 0x30) == 0)
{
*erroroffset = (int)(p - string) - 3;
*erroroffset = (PCRE2_SIZE)(p - string) - 3;
return PCRE2_ERROR_UTF8_ERR17;
}
if (c > 0xf4 || (c == 0xf4 && d > 0x8f))
{
*erroroffset = (int)(p - string) - 3;
*erroroffset = (PCRE2_SIZE)(p - string) - 3;
return PCRE2_ERROR_UTF8_ERR13;
}
break;
@ -251,22 +251,22 @@ for (p = string; length > 0; p++)
case 4:
if ((*(++p) & 0xc0) != 0x80) /* Third byte */
{
*erroroffset = (int)(p - string) - 2;
*erroroffset = (PCRE2_SIZE)(p - string) - 2;
return PCRE2_ERROR_UTF8_ERR7;
}
if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
{
*erroroffset = (int)(p - string) - 3;
*erroroffset = (PCRE2_SIZE)(p - string) - 3;
return PCRE2_ERROR_UTF8_ERR8;
}
if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
{
*erroroffset = (int)(p - string) - 4;
*erroroffset = (PCRE2_SIZE)(p - string) - 4;
return PCRE2_ERROR_UTF8_ERR9;
}
if (c == 0xf8 && (d & 0x38) == 0)
{
*erroroffset = (int)(p - string) - 4;
*erroroffset = (PCRE2_SIZE)(p - string) - 4;
return PCRE2_ERROR_UTF8_ERR18;
}
break;
@ -277,27 +277,27 @@ for (p = string; length > 0; p++)
case 5:
if ((*(++p) & 0xc0) != 0x80) /* Third byte */
{
*erroroffset = (int)(p - string) - 2;
*erroroffset = (PCRE2_SIZE)(p - string) - 2;
return PCRE2_ERROR_UTF8_ERR7;
}
if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */
{
*erroroffset = (int)(p - string) - 3;
*erroroffset = (PCRE2_SIZE)(p - string) - 3;
return PCRE2_ERROR_UTF8_ERR8;
}
if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */
{
*erroroffset = (int)(p - string) - 4;
*erroroffset = (PCRE2_SIZE)(p - string) - 4;
return PCRE2_ERROR_UTF8_ERR9;
}
if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */
{
*erroroffset = (int)(p - string) - 5;
*erroroffset = (PCRE2_SIZE)(p - string) - 5;
return PCRE2_ERROR_UTF8_ERR10;
}
if (c == 0xfc && (d & 0x3c) == 0)
{
*erroroffset = (int)(p - string) - 5;
*erroroffset = (PCRE2_SIZE)(p - string) - 5;
return PCRE2_ERROR_UTF8_ERR19;
}
break;
@ -309,7 +309,7 @@ for (p = string; length > 0; p++)
if (ab > 3)
{
*erroroffset = (int)(p - string) - ab;
*erroroffset = (PCRE2_SIZE)(p - string) - ab;
return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12;
}
}
@ -340,21 +340,21 @@ for (p = string; length > 0; p++)
/* High surrogate. Must be a followed by a low surrogate. */
if (length == 0)
{
*erroroffset = p - string;
*erroroffset = (PCRE2_SIZE)(p - string);
return PCRE2_ERROR_UTF16_ERR1;
}
p++;
length--;
if ((*p & 0xfc00) != 0xdc00)
{
*erroroffset = p - string - 1;
*erroroffset = (PCRE2_SIZE)(p - string) - 1;
return PCRE2_ERROR_UTF16_ERR2;
}
}
else
{
/* Isolated low surrogate. Always an error. */
*erroroffset = p - string;
*erroroffset = (PCRE2_SIZE)(p - string);
return PCRE2_ERROR_UTF16_ERR3;
}
}
@ -379,14 +379,14 @@ for (p = string; length > 0; length--, p++)
/* Normal UTF-32 code point. Neither high nor low surrogate. */
if (c > 0x10ffffu)
{
*erroroffset = p - string;
*erroroffset = (PCRE2_SIZE)(p - string);
return PCRE2_ERROR_UTF32_ERR2;
}
}
else
{
/* A surrogate */
*erroroffset = p - string;
*erroroffset = (PCRE2_SIZE)(p - string);
return PCRE2_ERROR_UTF32_ERR1;
}
}

View File

@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2016-2022 University of Cambridge
New API code Copyright (c) 2016-2023 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@ -133,6 +133,7 @@ while ((t = *data++) != XCL_END)
#ifdef SUPPORT_UNICODE
else /* XCL_PROP & XCL_NOTPROP */
{
int chartype;
const ucd_record *prop = GET_UCD(c);
BOOL isprop = t == XCL_PROP;
BOOL ok;
@ -144,8 +145,9 @@ while ((t = *data++) != XCL_END)
break;
case PT_LAMP:
if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
prop->chartype == ucp_Lt) == isprop) return !negated;
chartype = prop->chartype;
if ((chartype == ucp_Lu || chartype == ucp_Ll ||
chartype == ucp_Lt) == isprop) return !negated;
break;
case PT_GC:
@ -168,8 +170,9 @@ while ((t = *data++) != XCL_END)
break;
case PT_ALNUM:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop)
chartype = prop->chartype;
if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N) == isprop)
return !negated;
break;
@ -194,9 +197,10 @@ while ((t = *data++) != XCL_END)
break;
case PT_WORD:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
== isprop)
chartype = prop->chartype;
if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
PRIV(ucp_gentype)[chartype] == ucp_N ||
chartype == ucp_Mn || chartype == ucp_Pc) == isprop)
return !negated;
break;
@ -238,9 +242,10 @@ while ((t = *data++) != XCL_END)
*/
case PT_PXGRAPH:
if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z &&
(PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
(prop->chartype == ucp_Cf &&
chartype = prop->chartype;
if ((PRIV(ucp_gentype)[chartype] != ucp_Z &&
(PRIV(ucp_gentype)[chartype] != ucp_C ||
(chartype == ucp_Cf &&
c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))
)) == isprop)
return !negated;
@ -250,10 +255,11 @@ while ((t = *data++) != XCL_END)
not Zl and not Zp, and U+180E. */
case PT_PXPRINT:
if ((prop->chartype != ucp_Zl &&
prop->chartype != ucp_Zp &&
(PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
(prop->chartype == ucp_Cf &&
chartype = prop->chartype;
if ((chartype != ucp_Zl &&
chartype != ucp_Zp &&
(PRIV(ucp_gentype)[chartype] != ucp_C ||
(chartype == ucp_Cf &&
c != 0x061c && (c < 0x2066 || c > 0x2069))
)) == isprop)
return !negated;
@ -264,8 +270,21 @@ while ((t = *data++) != XCL_END)
compatibility (these are $+<=>^`|~). */
case PT_PXPUNCT:
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||
(c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
chartype = prop->chartype;
if ((PRIV(ucp_gentype)[chartype] == ucp_P ||
(c < 128 && PRIV(ucp_gentype)[chartype] == ucp_S)) == isprop)
return !negated;
break;
/* Perl has two sets of hex digits */
case PT_PXXDIGIT:
if (((c >= CHAR_0 && c <= CHAR_9) ||
(c >= CHAR_A && c <= CHAR_F) ||
(c >= CHAR_a && c <= CHAR_f) ||
(c >= 0xff10 && c <= 0xff19) || /* Fullwidth digits */
(c >= 0xff21 && c <= 0xff26) || /* Fullwidth letters */
(c >= 0xff41 && c <= 0xff46)) == isprop)
return !negated;
break;

View File

@ -0,0 +1,133 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/mman.h>
/*
On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
version where it's OK to have more than one JIT block or where MAP_JIT is
required.
On non-macOS systems, returns MAP_JIT if it is defined.
*/
#include <TargetConditionals.h>
#if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (TARGET_OS_MAC && !TARGET_OS_IPHONE)
#if defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86
#include <sys/utsname.h>
#include <stdlib.h>
#define SLJIT_MAP_JIT (get_map_jit_flag())
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
static SLJIT_INLINE int get_map_jit_flag(void)
{
size_t page_size;
void *ptr;
struct utsname name;
static int map_jit_flag = -1;
if (map_jit_flag < 0) {
map_jit_flag = 0;
uname(&name);
/* Kernel version for 10.14.0 (Mojave) or later */
if (atoi(name.release) >= 18) {
page_size = get_page_alignment() + 1;
/* Only use MAP_JIT if a hardened runtime is used */
ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr != MAP_FAILED)
munmap(ptr, page_size);
else
map_jit_flag = MAP_JIT;
}
}
return map_jit_flag;
}
#elif defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM
#include <AvailabilityMacros.h>
#include <pthread.h>
#define SLJIT_MAP_JIT (MAP_JIT)
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
apple_update_wx_flags(enable_exec)
static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)
{
#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000
if (__builtin_available(macos 11, *))
#endif /* BigSur */
pthread_jit_write_protect_np(enable_exec);
}
#elif defined(SLJIT_CONFIG_PPC) && SLJIT_CONFIG_PPC
#define SLJIT_MAP_JIT (0)
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
#else
#error "Unsupported architecture"
#endif /* SLJIT_CONFIG */
#else /* !TARGET_OS_OSX */
#ifdef MAP_JIT
#define SLJIT_MAP_JIT (MAP_JIT)
#else
#define SLJIT_MAP_JIT (0)
#endif
#endif /* TARGET_OS_OSX */
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{
void *retval;
int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
int flags = MAP_PRIVATE;
int fd = -1;
flags |= MAP_ANON | SLJIT_MAP_JIT;
retval = mmap(NULL, size, prot, flags, fd, 0);
if (retval == MAP_FAILED)
return NULL;
SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0);
return retval;
}
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
munmap(chunk, size);
}
#include "sljitExecAllocatorCore.c"

View File

@ -0,0 +1,330 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
This file contains a simple executable memory allocator
It is assumed, that executable code blocks are usually medium (or sometimes
large) memory blocks, and the allocator is not too frequently called (less
optimized than other allocators). Thus, using it as a generic allocator is
not suggested.
How does it work:
Memory is allocated in continuous memory areas called chunks by alloc_chunk()
Chunk format:
[ block ][ block ] ... [ block ][ block terminator ]
All blocks and the block terminator is started with block_header. The block
header contains the size of the previous and the next block. These sizes
can also contain special values.
Block size:
0 - The block is a free_block, with a different size member.
1 - The block is a block terminator.
n - The block is used at the moment, and the value contains its size.
Previous block size:
0 - This is the first block of the memory chunk.
n - The size of the previous block.
Using these size values we can go forward or backward on the block chain.
The unused blocks are stored in a chain list pointed by free_blocks. This
list is useful if we need to find a suitable memory area when the allocator
is called.
When a block is freed, the new free block is connected to its adjacent free
blocks if possible.
[ free block ][ used block ][ free block ]
and "used block" is freed, the three blocks are connected together:
[ one big free block ]
*/
/* Expected functions:
alloc_chunk / free_chunk :
* allocate executable system memory chunks
* the size is always divisible by CHUNK_SIZE
SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
* provided as part of sljitUtils
* only the allocator requires this lock, sljit is fully thread safe
as it only uses local variables
Supported defines:
SLJIT_HAS_CHUNK_HEADER - (optional) sljit_chunk_header is defined
SLJIT_HAS_EXECUTABLE_OFFSET - (optional) has executable offset data
SLJIT_UPDATE_WX_FLAGS - (optional) update WX flags
*/
#ifdef SLJIT_HAS_CHUNK_HEADER
#define CHUNK_HEADER_SIZE (sizeof(struct sljit_chunk_header))
#else /* !SLJIT_HAS_CHUNK_HEADER */
#define CHUNK_HEADER_SIZE 0
#endif /* SLJIT_HAS_CHUNK_HEADER */
#ifndef SLJIT_UPDATE_WX_FLAGS
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
#endif /* SLJIT_UPDATE_WX_FLAGS */
#ifndef CHUNK_SIZE
/* 64 KByte if not specified. */
#define CHUNK_SIZE (sljit_uw)0x10000
#endif /* CHUNK_SIZE */
struct block_header {
sljit_uw size;
sljit_uw prev_size;
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
sljit_sw executable_offset;
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
};
struct free_block {
struct block_header header;
struct free_block *next;
struct free_block *prev;
sljit_uw size;
};
#define AS_BLOCK_HEADER(base, offset) \
((struct block_header*)(((sljit_u8*)base) + offset))
#define AS_FREE_BLOCK(base, offset) \
((struct free_block*)(((sljit_u8*)base) + offset))
#define MEM_START(base) ((void*)((base) + 1))
#define CHUNK_MASK (~(CHUNK_SIZE - 1))
#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7)
#define CHUNK_EXTRA_SIZE (sizeof(struct block_header) + CHUNK_HEADER_SIZE)
static struct free_block* free_blocks;
static sljit_uw allocated_size;
static sljit_uw total_size;
static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
{
free_block->header.size = 0;
free_block->size = size;
free_block->next = free_blocks;
free_block->prev = NULL;
if (free_blocks)
free_blocks->prev = free_block;
free_blocks = free_block;
}
static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
{
if (free_block->next)
free_block->next->prev = free_block->prev;
if (free_block->prev)
free_block->prev->next = free_block->next;
else {
SLJIT_ASSERT(free_blocks == free_block);
free_blocks = free_block->next;
}
}
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
{
struct block_header *header;
struct block_header *next_header;
struct free_block *free_block;
sljit_uw chunk_size;
#ifdef SLJIT_HAS_CHUNK_HEADER
struct sljit_chunk_header *chunk_header;
#else /* !SLJIT_HAS_CHUNK_HEADER */
void *chunk_header;
#endif /* SLJIT_HAS_CHUNK_HEADER */
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
sljit_sw executable_offset;
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
if (size < (64 - sizeof(struct block_header)))
size = (64 - sizeof(struct block_header));
size = ALIGN_SIZE(size);
SLJIT_ALLOCATOR_LOCK();
free_block = free_blocks;
while (free_block) {
if (free_block->size >= size) {
chunk_size = free_block->size;
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
if (chunk_size > size + 64) {
/* We just cut a block from the end of the free block. */
chunk_size -= size;
free_block->size = chunk_size;
header = AS_BLOCK_HEADER(free_block, chunk_size);
header->prev_size = chunk_size;
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
header->executable_offset = free_block->header.executable_offset;
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
AS_BLOCK_HEADER(header, size)->prev_size = size;
}
else {
sljit_remove_free_block(free_block);
header = (struct block_header*)free_block;
size = chunk_size;
}
allocated_size += size;
header->size = size;
SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
free_block = free_block->next;
}
chunk_size = (size + CHUNK_EXTRA_SIZE + CHUNK_SIZE - 1) & CHUNK_MASK;
chunk_header = alloc_chunk(chunk_size);
if (!chunk_header) {
SLJIT_ALLOCATOR_UNLOCK();
return NULL;
}
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
executable_offset = (sljit_sw)((sljit_u8*)chunk_header->executable - (sljit_u8*)chunk_header);
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
chunk_size -= CHUNK_EXTRA_SIZE;
total_size += chunk_size;
header = (struct block_header*)(((sljit_u8*)chunk_header) + CHUNK_HEADER_SIZE);
header->prev_size = 0;
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
header->executable_offset = executable_offset;
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
if (chunk_size > size + 64) {
/* Cut the allocated space into a free and a used block. */
allocated_size += size;
header->size = size;
chunk_size -= size;
free_block = AS_FREE_BLOCK(header, size);
free_block->header.prev_size = size;
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
free_block->header.executable_offset = executable_offset;
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
sljit_insert_free_block(free_block, chunk_size);
next_header = AS_BLOCK_HEADER(free_block, chunk_size);
}
else {
/* All space belongs to this allocation. */
allocated_size += chunk_size;
header->size = chunk_size;
next_header = AS_BLOCK_HEADER(header, chunk_size);
}
SLJIT_ALLOCATOR_UNLOCK();
next_header->size = 1;
next_header->prev_size = chunk_size;
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
next_header->executable_offset = executable_offset;
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
return MEM_START(header);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
{
struct block_header *header;
struct free_block* free_block;
SLJIT_ALLOCATOR_LOCK();
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
header = AS_BLOCK_HEADER(header, -header->executable_offset);
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
allocated_size -= header->size;
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
/* Connecting free blocks together if possible. */
/* If header->prev_size == 0, free_block will equal to header.
In this case, free_block->header.size will be > 0. */
free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size);
if (SLJIT_UNLIKELY(!free_block->header.size)) {
free_block->size += header->size;
header = AS_BLOCK_HEADER(free_block, free_block->size);
header->prev_size = free_block->size;
}
else {
free_block = (struct free_block*)header;
sljit_insert_free_block(free_block, header->size);
}
header = AS_BLOCK_HEADER(free_block, free_block->size);
if (SLJIT_UNLIKELY(!header->size)) {
free_block->size += ((struct free_block*)header)->size;
sljit_remove_free_block((struct free_block*)header);
header = AS_BLOCK_HEADER(free_block, free_block->size);
header->prev_size = free_block->size;
}
/* The whole chunk is free. */
if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
/* If this block is freed, we still have (allocated_size / 2) free space. */
if (total_size - free_block->size > (allocated_size * 3 / 2)) {
total_size -= free_block->size;
sljit_remove_free_block(free_block);
free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE);
}
}
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
SLJIT_ALLOCATOR_UNLOCK();
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
{
struct free_block* free_block;
struct free_block* next_free_block;
SLJIT_ALLOCATOR_LOCK();
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
free_block = free_blocks;
while (free_block) {
next_free_block = free_block->next;
if (!free_block->header.prev_size &&
AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
total_size -= free_block->size;
sljit_remove_free_block(free_block);
free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE);
}
free_block = next_free_block;
}
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
SLJIT_ALLOCATOR_UNLOCK();
}
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr)
{
return ((struct block_header *)(ptr))[-1].executable_offset;
}
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */

View File

@ -0,0 +1,89 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/mman.h>
#include <sys/procctl.h>
#ifdef PROC_WXMAP_CTL
static SLJIT_INLINE int sljit_is_wx_block(void)
{
static int wx_block = -1;
if (wx_block < 0) {
int sljit_wx_enable = PROC_WX_MAPPINGS_PERMIT;
wx_block = !!procctl(P_PID, 0, PROC_WXMAP_CTL, &sljit_wx_enable);
}
return wx_block;
}
#define SLJIT_IS_WX_BLOCK sljit_is_wx_block()
#else /* !PROC_WXMAP_CTL */
#define SLJIT_IS_WX_BLOCK (1)
#endif /* PROC_WXMAP_CTL */
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{
void *retval;
int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
int flags = MAP_PRIVATE;
int fd = -1;
#ifdef PROT_MAX
prot |= PROT_MAX(prot);
#endif
#ifdef MAP_ANON
flags |= MAP_ANON;
#else /* !MAP_ANON */
if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))
return NULL;
fd = dev_zero;
#endif /* MAP_ANON */
retry:
retval = mmap(NULL, size, prot, flags, fd, 0);
if (retval == MAP_FAILED) {
if (!SLJIT_IS_WX_BLOCK)
goto retry;
return NULL;
}
/* HardenedBSD's mmap lies, so check permissions again. */
if (mprotect(retval, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) {
munmap(retval, size);
return NULL;
}
return retval;
}
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
munmap(chunk, size);
}
#include "sljitExecAllocatorCore.c"

View File

@ -0,0 +1,62 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/mman.h>
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{
void *retval;
int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
int flags = MAP_PRIVATE;
int fd = -1;
#ifdef PROT_MAX
prot |= PROT_MAX(prot);
#endif
#ifdef MAP_ANON
flags |= MAP_ANON;
#else /* !MAP_ANON */
if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))
return NULL;
fd = dev_zero;
#endif /* MAP_ANON */
retval = mmap(NULL, size, prot, flags, fd, 0);
if (retval == MAP_FAILED)
return NULL;
return retval;
}
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
munmap(chunk, size);
}
#include "sljitExecAllocatorCore.c"

View File

@ -0,0 +1,40 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{
return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
SLJIT_UNUSED_ARG(size);
VirtualFree(chunk, 0, MEM_RELEASE);
}
#include "sljitExecAllocatorCore.c"

View File

@ -0,0 +1,72 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define SLJIT_HAS_CHUNK_HEADER
#define SLJIT_HAS_EXECUTABLE_OFFSET
struct sljit_chunk_header {
void *executable;
};
/*
* MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to
* adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed
*/
static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size)
{
struct sljit_chunk_header *retval;
retval = (struct sljit_chunk_header *)mmap(NULL, size,
PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC),
MAP_ANON | MAP_SHARED, -1, 0);
if (retval == MAP_FAILED)
return NULL;
retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP);
if (retval->executable == MAP_FAILED) {
munmap((void *)retval, size);
return NULL;
}
if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) {
munmap(retval->executable, size);
munmap((void *)retval, size);
return NULL;
}
return retval;
}
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1;
munmap(header->executable, size);
munmap((void *)header, size);
}
#include "sljitExecAllocatorCore.c"

View File

@ -0,0 +1,172 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define SLJIT_HAS_CHUNK_HEADER
#define SLJIT_HAS_EXECUTABLE_OFFSET
struct sljit_chunk_header {
void *executable;
};
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#ifndef O_NOATIME
#define O_NOATIME 0
#endif
/* this is a linux extension available since kernel 3.11 */
#ifndef O_TMPFILE
#define O_TMPFILE 0x404000
#endif
#ifndef _GNU_SOURCE
char *secure_getenv(const char *name);
int mkostemp(char *template, int flags);
#endif
static SLJIT_INLINE int create_tempfile(void)
{
int fd;
char tmp_name[256];
size_t tmp_name_len = 0;
char *dir;
struct stat st;
#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
mode_t mode;
#endif
#ifdef HAVE_MEMFD_CREATE
/* this is a GNU extension, make sure to use -D_GNU_SOURCE */
fd = memfd_create("sljit", MFD_CLOEXEC);
if (fd != -1) {
fchmod(fd, 0);
return fd;
}
#endif
dir = secure_getenv("TMPDIR");
if (dir) {
size_t len = strlen(dir);
if (len > 0 && len < sizeof(tmp_name)) {
if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) {
memcpy(tmp_name, dir, len + 1);
tmp_name_len = len;
}
}
}
#ifdef P_tmpdir
if (!tmp_name_len) {
tmp_name_len = strlen(P_tmpdir);
if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))
strcpy(tmp_name, P_tmpdir);
}
#endif
if (!tmp_name_len) {
strcpy(tmp_name, "/tmp");
tmp_name_len = 4;
}
SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));
if (tmp_name_len > 1 && tmp_name[tmp_name_len - 1] == '/')
tmp_name[--tmp_name_len] = '\0';
fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);
if (fd != -1)
return fd;
if (tmp_name_len >= sizeof(tmp_name) - 7)
return -1;
strcpy(tmp_name + tmp_name_len, "/XXXXXX");
#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
mode = umask(0777);
#endif
fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);
#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
umask(mode);
#else
fchmod(fd, 0);
#endif
if (fd == -1)
return -1;
if (unlink(tmp_name)) {
close(fd);
return -1;
}
return fd;
}
static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size)
{
struct sljit_chunk_header *retval;
int fd;
fd = create_tempfile();
if (fd == -1)
return NULL;
if (ftruncate(fd, (off_t)size)) {
close(fd);
return NULL;
}
retval = (struct sljit_chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (retval == MAP_FAILED) {
close(fd);
return NULL;
}
retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
if (retval->executable == MAP_FAILED) {
munmap((void *)retval, size);
close(fd);
return NULL;
}
close(fd);
return retval;
}
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1;
munmap(header->executable, size);
munmap((void *)header, size);
}
#include "sljitExecAllocatorCore.c"

View File

@ -0,0 +1,141 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
This file contains a simple W^X executable memory allocator
In *NIX, MAP_ANON is required (that is considered a feature) so make
sure to set the right availability macros for your system or the code
will fail to build.
If your system doesn't support mapping of anonymous pages (ex: IRIX) it
is also likely that it doesn't need this allocator and should be using
the standard one instead.
It allocates a separate map for each code block and may waste a lot of
memory, because whatever was requested, will be rounded up to the page
size (minimum 4KB, but could be even bigger).
It changes the page permissions (RW <-> RX) as needed and therefore, if you
will be updating the code after it has been generated, need to make sure to
block any concurrent execution, or could result in a SIGBUS, that could
even manifest itself at a different address than the one that was being
modified.
Only use if you are unable to use the regular allocator because of security
restrictions and adding exceptions to your application or the system are
not possible.
*/
#include <sys/types.h>
#include <sys/mman.h>
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
sljit_update_wx_flags((from), (to), (enable_exec))
#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
#include <pthread.h>
#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock)
#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock)
#else
#define SLJIT_SE_LOCK()
#define SLJIT_SE_UNLOCK()
#endif /* !SLJIT_SINGLE_THREADED */
#define SLJIT_WX_IS_BLOCK(ptr, size) generic_check_is_wx_block(ptr, size)
static SLJIT_INLINE int generic_check_is_wx_block(void *ptr, sljit_uw size)
{
if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC)))
return !!mprotect(ptr, size, PROT_READ | PROT_WRITE);
return 1;
}
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
{
#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
static int wx_block = -1;
int prot = PROT_READ | PROT_WRITE;
sljit_uw* ptr;
if (SLJIT_UNLIKELY(wx_block > 0))
return NULL;
#ifdef PROT_MAX
prot |= PROT_MAX(PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
size += sizeof(sljit_uw);
ptr = (sljit_uw*)mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr == MAP_FAILED)
return NULL;
if (SLJIT_UNLIKELY(wx_block < 0)) {
SLJIT_SE_LOCK();
wx_block = SLJIT_WX_IS_BLOCK(ptr, size);
SLJIT_SE_UNLOCK();
if (SLJIT_UNLIKELY(wx_block)) {
munmap((void *)ptr, size);
return NULL;
}
}
*ptr++ = size;
return ptr;
}
#undef SLJIT_SE_UNLOCK
#undef SLJIT_SE_LOCK
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
{
sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1;
munmap((void*)start_ptr, *start_ptr);
}
static void sljit_update_wx_flags(void *from, void *to, int enable_exec)
{
sljit_uw page_mask = (sljit_uw)get_page_alignment();
sljit_uw start = (sljit_uw)from;
sljit_uw end = (sljit_uw)to;
int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);
SLJIT_ASSERT(start < end);
start &= ~page_mask;
end = (end + page_mask) & ~page_mask;
mprotect((void*)start, end - start, prot);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
{
/* This allocator does not keep unused memory for future allocations. */
}

View File

@ -0,0 +1,102 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
This file contains a simple W^X executable memory allocator
In *NIX, MAP_ANON is required (that is considered a feature) so make
sure to set the right availability macros for your system or the code
will fail to build.
If your system doesn't support mapping of anonymous pages (ex: IRIX) it
is also likely that it doesn't need this allocator and should be using
the standard one instead.
It allocates a separate map for each code block and may waste a lot of
memory, because whatever was requested, will be rounded up to the page
size (minimum 4KB, but could be even bigger).
It changes the page permissions (RW <-> RX) as needed and therefore, if you
will be updating the code after it has been generated, need to make sure to
block any concurrent execution, or could result in a SIGBUS, that could
even manifest itself at a different address than the one that was being
modified.
Only use if you are unable to use the regular allocator because of security
restrictions and adding exceptions to your application or the system are
not possible.
*/
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
sljit_update_wx_flags((from), (to), (enable_exec))
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
{
sljit_uw *ptr;
size += sizeof(sljit_uw);
ptr = (sljit_uw*)VirtualAlloc(NULL, size,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!ptr)
return NULL;
*ptr++ = size;
return ptr;
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
{
sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw);
#if defined(SLJIT_DEBUG) && SLJIT_DEBUG
sljit_uw page_mask = (sljit_uw)get_page_alignment();
SLJIT_ASSERT(!(start & page_mask));
#endif
VirtualFree((void*)start, 0, MEM_RELEASE);
}
static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
{
DWORD oldprot;
sljit_uw page_mask = (sljit_uw)get_page_alignment();
sljit_uw start = (sljit_uw)from;
sljit_uw end = (sljit_uw)to;
DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE;
SLJIT_ASSERT(start < end);
start &= ~page_mask;
end = (end + page_mask) & ~page_mask;
VirtualProtect((void*)start, end - start, prot, &oldprot);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
{
/* This allocator does not keep unused memory for future allocations. */
}

View File

@ -38,28 +38,6 @@ extern "C" {
non-zero value.
*/
/* --------------------------------------------------------------------- */
/* Architecture */
/* --------------------------------------------------------------------- */
/* Architecture selection. */
/* #define SLJIT_CONFIG_X86_32 1 */
/* #define SLJIT_CONFIG_X86_64 1 */
/* #define SLJIT_CONFIG_ARM_V5 1 */
/* #define SLJIT_CONFIG_ARM_V7 1 */
/* #define SLJIT_CONFIG_ARM_THUMB2 1 */
/* #define SLJIT_CONFIG_ARM_64 1 */
/* #define SLJIT_CONFIG_PPC_32 1 */
/* #define SLJIT_CONFIG_PPC_64 1 */
/* #define SLJIT_CONFIG_MIPS_32 1 */
/* #define SLJIT_CONFIG_MIPS_64 1 */
/* #define SLJIT_CONFIG_RISCV_32 1 */
/* #define SLJIT_CONFIG_RISCV_64 1 */
/* #define SLJIT_CONFIG_S390X 1 */
/* #define SLJIT_CONFIG_AUTO 1 */
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
/* --------------------------------------------------------------------- */
/* Utilities */
/* --------------------------------------------------------------------- */
@ -96,7 +74,9 @@ extern "C" {
/* Executable code allocation:
If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_EXEC_OFFSET. */
define SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC.
Optionally, depending on the implementation used for the allocator,
SLJIT_EXEC_OFFSET and SLJIT_UPDATE_WX_FLAGS might also be needed. */
#ifndef SLJIT_EXECUTABLE_ALLOCATOR
/* Enabled by default. */
#define SLJIT_EXECUTABLE_ALLOCATOR 1

View File

@ -0,0 +1,188 @@
/*
* Stack-less Just-In-Time compiler
*
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SLJIT_CONFIG_CPU_H_
#define SLJIT_CONFIG_CPU_H_
/* --------------------------------------------------------------------- */
/* Architecture */
/* --------------------------------------------------------------------- */
/* Architecture selection. */
/* #define SLJIT_CONFIG_X86_32 1 */
/* #define SLJIT_CONFIG_X86_64 1 */
/* #define SLJIT_CONFIG_ARM_V6 1 */
/* #define SLJIT_CONFIG_ARM_V7 1 */
/* #define SLJIT_CONFIG_ARM_THUMB2 1 */
/* #define SLJIT_CONFIG_ARM_64 1 */
/* #define SLJIT_CONFIG_PPC_32 1 */
/* #define SLJIT_CONFIG_PPC_64 1 */
/* #define SLJIT_CONFIG_MIPS_32 1 */
/* #define SLJIT_CONFIG_MIPS_64 1 */
/* #define SLJIT_CONFIG_RISCV_32 1 */
/* #define SLJIT_CONFIG_RISCV_64 1 */
/* #define SLJIT_CONFIG_S390X 1 */
/* #define SLJIT_CONFIG_LOONGARCH_64 */
/* #define SLJIT_CONFIG_AUTO 1 */
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
/*****************/
/* Sanity check. */
/*****************/
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \
+ (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
+ (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
+ (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
+ (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \
+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
#error "Multiple architectures are selected"
#endif
#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
&& !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
&& !(defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \
&& !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
&& !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
&& !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
&& !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
&& !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
&& !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
&& !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \
&& !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \
&& !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO
#error "An architecture must be selected"
#else /* SLJIT_CONFIG_AUTO */
#define SLJIT_CONFIG_AUTO 1
#endif /* !SLJIT_CONFIG_AUTO */
#endif /* !SLJIT_CONFIG */
/********************************************************/
/* Automatic CPU detection (requires compiler support). */
/********************************************************/
#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
#ifndef _WIN32
#if defined(__i386__) || defined(__i386)
#define SLJIT_CONFIG_X86_32 1
#elif defined(__x86_64__)
#define SLJIT_CONFIG_X86_64 1
#elif defined(__aarch64__)
#define SLJIT_CONFIG_ARM_64 1
#elif defined(__thumb2__)
#define SLJIT_CONFIG_ARM_THUMB2 1
#elif (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \
((defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__)) \
|| (defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8R__)) \
|| (defined(__ARM_ARCH_9A__)))
#define SLJIT_CONFIG_ARM_V7 1
#elif defined(__arm__) || defined (__ARM__)
#define SLJIT_CONFIG_ARM_V6 1
#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__))
#define SLJIT_CONFIG_PPC_64 1
#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
#define SLJIT_CONFIG_PPC_32 1
#elif defined(__mips__) && !defined(_LP64)
#define SLJIT_CONFIG_MIPS_32 1
#elif defined(__mips64)
#define SLJIT_CONFIG_MIPS_64 1
#elif defined (__riscv_xlen) && (__riscv_xlen == 32)
#define SLJIT_CONFIG_RISCV_32 1
#elif defined (__riscv_xlen) && (__riscv_xlen == 64)
#define SLJIT_CONFIG_RISCV_64 1
#elif defined (__loongarch_lp64)
#define SLJIT_CONFIG_LOONGARCH_64 1
#elif defined(__s390x__)
#define SLJIT_CONFIG_S390X 1
#else
/* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1
#endif
#else /* _WIN32 */
#if defined(_M_X64) || defined(__x86_64__)
#define SLJIT_CONFIG_X86_64 1
#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__)
#define SLJIT_CONFIG_ARM_THUMB2 1
#elif (defined(_M_ARM) && _M_ARM >= 7)
#define SLJIT_CONFIG_ARM_V7 1
#elif defined(_ARM_)
#define SLJIT_CONFIG_ARM_V6 1
#elif defined(_M_ARM64) || defined(__aarch64__)
#define SLJIT_CONFIG_ARM_64 1
#else
#define SLJIT_CONFIG_X86_32 1
#endif
#endif /* !_WIN32 */
#endif /* SLJIT_CONFIG_AUTO */
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
#undef SLJIT_EXECUTABLE_ALLOCATOR
#endif /* SLJIT_CONFIG_UNSUPPORTED */
/******************************/
/* CPU family type detection. */
/******************************/
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
#define SLJIT_CONFIG_ARM_32 1
#endif
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
#define SLJIT_CONFIG_X86 1
#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
#define SLJIT_CONFIG_ARM 1
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
#define SLJIT_CONFIG_PPC 1
#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
#define SLJIT_CONFIG_MIPS 1
#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
#define SLJIT_CONFIG_RISCV 1
#elif (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64)
#define SLJIT_CONFIG_LOONGARCH 1
#endif
#endif /* SLJIT_CONFIG_CPU_H_ */

View File

@ -61,6 +61,8 @@ extern "C" {
SLJIT_BIG_ENDIAN : big endian architecture
SLJIT_UNALIGNED : unaligned memory accesses for non-fpu operations are supported
SLJIT_FPU_UNALIGNED : unaligned memory accesses for fpu operations are supported
SLJIT_MASKED_SHIFT : all word shifts are always masked
SLJIT_MASKED_SHIFT32 : all 32 bit shifts are always masked
SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information
Constants:
@ -70,6 +72,8 @@ extern "C" {
SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers
SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers
SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers
SLJIT_NUMBER_OF_TEMPORARY_REGISTERS : number of available temporary registers
SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS : number of available temporary floating point registers
SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
SLJIT_F32_SHIFT : the shift required to apply when accessing
a single precision floating point array by index
@ -79,141 +83,27 @@ extern "C" {
the scratch register index of ecx is stored in this variable
SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
SLJIT_CONV_MAX_FLOAT : result when a floating point value is converted to integer
and the floating point value is higher than the maximum integer value
(possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT)
SLJIT_CONV_MIN_FLOAT : result when a floating point value is converted to integer
and the floating point value is lower than the minimum integer value
(possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT)
SLJIT_CONV_NAN_FLOAT : result when a NaN floating point value is converted to integer
(possible values: SLJIT_CONV_RESULT_MAX_INT, SLJIT_CONV_RESULT_MIN_INT,
or SLJIT_CONV_RESULT_ZERO)
Other macros:
SLJIT_TMP_R0 .. R9 : accessing temporary registers
SLJIT_TMP_R(i) : accessing temporary registers
SLJIT_TMP_FR0 .. FR9 : accessing temporary floating point registers
SLJIT_TMP_FR(i) : accessing temporary floating point registers
SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit
floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero
*/
/*****************/
/* Sanity check. */
/*****************/
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
+ (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
+ (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
#error "Multiple architectures are selected"
#endif
#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
&& !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
&& !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
&& !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
&& !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
&& !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
&& !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
&& !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \
&& !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
&& !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \
&& !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO
#error "An architecture must be selected"
#else /* SLJIT_CONFIG_AUTO */
#define SLJIT_CONFIG_AUTO 1
#endif /* !SLJIT_CONFIG_AUTO */
#endif /* !SLJIT_CONFIG */
/********************************************************/
/* Automatic CPU detection (requires compiler support). */
/********************************************************/
#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
#ifndef _WIN32
#if defined(__i386__) || defined(__i386)
#define SLJIT_CONFIG_X86_32 1
#elif defined(__x86_64__)
#define SLJIT_CONFIG_X86_64 1
#elif defined(__arm__) || defined(__ARM__)
#ifdef __thumb2__
#define SLJIT_CONFIG_ARM_THUMB2 1
#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__)
#define SLJIT_CONFIG_ARM_V7 1
#else
#define SLJIT_CONFIG_ARM_V5 1
#endif
#elif defined (__aarch64__)
#define SLJIT_CONFIG_ARM_64 1
#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__))
#define SLJIT_CONFIG_PPC_64 1
#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
#define SLJIT_CONFIG_PPC_32 1
#elif defined(__mips__) && !defined(_LP64)
#define SLJIT_CONFIG_MIPS_32 1
#elif defined(__mips64)
#define SLJIT_CONFIG_MIPS_64 1
#elif defined (__riscv_xlen) && (__riscv_xlen == 32)
#define SLJIT_CONFIG_RISCV_32 1
#elif defined (__riscv_xlen) && (__riscv_xlen == 64)
#define SLJIT_CONFIG_RISCV_64 1
#elif defined(__s390x__)
#define SLJIT_CONFIG_S390X 1
#else
/* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1
#endif
#else /* _WIN32 */
#if defined(_M_X64) || defined(__x86_64__)
#define SLJIT_CONFIG_X86_64 1
#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__)
#define SLJIT_CONFIG_ARM_THUMB2 1
#elif (defined(_M_ARM) && _M_ARM >= 7)
#define SLJIT_CONFIG_ARM_V7 1
#elif defined(_ARM_)
#define SLJIT_CONFIG_ARM_V5 1
#elif defined(_M_ARM64) || defined(__aarch64__)
#define SLJIT_CONFIG_ARM_64 1
#else
#define SLJIT_CONFIG_X86_32 1
#endif
#endif /* !_WIN32 */
#endif /* SLJIT_CONFIG_AUTO */
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
#undef SLJIT_EXECUTABLE_ALLOCATOR
#endif
/******************************/
/* CPU family type detection. */
/******************************/
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
#define SLJIT_CONFIG_ARM_32 1
#endif
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
#define SLJIT_CONFIG_X86 1
#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
#define SLJIT_CONFIG_ARM 1
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
#define SLJIT_CONFIG_PPC 1
#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
#define SLJIT_CONFIG_MIPS 1
#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
#define SLJIT_CONFIG_RISCV 1
#endif
/***********************************************************/
/* Intel Control-flow Enforcement Technology (CET) spport. */
/***********************************************************/
@ -328,6 +218,10 @@ extern "C" {
/* Instruction cache flush. */
/****************************/
#ifdef __APPLE__
#include <AvailabilityMacros.h>
#endif
/*
* TODO:
*
@ -368,7 +262,7 @@ extern "C" {
/* Not required to implement on archs with unified caches. */
#define SLJIT_CACHE_FLUSH(from, to)
#elif defined __APPLE__
#elif defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
/* Supported by all macs since Mac OS 10.5.
However, it does not work on non-jailbroken iOS devices,
@ -433,14 +327,15 @@ typedef signed int sljit_s32;
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
/* Just to have something. */
#define SLJIT_WORD_SHIFT 0
typedef unsigned long int sljit_uw;
typedef long int sljit_sw;
typedef unsigned int sljit_uw;
typedef int sljit_sw;
#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
&& !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
&& !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64)
#define SLJIT_32BIT_ARCHITECTURE 1
#define SLJIT_WORD_SHIFT 2
typedef unsigned int sljit_uw;
@ -476,12 +371,42 @@ typedef double sljit_f64;
#define SLJIT_F32_SHIFT 2
#define SLJIT_F64_SHIFT 3
#define SLJIT_CONV_RESULT_MAX_INT 0
#define SLJIT_CONV_RESULT_MIN_INT 1
#define SLJIT_CONV_RESULT_ZERO 2
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MIN_INT
#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#elif (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT
#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_ZERO
#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT
#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MAX_INT
#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT
#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT
#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT
#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT
#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT
#else
#error "Result for float to integer conversion is not defined"
#endif
#ifndef SLJIT_W
/* Defining long constants. */
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
#define SLJIT_W(w) (w##l)
#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
#ifdef _WIN64
#define SLJIT_W(w) (w##ll)
#else /* !windows */
@ -521,9 +446,10 @@ typedef double sljit_f64;
/* Auto detecting mips revision. */
#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
#define SLJIT_MIPS_REV 6
#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \
|| (defined __clang__ && defined _MIPS_ARCH_OCTEON) \
|| (defined __clang__ && defined _MIPS_ARCH_P5600)
#elif defined(__mips_isa_rev) && __mips_isa_rev >= 1
#define SLJIT_MIPS_REV __mips_isa_rev
#elif defined(__clang__) \
&& (defined(_MIPS_ARCH_OCTEON) || defined(_MIPS_ARCH_P5600))
/* clang either forgets to define (clang-7) __mips_isa_rev at all
* or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+)
* and -march=p5600 (MIPS32 R5).
@ -562,7 +488,8 @@ typedef double sljit_f64;
|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
|| (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|| (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
#define SLJIT_UNALIGNED 1
#endif
@ -574,7 +501,8 @@ typedef double sljit_f64;
|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
|| (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|| (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
#define SLJIT_FPU_UNALIGNED 1
#endif
@ -594,6 +522,19 @@ typedef double sljit_f64;
#define SLJIT_FUNC
#endif /* !SLJIT_FUNC */
/* Disable instrumentation for these functions as they may not be sound */
#ifndef SLJIT_FUNC_ATTRIBUTE
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#define SLJIT_FUNC_ATTRIBUTE __attribute__((no_sanitize("memory")))
#endif /* __has_feature(memory_sanitizer) */
#endif /* defined(__has_feature) */
#endif
#ifndef SLJIT_FUNC_ATTRIBUTE
#define SLJIT_FUNC_ATTRIBUTE
#endif
#ifndef SLJIT_INDIRECT_CALL
#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \
|| ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX)
@ -631,12 +572,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr)
#else
#define SLJIT_EXEC_OFFSET(ptr) 0
#endif
#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
#ifndef SLJIT_EXEC_OFFSET
#define SLJIT_EXEC_OFFSET(ptr) 0
#endif
/**********************************************/
/* Registers and locals offset determination. */
/**********************************************/
@ -645,15 +588,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_NUMBER_OF_REGISTERS 12
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 7
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 1
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 7
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1
#define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw))
#define SLJIT_PREF_SHIFT_REG SLJIT_R2
#define SLJIT_MASKED_SHIFT 1
#define SLJIT_MASKED_SHIFT32 1
#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
#define SLJIT_NUMBER_OF_REGISTERS 13
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1
#ifndef _WIN64
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
@ -664,37 +613,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw))
#endif /* !_WIN64 */
#define SLJIT_PREF_SHIFT_REG SLJIT_R3
#define SLJIT_MASKED_SHIFT 1
#define SLJIT_MASKED_SHIFT32 1
#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
#define SLJIT_NUMBER_OF_REGISTERS 12
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#define SLJIT_LOCALS_OFFSET_BASE 0
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32)
#define SLJIT_NUMBER_OF_REGISTERS 12
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_LOCALS_OFFSET_BASE 0
#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
#define SLJIT_NUMBER_OF_REGISTERS 26
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw))
#define SLJIT_MASKED_SHIFT 1
#define SLJIT_MASKED_SHIFT32 1
#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
#define SLJIT_NUMBER_OF_REGISTERS 23
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw))
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
@ -717,14 +668,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 29
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#endif
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 3
#define SLJIT_MASKED_SHIFT 1
#define SLJIT_MASKED_SHIFT32 1
#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
#define SLJIT_NUMBER_OF_REGISTERS 23
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 12
#define SLJIT_LOCALS_OFFSET_BASE 0
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_LOCALS_OFFSET_BASE 0
#define SLJIT_MASKED_SHIFT 1
#define SLJIT_MASKED_SHIFT32 1
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
@ -751,16 +710,34 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_NUMBER_OF_REGISTERS 12
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1
#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
#define SLJIT_MASKED_SHIFT 1
#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
#define SLJIT_NUMBER_OF_REGISTERS 23
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_LOCALS_OFFSET_BASE 0
#define SLJIT_MASKED_SHIFT 1
#define SLJIT_MASKED_SHIFT32 1
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
/* Just to have something. */
#define SLJIT_NUMBER_OF_REGISTERS 0
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 0
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 0
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 0
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 0
#define SLJIT_LOCALS_OFFSET_BASE 0
#endif
@ -773,6 +750,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \
(SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS)
/**********************************/
/* Temporary register management. */
/**********************************/
#define SLJIT_TMP_REGISTER_BASE (SLJIT_NUMBER_OF_REGISTERS + 2)
#define SLJIT_TMP_FREGISTER_BASE (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
/* WARNING: Accessing temporary registers is not recommended, because they
are also used by the JIT compiler for various computations. Using them
might have any side effects including incorrect operations and crashes,
so use them at your own risk. The machine registers themselves might have
limitations, e.g. the r0 register on s390x / ppc cannot be used as
base address for memory operations. */
/* Temporary registers */
#define SLJIT_TMP_R0 (SLJIT_TMP_REGISTER_BASE + 0)
#define SLJIT_TMP_R1 (SLJIT_TMP_REGISTER_BASE + 1)
#define SLJIT_TMP_R2 (SLJIT_TMP_REGISTER_BASE + 2)
#define SLJIT_TMP_R3 (SLJIT_TMP_REGISTER_BASE + 3)
#define SLJIT_TMP_R4 (SLJIT_TMP_REGISTER_BASE + 4)
#define SLJIT_TMP_R5 (SLJIT_TMP_REGISTER_BASE + 5)
#define SLJIT_TMP_R6 (SLJIT_TMP_REGISTER_BASE + 6)
#define SLJIT_TMP_R7 (SLJIT_TMP_REGISTER_BASE + 7)
#define SLJIT_TMP_R8 (SLJIT_TMP_REGISTER_BASE + 8)
#define SLJIT_TMP_R9 (SLJIT_TMP_REGISTER_BASE + 9)
#define SLJIT_TMP_R(i) (SLJIT_TMP_REGISTER_BASE + (i))
#define SLJIT_TMP_FR0 (SLJIT_TMP_FREGISTER_BASE + 0)
#define SLJIT_TMP_FR1 (SLJIT_TMP_FREGISTER_BASE + 1)
#define SLJIT_TMP_FR2 (SLJIT_TMP_FREGISTER_BASE + 2)
#define SLJIT_TMP_FR3 (SLJIT_TMP_FREGISTER_BASE + 3)
#define SLJIT_TMP_FR4 (SLJIT_TMP_FREGISTER_BASE + 4)
#define SLJIT_TMP_FR5 (SLJIT_TMP_FREGISTER_BASE + 5)
#define SLJIT_TMP_FR6 (SLJIT_TMP_FREGISTER_BASE + 6)
#define SLJIT_TMP_FR7 (SLJIT_TMP_FREGISTER_BASE + 7)
#define SLJIT_TMP_FR8 (SLJIT_TMP_FREGISTER_BASE + 8)
#define SLJIT_TMP_FR9 (SLJIT_TMP_FREGISTER_BASE + 9)
#define SLJIT_TMP_FR(i) (SLJIT_TMP_FREGISTER_BASE + (i))
/********************************/
/* CPU status flags management. */
/********************************/
@ -781,10 +797,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
|| (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
|| (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|| (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
#define SLJIT_HAS_STATUS_FLAGS_STATE 1
#endif
/***************************************/
/* Floating point register management. */
/***************************************/
#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
#define SLJIT_F64_SECOND(reg) \
((reg) + SLJIT_FS0 + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)
#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */
#define SLJIT_F64_SECOND(reg) \
(reg)
#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */
/*************************************/
/* Debug and verbose related macros. */
/*************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,49 @@
/* mips 32-bit arch dependent functions. */
static sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op,
sljit_sw src1, sljit_sw src2, sljit_sw dst)
{
int is_32 = (op & SLJIT_32);
sljit_ins mfhc = MFC1, mthc = MTC1;
sljit_ins src1_r = FS(src1), src2_r = FS(src2), dst_r = FS(dst);
if (!is_32) {
switch (cpu_feature_list & CPU_FEATURE_FR) {
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
case CPU_FEATURE_FR:
mfhc = MFHC1;
mthc = MTHC1;
break;
#endif /* SLJIT_MIPS_REV >= 2 */
default:
src1_r |= (1 << 11);
src2_r |= (1 << 11);
dst_r |= (1 << 11);
break;
}
}
FAIL_IF(push_inst(compiler, mfhc | T(TMP_REG1) | src1_r, DR(TMP_REG1)));
FAIL_IF(push_inst(compiler, mfhc | T(TMP_REG2) | src2_r, DR(TMP_REG2)));
if (!is_32 && src1 != dst)
FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(src1) | FD(dst), MOVABLE_INS));
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
else
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
#endif /* MIPS III */
FAIL_IF(push_inst(compiler, XOR | T(TMP_REG1) | D(TMP_REG2) | S(TMP_REG2), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, SLL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, XOR | T(TMP_REG2) | D(TMP_REG1) | S(TMP_REG1), DR(TMP_REG1)));
FAIL_IF(push_inst(compiler, mthc | T(TMP_REG1) | dst_r, MOVABLE_INS));
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
if (mthc == MTC1)
return push_inst(compiler, NOP, UNMOVABLE_INS);
#endif /* MIPS III */
return SLJIT_SUCCESS;
}
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
{
if (!(imm & ~0xffff))
@ -44,6 +87,108 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,
sljit_s32 freg, sljit_f64 value)
{
union {
struct {
#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN
sljit_s32 lo;
sljit_s32 hi;
#else /* !SLJIT_LITTLE_ENDIAN */
sljit_s32 hi;
sljit_s32 lo;
#endif /* SLJIT_LITTLE_ENDIAN */
} bin;
sljit_f64 value;
} u;
CHECK_ERROR();
CHECK(check_sljit_emit_fset64(compiler, freg, value));
u.value = value;
if (u.bin.lo != 0)
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.bin.lo));
if (u.bin.hi != 0)
FAIL_IF(load_immediate(compiler, DR(TMP_REG2), u.bin.hi));
FAIL_IF(push_inst(compiler, MTC1 | (u.bin.lo != 0 ? T(TMP_REG1) : TA(0)) | FS(freg), MOVABLE_INS));
switch (cpu_feature_list & CPU_FEATURE_FR) {
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
case CPU_FEATURE_FR:
return push_inst(compiler, MTHC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg), MOVABLE_INS);
#endif /* SLJIT_MIPS_REV >= 2 */
default:
FAIL_IF(push_inst(compiler, MTC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg) | (1 << 11), MOVABLE_INS));
break;
}
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
#endif /* MIPS III */
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 freg, sljit_s32 reg)
{
sljit_s32 reg2 = 0;
sljit_ins inst = FS(freg);
sljit_ins mthc = MTC1, mfhc = MFC1;
int is_32 = (op & SLJIT_32);
CHECK_ERROR();
CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
op = GET_OPCODE(op);
if (reg & REG_PAIR_MASK) {
reg2 = REG_PAIR_SECOND(reg);
reg = REG_PAIR_FIRST(reg);
inst |= T(reg2);
if (op == SLJIT_COPY_TO_F64)
FAIL_IF(push_inst(compiler, MTC1 | inst, MOVABLE_INS));
else
FAIL_IF(push_inst(compiler, MFC1 | inst, DR(reg2)));
inst = FS(freg) | (1 << 11);
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
if (cpu_feature_list & CPU_FEATURE_FR) {
mthc = MTHC1;
mfhc = MFHC1;
inst = FS(freg);
}
#endif /* SLJIT_MIPS_REV >= 2 */
}
inst |= T(reg);
if (!is_32 && !reg2) {
switch (cpu_feature_list & CPU_FEATURE_FR) {
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
case CPU_FEATURE_FR:
mthc = MTHC1;
mfhc = MFHC1;
break;
#endif /* SLJIT_MIPS_REV >= 2 */
default:
inst |= (1 << 11);
break;
}
}
if (op == SLJIT_COPY_TO_F64)
FAIL_IF(push_inst(compiler, mthc | inst, MOVABLE_INS));
else
FAIL_IF(push_inst(compiler, mfhc | inst, DR(reg)));
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
if (mthc == MTC1 || mfhc == MFC1)
return push_inst(compiler, NOP, UNMOVABLE_INS);
#endif /* MIPS III */
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
@ -74,6 +219,11 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
sljit_ins ins = NOP;
sljit_u8 offsets[4];
sljit_u8 *offsets_ptr = offsets;
#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN
sljit_ins f64_hi = TA(7), f64_lo = TA(6);
#else
sljit_ins f64_hi = TA(6), f64_lo = TA(7);
#endif /* SLJIT_LITTLE_ENDIAN */
SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
@ -138,20 +288,28 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
switch (types & SLJIT_ARG_MASK) {
case SLJIT_ARG_TYPE_F64:
if (*offsets_ptr < 4 * sizeof (sljit_sw)) {
if (*offsets_ptr < 4 * sizeof(sljit_sw)) {
if (prev_ins != NOP)
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
/* Must be preceded by at least one other argument,
* and its starting offset must be 8 because of alignment. */
SLJIT_ASSERT((*offsets_ptr >> 2) == 2);
prev_ins = MFC1 | TA(6) | FS(float_arg_count) | (1 << 11);
ins = MFC1 | TA(7) | FS(float_arg_count);
switch (cpu_feature_list & CPU_FEATURE_FR) {
#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2
case CPU_FEATURE_FR:
prev_ins = MFHC1 | f64_hi | FS(float_arg_count);
break;
#endif /* SLJIT_MIPS_REV >= 2 */
default:
prev_ins = MFC1 | f64_hi | FS(float_arg_count) | (1 << 11);
break;
}
ins = MFC1 | f64_lo | FS(float_arg_count);
} else if (*offsets_ptr < 254)
ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);
else if (*offsets_ptr == 254)
ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
ins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1);
float_arg_count--;
break;
@ -161,7 +319,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
else if (*offsets_ptr < 254)
ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr);
else if (*offsets_ptr == 254)
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
ins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1);
float_arg_count--;
break;
@ -285,7 +443,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
if (src & SLJIT_IMM)
if (src == SLJIT_IMM)
FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
else if (src != PIC_ADDR_REG)
FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));

View File

@ -26,6 +26,23 @@
/* mips 64-bit arch dependent functions. */
static sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src1, sljit_s32 src2, sljit_s32 dst)
{
FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG1) | FS(src1), DR(TMP_REG1)));
FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG2) | FS(src2), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, XOR | S(TMP_REG2) | T(TMP_REG1) | D(TMP_REG2), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1)));
FAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | T(TMP_REG1) | FS(dst), MOVABLE_INS));
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
if (!(op & SLJIT_32))
return push_inst(compiler, NOP, UNMOVABLE_INS);
#endif /* MIPS III */
return SLJIT_SUCCESS;
}
static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
{
sljit_s32 shift = 32;
@ -128,6 +145,57 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,
sljit_s32 freg, sljit_f64 value)
{
union {
sljit_sw imm;
sljit_f64 value;
} u;
CHECK_ERROR();
CHECK(check_sljit_emit_fset64(compiler, freg, value));
u.value = value;
if (u.imm == 0) {
FAIL_IF(push_inst(compiler, DMTC1 | TA(0) | FS(freg), MOVABLE_INS));
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
#endif /* MIPS III */
return SLJIT_SUCCESS;
}
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm));
FAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS));
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
#endif /* MIPS III */
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 freg, sljit_s32 reg)
{
sljit_ins inst;
CHECK_ERROR();
CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
inst = T(reg) | FS(freg);
if (GET_OPCODE(op) == SLJIT_COPY_TO_F64)
FAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | inst, MOVABLE_INS));
else
FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | inst, DR(reg)));
#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1
if (!(op & SLJIT_32))
return push_inst(compiler, NOP, UNMOVABLE_INS);
#endif /* MIPS III */
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
@ -183,17 +251,17 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
switch (types & SLJIT_ARG_MASK) {
case SLJIT_ARG_TYPE_F64:
if (arg_count != float_arg_count)
ins = MOV_S | FMT_D | FS(float_arg_count) | FD(arg_count);
ins = MOV_fmt(FMT_D) | FS(float_arg_count) | FD(arg_count);
else if (arg_count == 1)
ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
ins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1);
arg_count--;
float_arg_count--;
break;
case SLJIT_ARG_TYPE_F32:
if (arg_count != float_arg_count)
ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count);
ins = MOV_fmt(FMT_S) | FS(float_arg_count) | FD(arg_count);
else if (arg_count == 1)
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
ins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1);
arg_count--;
float_arg_count--;
break;
@ -300,7 +368,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
if (src & SLJIT_IMM)
if (src == SLJIT_IMM)
FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
else if (src != PIC_ADDR_REG)
FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));

File diff suppressed because it is too large Load Diff

View File

@ -85,10 +85,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
}
return SLJIT_SUCCESS;
case SLJIT_NOT:
SLJIT_ASSERT(src1 == TMP_REG1);
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
case SLJIT_CLZ:
SLJIT_ASSERT(src1 == TMP_REG1);
return push_inst(compiler, CNTLZW | S(src2) | A(dst));
@ -246,6 +242,10 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm)));
return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16));
}
if (flags & ALT_FORM4) {
SLJIT_ASSERT(src1 == TMP_REG1);
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
}
return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
case SLJIT_SHL:
@ -325,6 +325,151 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
}
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 dst, sljit_sw dstw,
sljit_s32 src, sljit_sw srcw)
{
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
sljit_s32 invert_sign = 1;
if (src == SLJIT_IMM) {
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000));
src = TMP_REG1;
invert_sign = 0;
} else if (!FAST_IS_REG(src)) {
FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
}
/* First, a special double precision floating point value is constructed:
(2^53 + (src xor (2^31)))
The upper 32 bits of this number is a constant, and the lower 32 bits
is simply the value of the source argument. The xor 2^31 operation adds
0x80000000 to the source argument, which moves it into the 0 - 0xffffffff
range. Finally we substract 2^53 + 2^31 to get the converted value. */
FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
if (invert_sign)
FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000));
FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));
FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
if (op & SLJIT_32)
FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));
if (dst & SLJIT_MEM)
return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
return SLJIT_SUCCESS;
}
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 dst, sljit_sw dstw,
sljit_s32 src, sljit_sw srcw)
{
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
if (src == SLJIT_IMM) {
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
src = TMP_REG1;
} else if (!FAST_IS_REG(src)) {
FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
}
/* First, a special double precision floating point value is constructed:
(2^53 + src)
The upper 32 bits of this number is a constant, and the lower 32 bits
is simply the value of the source argument. Finally we substract 2^53
to get the converted value. */
FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330));
FAIL_IF(push_inst(compiler, STW | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, STW | S(TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2)));
if (op & SLJIT_32)
FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));
if (dst & SLJIT_MEM)
return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,
sljit_s32 freg, sljit_f64 value)
{
union {
sljit_s32 imm[2];
sljit_f64 value;
} u;
CHECK_ERROR();
CHECK(check_sljit_emit_fset64(compiler, freg, value));
u.value = value;
if (u.imm[0] != 0)
FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0]));
if (u.imm[1] != 0)
FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1]));
/* Saved in the same endianness. */
FAIL_IF(push_inst(compiler, STW | S(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, STW | S(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | A(SLJIT_SP) | (TMP_MEM_OFFSET + sizeof(sljit_s32))));
return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 freg, sljit_s32 reg)
{
sljit_s32 reg2 = 0;
CHECK_ERROR();
CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
if (op & SLJIT_32) {
if (op == SLJIT_COPY32_TO_F32) {
FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
return push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
}
FAIL_IF(push_inst(compiler, STFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
}
if (reg & REG_PAIR_MASK) {
reg2 = REG_PAIR_SECOND(reg);
reg = REG_PAIR_FIRST(reg);
}
if (op == SLJIT_COPY_TO_F64) {
FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI));
if (reg2 != 0)
FAIL_IF(push_inst(compiler, STW | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
else
FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
}
FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
if (reg2 != 0)
FAIL_IF(push_inst(compiler, LWZ | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO));
return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;

View File

@ -49,7 +49,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg,
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
if (!(imm & ~0xffff))
if (((sljit_uw)imm >> 16) == 0)
return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm));
if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
@ -57,6 +57,11 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg,
return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
}
if (((sljit_uw)imm >> 32) == 0) {
FAIL_IF(push_inst(compiler, ORIS | S(TMP_ZERO) | A(reg) | IMM(imm >> 16)));
return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS;
}
/* Count leading zeroes. */
tmp = (sljit_uw)((imm >= 0) ? imm : ~imm);
ASM_SLJIT_CLZ(tmp, shift);
@ -198,11 +203,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
}
return SLJIT_SUCCESS;
case SLJIT_NOT:
SLJIT_ASSERT(src1 == TMP_REG1);
UN_EXTS();
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
case SLJIT_CLZ:
SLJIT_ASSERT(src1 == TMP_REG1);
return push_inst(compiler, ((flags & ALT_FORM1) ? CNTLZW : CNTLZD) | S(src2) | A(dst));
@ -399,6 +399,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm)));
return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16));
}
if (flags & ALT_FORM4) {
SLJIT_ASSERT(src1 == TMP_REG1);
UN_EXTS();
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
}
return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2));
case SLJIT_SHL:
@ -563,6 +568,141 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
}
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 dst, sljit_sw dstw,
sljit_s32 src, sljit_sw srcw)
{
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
if (src == SLJIT_IMM) {
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32)
srcw = (sljit_s32)srcw;
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
src = TMP_REG1;
} else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) {
if (FAST_IS_REG(src))
FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1)));
else
FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
}
if (FAST_IS_REG(src)) {
FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
} else
FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1));
FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
if (op & SLJIT_32)
FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));
if (dst & SLJIT_MEM)
return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
return SLJIT_SUCCESS;
}
static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 dst, sljit_sw dstw,
sljit_s32 src, sljit_sw srcw)
{
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) {
if (src == SLJIT_IMM) {
FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_u32)srcw));
src = TMP_REG1;
} else {
if (FAST_IS_REG(src))
FAIL_IF(push_inst(compiler, CLRLDI(TMP_REG1, src, 32)));
else
FAIL_IF(emit_op_mem(compiler, INT_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
}
FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
} else {
if (src == SLJIT_IMM) {
FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
src = TMP_REG1;
} else if (src & SLJIT_MEM) {
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
}
FAIL_IF(push_inst(compiler, CMPI | CRD(0 | 1) | A(src) | 0));
FAIL_IF(push_inst(compiler, BCx | (12 << 21) | (0 << 16) | 20));
FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
FAIL_IF(push_inst(compiler, Bx | ((op & SLJIT_32) ? 36 : 32)));
if (op & SLJIT_32)
FAIL_IF(push_inst(compiler, RLWINM | S(src) | A(TMP_REG2) | RLWI_SH(10) | RLWI_MBE(10, 21)));
else
FAIL_IF(push_inst(compiler, ANDI | S(src) | A(TMP_REG2) | 0x1));
/* Shift right. */
FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(63) | RLDI_MB(1)));
if (op & SLJIT_32)
FAIL_IF(push_inst(compiler, RLDICR | S(TMP_REG1) | A(TMP_REG1) | RLDI_SH(0) | RLDI_ME(53)));
FAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2)));
FAIL_IF(push_inst(compiler, STD | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET));
FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1)));
FAIL_IF(push_inst(compiler, FADD | FD(dst_r) | FA(dst_r) | FB(dst_r)));
}
if (op & SLJIT_32)
FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)));
if (dst & SLJIT_MEM)
return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1);
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler,
sljit_s32 freg, sljit_f64 value)
{
union {
sljit_sw imm;
sljit_f64 value;
} u;
CHECK_ERROR();
CHECK(check_sljit_emit_fset64(compiler, freg, value));
u.value = value;
if (u.imm != 0)
FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm));
FAIL_IF(push_inst(compiler, STD | S(u.imm != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET));
return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 freg, sljit_s32 reg)
{
CHECK_ERROR();
CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg));
if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) {
FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STW : STD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
return push_inst(compiler, ((op & SLJIT_32) ? LFS : LFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
}
FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STFS : STFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET));
return push_inst(compiler, ((op & SLJIT_32) ? LWZ : LD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins*)addr;

Some files were not shown because too many files have changed in this diff Show More