Skip to content

Commit

Permalink
Merge pull request #64 from eclipxe13/version-0.5.4
Browse files Browse the repository at this point in the history
Corrección de paquetes truncados al descargar y mantenimiento (v0.5.4)
  • Loading branch information
eclipxe13 authored Apr 17, 2024
2 parents 7fc5256 + b922c1e commit 4f95e0d
Show file tree
Hide file tree
Showing 16 changed files with 228 additions and 42 deletions.
36 changes: 18 additions & 18 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.3'
coverage: none
tools: cs2pr, phpcs
env:
Expand All @@ -35,11 +35,11 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.3'
coverage: none
tools: cs2pr, php-cs-fixer
env:
Expand All @@ -52,11 +52,11 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.3'
coverage: none
tools: composer:v2, phpstan
env:
Expand All @@ -65,29 +65,29 @@ jobs:
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
path: "${{ steps.composer-cache.outputs.dir }}"
key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}"
restore-keys: "${{ runner.os }}-composer-"
- name: Install project dependencies
run: composer upgrade --no-interaction --no-progress --prefer-dist
- name: PHPStan
run: phpstan analyse --no-progress --verbose

tests:
name: Tests on PHP ${{ matrix.php-versions }}
name: Tests on PHP ${{ matrix.php-version }}
runs-on: "ubuntu-latest"
strategy:
matrix:
php-versions: ['7.3', '7.4', '8.0', '8.1', '8.2']
php-version: ['7.3', '7.4', '8.0', '8.1', '8.2', '8.3']
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
php-version: ${{ matrix.php-version }}
coverage: none
tools: composer:v2
env:
Expand All @@ -96,11 +96,11 @@ jobs:
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
path: "${{ steps.composer-cache.outputs.dir }}"
key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}"
restore-keys: "${{ runner.os }}-composer-"
- name: Install project dependencies
run: composer upgrade --no-interaction --no-progress --prefer-dist
- name: Tests (phpunit)
Expand Down
30 changes: 15 additions & 15 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ on:
jobs:

tests-coverage:
name: Tests on PHP 8.2 (code coverage)
name: Create code coverage
runs-on: "ubuntu-latest"
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.3'
coverage: xdebug
tools: composer:v2
env:
Expand All @@ -28,17 +28,17 @@ jobs:
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
path: "${{ steps.composer-cache.outputs.dir }}"
key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}"
restore-keys: "${{ runner.os }}-composer-"
- name: Install project dependencies
run: composer upgrade --no-interaction --no-progress --prefer-dist
- name: Create code coverage
run: vendor/bin/phpunit --testdox --verbose --coverage-xml=build/coverage --coverage-clover=build/coverage/clover.xml --log-junit=build/coverage/junit.xml
- name: Store code coverage
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: ${{ !env.ACT }} # do not run using nektos/act
with:
name: code-coverage
Expand Down Expand Up @@ -74,28 +74,28 @@ jobs:
runs-on: "ubuntu-latest"
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Unshallow clone to provide blame information
run: git fetch --unshallow
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.3'
coverage: none
tools: composer:v2
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
restore-keys: ${{ runner.os }}-composer-
path: "${{ steps.composer-cache.outputs.dir }}"
key: "${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}"
restore-keys: "${{ runner.os }}-composer-"
- name: Install project dependencies
run: composer upgrade --no-interaction --no-progress --prefer-dist
- name: Obtain code coverage
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: code-coverage
path: build/coverage
Expand Down
8 changes: 4 additions & 4 deletions .phive/phars.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phive xmlns="https://phar.io/phive">
<phar name="php-cs-fixer" version="^3.37.1" installed="3.37.1" location="./tools/php-cs-fixer" copy="false"/>
<phar name="phpcs" version="^3.7.2" installed="3.7.2" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^3.7.2" installed="3.7.2" location="./tools/phpcbf" copy="false"/>
<phar name="phpstan" version="^1.10.40" installed="1.10.40" location="./tools/phpstan" copy="false"/>
<phar name="php-cs-fixer" version="^3.54.0" installed="3.54.0" location="./tools/php-cs-fixer" copy="false"/>
<phar name="phpcs" version="^3.9.1" installed="3.9.1" location="./tools/phpcs" copy="false"/>
<phar name="phpcbf" version="^3.9.1" installed="3.9.1" location="./tools/phpcbf" copy="false"/>
<phar name="phpstan" version="^1.10.67" installed="1.10.67" location="./tools/phpstan" copy="false"/>
</phive>
1 change: 1 addition & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
'standardize_not_equals' => true,
'concat_space' => ['spacing' => 'one'],
'linebreak_after_opening_tag' => true,
'fully_qualified_strict_types' => true,
// symfony:risky
'no_alias_functions' => true,
'self_accessor' => true,
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2019 - 2023 PhpCfdi https://www.phpcfdi.com/
Copyright (c) 2019 - 2024 PhpCfdi https://www.phpcfdi.com/

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"ext-json": "*",
"ext-zip": "*",
"ext-mbstring": "*",
"ext-libxml": "*",
"phpcfdi/credentials": "^1.1",
"phpcfdi/rfc": "^1.1",
"eclipxe/enum": "^0.2.0",
Expand Down
23 changes: 23 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,29 @@ que nombraremos así: ` Breaking . Feature . Fix `, donde:
**Importante:** Las reglas de SEMVER no aplican si estás usando una rama (por ejemplo `main-dev`)
o estás usando una versión cero (por ejemplo `0.18.4`).

## Versión 0.5.4 2024-04-17

- Se corrige un bug donde en algunas ocasiones falla al procesar la respuesta de una descarga de paquetes.

