Skip to content

ext/standard/pack: minor refactoring #18822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 12, 2025
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 17 additions & 40 deletions ext/standard/pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,10 @@

#include "php.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef PHP_WIN32
#define O_RDONLY _O_RDONLY
#include "win32/param.h"
#else
#include <sys/param.h>
#endif
#include "pack.h"
#ifdef HAVE_PWD_H
#ifdef PHP_WIN32
#include "win32/pwd.h"
#else
#include <pwd.h>
#endif
#endif
#include "fsock.h"
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif

#define INC_OUTPUTPOS(a,b) \
if ((a) < 0 || ((INT_MAX - outputpos)/((int)b)) < (a)) { \
Expand Down Expand Up @@ -274,7 +254,7 @@ PHP_FUNCTION(pack)
}

/* Handle special arg '*' for all codes and check argv overflows */
switch ((int) code) {
switch (code) {
/* Never uses any args */
case 'x':
case 'X':
Expand Down Expand Up @@ -380,10 +360,10 @@ PHP_FUNCTION(pack)

/* Calculate output length and upper bound while processing*/
for (i = 0; i < formatcount; i++) {
int code = (int) formatcodes[i];
char code = formatcodes[i];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains leading spaces while the rest of the file uses tab

int arg = formatargs[i];

switch ((int) code) {
switch (code) {
case 'h':
case 'H':
INC_OUTPUTPOS((arg + (arg % 2)) / 2,1) /* 4 bit per arg */
Expand Down Expand Up @@ -463,10 +443,10 @@ PHP_FUNCTION(pack)

/* Do actual packing */
for (i = 0; i < formatcount; i++) {
int code = (int) formatcodes[i];
char code = formatcodes[i];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contains leading spaces while the rest of the file uses tab

int arg = formatargs[i];

switch ((int) code) {
switch (code) {
case 'a':
case 'A':
case 'Z': {
Expand Down Expand Up @@ -632,7 +612,7 @@ PHP_FUNCTION(pack)

case 'd': {
while (arg-- > 0) {
double v = (double) zval_get_double(&argv[currentarg++]);
double v = zval_get_double(&argv[currentarg++]);
memcpy(&ZSTR_VAL(output)[outputpos], &v, sizeof(v));
outputpos += sizeof(v);
}
Expand All @@ -642,7 +622,7 @@ PHP_FUNCTION(pack)
case 'e': {
/* pack little endian double */
while (arg-- > 0) {
double v = (double) zval_get_double(&argv[currentarg++]);
double v = zval_get_double(&argv[currentarg++]);
php_pack_copy_double(1, &ZSTR_VAL(output)[outputpos], v);
outputpos += sizeof(v);
}
Expand All @@ -652,7 +632,7 @@ PHP_FUNCTION(pack)
case 'E': {
/* pack big endian double */
while (arg-- > 0) {
double v = (double) zval_get_double(&argv[currentarg++]);
double v = zval_get_double(&argv[currentarg++]);
php_pack_copy_double(0, &ZSTR_VAL(output)[outputpos], v);
outputpos += sizeof(v);
}
Expand Down Expand Up @@ -737,15 +717,14 @@ PHP_FUNCTION(unpack)

while (formatlen-- > 0) {
char type = *(format++);
char c;
int repetitions = 1, argb;
char *name;
int namelen;
int size = 0;

/* Handle format arguments if any */
if (formatlen > 0) {
c = *format;
char c = *format;

if (c >= '0' && c <= '9') {
errno = 0;
Expand Down Expand Up @@ -784,7 +763,7 @@ PHP_FUNCTION(unpack)
if (namelen > 200)
namelen = 200;

switch ((int) type) {
switch (type) {
/* Never use any input */
case 'X':
size = -1;
Expand Down Expand Up @@ -899,7 +878,7 @@ PHP_FUNCTION(unpack)
real_name = zend_string_concat2(name, namelen, res, digits);
}

switch ((int) type) {
switch (type) {
case 'a': {
/* a will not strip any trailing whitespace or null padding */
zend_long len = inputlen - inputpos; /* Remaining string */
Expand All @@ -917,7 +896,6 @@ PHP_FUNCTION(unpack)
}
case 'A': {
/* A will strip any trailing whitespace */
char padn = '\0'; char pads = ' '; char padt = '\t'; char padc = '\r'; char padl = '\n';
zend_long len = inputlen - inputpos; /* Remaining string */

/* If size was given take minimum of len and size */
Expand All @@ -929,11 +907,11 @@ PHP_FUNCTION(unpack)

/* Remove trailing white space and nulls chars from unpacked data */
while (--len >= 0) {
if (input[inputpos + len] != padn
&& input[inputpos + len] != pads
&& input[inputpos + len] != padt
&& input[inputpos + len] != padc
&& input[inputpos + len] != padl
if (input[inputpos + len] != '\0'
&& input[inputpos + len] != ' '
&& input[inputpos + len] != '\t'
&& input[inputpos + len] != '\r'
&& input[inputpos + len] != '\n'
)
break;
}
Expand All @@ -945,7 +923,6 @@ PHP_FUNCTION(unpack)
/* New option added for Z to remain in-line with the Perl implementation */
case 'Z': {
/* Z will strip everything after the first null character */
char pad = '\0';
zend_long s,
len = inputlen - inputpos; /* Remaining string */

Expand All @@ -958,7 +935,7 @@ PHP_FUNCTION(unpack)

/* Remove everything after the first null */
for (s=0 ; s < len ; s++) {
if (input[inputpos + s] == pad)
if (input[inputpos + s] == '\0')
break;
}
len = s;
Expand Down