From ab26d285759e4c917879967b09976a44829ed570 Mon Sep 17 00:00:00 2001
From: Gustavo Lopes <mail@geleia.net>
Date: Mon, 16 Aug 2021 01:28:05 +0100
Subject: [PATCH] Fixes for PHP 8.1

---
 rar_stream.c   |  6 ++++++
 rararch.c      |  8 +++++++-
 rarentry.c     | 26 +++++++++++++++-----------
 tests/047.phpt |  6 +++---
 4 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/rar_stream.c b/rar_stream.c
index 6fe207a..c6546a6 100644
--- a/rar_stream.c
+++ b/rar_stream.c
@@ -784,7 +784,13 @@ static int _rar_get_archive_and_fragment(php_stream_wrapper *wrapper,
 #if PHP_MAJOR_VERSION < 7
 			*archive = zend_resolve_path(tmp_archive, tmp_arch_len TSRMLS_CC);
 #else
+#  if PHP_VERSION_ID < 80100
 			zend_string *arc_str = zend_resolve_path(tmp_archive, tmp_arch_len);
+#  else
+			zend_string *tmp_archive_str = zend_string_init_fast(tmp_archive, tmp_arch_len);
+			zend_string *arc_str = zend_resolve_path(tmp_archive_str);
+			zend_string_free(tmp_archive_str);
+#  endif
 			if (arc_str != NULL) {
 				*archive = estrndup(arc_str->val, arc_str->len);
 			} else {
diff --git a/rararch.c b/rararch.c
index ed79f10..7cbfa26 100644
--- a/rararch.c
+++ b/rararch.c
@@ -28,6 +28,7 @@
 /* $Id$ */
 
 #include "zend_types.h"
+#include <zend_API.h>
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -962,6 +963,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_rararchive_setallowbroken, 0, 0, 1)
 	ZEND_ARG_INFO(0, allow_broken)
 ZEND_END_ARG_INFO()
 
+#if PHP_MAJOR_VERSION >= 8
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_rararchive_getiterator, 0, 0, Traversable, 0)
+ZEND_END_ARG_INFO()
+#endif
+
 ZEND_BEGIN_ARG_INFO(arginfo_rararchive_void, 0)
 ZEND_END_ARG_INFO()
 /* }}} */
@@ -981,7 +987,7 @@ static zend_function_entry php_rararch_class_functions[] = {
 	PHP_ME(rararch,					__toString,				arginfo_rararchive_void,		ZEND_ACC_PUBLIC)
 	PHP_ME_MAPPING(__construct,		rar_bogus_ctor,			arginfo_rararchive_void,		ZEND_ACC_PRIVATE | ZEND_ACC_CTOR)
 #if PHP_MAJOR_VERSION >= 8
-	PHP_ME(rararch,					getIterator,			arginfo_rararchive_void,		ZEND_ACC_PUBLIC)
+	PHP_ME(rararch,					getIterator,			arginfo_rararchive_getiterator,	ZEND_ACC_PUBLIC)
 #endif
 	{NULL, NULL, NULL}
 };
diff --git a/rarentry.c b/rarentry.c
index 5943f38..5e680f6 100644
--- a/rarentry.c
+++ b/rarentry.c
@@ -27,11 +27,10 @@
 
 /* $Id$ */
 
-#ifdef __cplusplus
-extern "C" {
+#include <zend_types.h>
+#ifndef _GNU_SOURCE
+#  define _GNU_SOURCE
 #endif
-
-#define _GNU_SOURCE
 #include <string.h>
 
 #include <php.h>
@@ -270,8 +269,8 @@ static void _rar_dos_date_to_text(unsigned dos_time, char *date_string) /* {{{ *
 /* }}} */
 
 /* {{{ Methods */
-/* {{{ proto bool RarEntry::extract(string dir [, string filepath = ''
-       [, string password = NULL [, bool extended_data  = FALSE]])
+/* {{{ public function extract(?string $dir, ?string $filepath = '',
+		?string $password = null, bool $extended_data = false): void {}
    Extract file from the archive */
 PHP_METHOD(rarentry, extract)
 { /* lots of variables, but no need to be intimidated */
@@ -298,7 +297,7 @@ PHP_METHOD(rarentry, extract)
 	 * password that's different from the one stored in the rar_file_t object*/
 	rar_cb_user_data		cb_udata = {NULL};
 
-	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss!b", &dir,
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!|s!s!b", &dir,
 			&dir_len, &filepath, &filepath_len, &password, &password_len,
 			&process_ed) == FAILURE ) {
 		return;
@@ -714,12 +713,21 @@ PHP_METHOD(rarentry, __toString)
 /* }}} */
 
 /* {{{ arginfo */
+#if PHP_MAJOR_VERSION < 8
 ZEND_BEGIN_ARG_INFO_EX(arginfo_rarentry_extract, 0, 0, 1)
 	ZEND_ARG_INFO(0, path)
 	ZEND_ARG_INFO(0, filename)
 	ZEND_ARG_INFO(0, password)
 	ZEND_ARG_INFO(0, extended_data)
 ZEND_END_ARG_INFO()
+#else
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rarentry_extract, 0, 1, _IS_BOOL, 0)
+	ZEND_ARG_TYPE_INFO(0, dir, IS_STRING, 1)
+	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filepath, IS_STRING, 1, "\'\'")
+	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, password, IS_STRING, 1, "null")
+	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extended_data, _IS_BOOL, 0, "false")
+ZEND_END_ARG_INFO()
+#endif
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_rarentry_getstream, 0, 0, 0)
 	ZEND_ARG_INFO(0, password)
@@ -829,7 +837,3 @@ void minit_rarentry(TSRMLS_D)
 	REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SYM_LINK",				0x0A000L);
 	REG_RAR_CLASS_CONST_LONG("ATTRIBUTE_UNIX_SOCKET",				0x0C000L);
 }
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tests/047.phpt b/tests/047.phpt
index b1b5f53..8bd3e90 100644
--- a/tests/047.phpt
+++ b/tests/047.phpt
@@ -10,9 +10,9 @@ function resolve($vol) {
 	else
 		return null;
 }
-function int32_to_hex($value) { 
-  $value &= 0xffffffff; 
-  return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT); 
+function int32_to_hex($value) {
+  $value &= 0xffffffff;
+  return str_pad(strtoupper(dechex($value)), 8, "0", STR_PAD_LEFT);
 }
 echo "Fail:\n";
 $rar_file1 = rar_open(dirname(__FILE__).'/multi_broken.part1.rar');
-- 
2.31.1