El método `DOMDocument::loadXML()` con `LibXML >= 1.11.0` trunca a 10,000,000 bytes el contenido de un
nodo de tipo texto. Esto lleva a que el contenido de un paquete se trunque y el archivo ZIP descargado
se encuentre truncado y, por lo tanto, corrupto. Se ha corregido usando la opción `LIBXML_PARSEHUGE`.
Al usar `LIBXML_PARSEHUGE` se está quitando una protección natural que impide una denegación de servicio.
Sin embargo, podemos considerar segura esta acción dado que solo ocurre en el contexto de respuestas
recibidas del servicio de descarga masiva del SAT.

- Se actualiza el archivo de licencia a 2024.

## Mantenimiento 2024-04-17

- Se mejoran las pruebas del rasgo `ComplementoTrait`.
- Se actualizaron los flujos de trabajo:
- Se agregó PHP 8.3 a la matriz de pruebas.
- Los trabajos ahora corren en PHP 8.3.
- Se actualizan las acciones de GitHub a la versión 4.
- Se cambia la variable `build/tests/matrix/php-versions` a singular.
- Se actualizaron las herramientas de desarrollo.

## Mantenimiento 2023-10-30

- El proceso de integración continua falló al momento de verificar el estilo de código con `php-cs-fixer:3.37.1`.
Expand Down
4 changes: 2 additions & 2 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="EngineWorks">
<description>The EngineWorks (PSR-2 based) coding standard.</description>
<description>The EngineWorks (PSR-12 based) coding standard.</description>

<file>src</file>
<file>tests</file>
Expand Down
3 changes: 2 additions & 1 deletion src/Internal/InteractsXmlTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public function readXmlDocument(string $source): DOMDocument
throw new InvalidArgumentException('Cannot load an xml with empty content');
}
$document = new DOMDocument();
$document->loadXML($source);
// as of libxml2 >= 1.11.0 it will truncate huge text nodes (like the zip files in base64)
$document->loadXML($source, LIBXML_PARSEHUGE);
return $document;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Shared/ComplementoTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function label(): string
return $label;
}
}
return '';
return ''; // @codeCoverageIgnore
}

public function jsonSerialize(): string
Expand Down
87 changes: 87 additions & 0 deletions tests/Unit/Services/Download/DownloadTranslatorContentsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

declare(strict_types=1);

namespace PhpCfdi\SatWsDescargaMasiva\Tests\Unit\Services\Download;

use LogicException;
use PhpCfdi\SatWsDescargaMasiva\Services\Download\DownloadTranslator;
use PhpCfdi\SatWsDescargaMasiva\Tests\TestCase;
use ZipArchive;

final class DownloadTranslatorContentsTest extends TestCase
{
private const FILE_SIZE_LIMIT = 10 * 1024 * 1024; // 10 MiB

/** @var string */
private $hugeZipFile;

/** @var string */
private $hugeResponse;

protected function setUp(): void
{
parent::setUp();
$hugeZipFile = tempnam('', '');
if (false === $hugeZipFile) {
throw new LogicException('Unable to create a temporary file');
}

$this->hugeZipFile = $hugeZipFile;
$this->createHugeZipFile($this->hugeZipFile);
$this->hugeResponse = $this->createHugeResponse($this->hugeZipFile);
if (strlen($this->hugeResponse) < self::FILE_SIZE_LIMIT) {
throw new LogicException(
sprintf('Unable to create a response with size bigger than %s bytes', self::FILE_SIZE_LIMIT)
);
}
}

protected function tearDown(): void
{
unlink($this->hugeZipFile);
parent::tearDown();
}

private function createHugeZipFile(string $destination): void
{
$chunkSize = 2 * 1024 * 1024; // 1MB
$limitSize = self::FILE_SIZE_LIMIT; // 10MB
$fileCount = intval($limitSize / $chunkSize) + 1;
$archive = new ZipArchive();
$archive->open($destination, ZipArchive::OVERWRITE);
for ($i = 1; $i < $fileCount; $i++) {
/** @noinspection PhpUnhandledExceptionInspection */
$archive->addFromString(sprintf('%d.txt', $i), random_bytes($chunkSize));
}
$archive->close();
}

private function createHugeResponse(string $contentFile): string
{
$template = $this->fileContents('download/response-with-package-template.xml');
$template = (string) preg_replace('/>\s+</', '><', $template);
$template = str_replace('?>', "?>\n", $template);
$search = '<Paquete />';
$strpos = (int) strpos($template, $search);
/** @noinspection PhpUnnecessaryLocalVariableInspection */
$template = substr($template, 0, $strpos)
. '<Paquete>' . base64_encode((string) file_get_contents($contentFile)) . '</Paquete>'
. substr($template, $strpos + strlen($search));
// file_put_contents('/tmp/sample-response.xml', $template);
return $template;
}

public function testCreateDownloadResultFromHugeResponse(): void
{
$translator = new DownloadTranslator();

$result = $translator->createDownloadResultFromSoapResponse($this->hugeResponse);

$this->assertSame(
sha1_file($this->hugeZipFile),
sha1($result->getPackageContent()),
'Extracted package contents for huge file are not the expected',
);
}
}
2 changes: 2 additions & 0 deletions tests/Unit/Shared/ComplementoCfdiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ public function testSample(): void
{
$complemento = ComplementoCfdi::valesDespensa10();
$this->assertFalse($complemento->isUndefined());
$this->assertTrue($complemento->{'isValesDespensa10'}());
$this->assertSame('valesdedespensa', $complemento->value());
$this->assertSame('Vales de despensa 1.0', $complemento->label());
$this->assertEquals(new ComplementoCfdi('valesdedespensa'), $complemento);
$this->assertEquals(ComplementoCfdi::create('valesdedespensa'), $complemento);
}
}
Loading

0 comments on commit 4f95e0d

Please sign in to comment.