Merge pull request #2498 from paperless-ngx/fix-2496

Fix: limit asn integer size
This commit is contained in:
shamoon 2023-01-24 10:37:04 -08:00 committed by GitHub
commit c7690c05f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 62 additions and 5 deletions

View File

@ -140,13 +140,13 @@ class Consumer(LoggingMixin):
if not self.override_asn: if not self.override_asn:
# check not necessary in case no ASN gets set # check not necessary in case no ASN gets set
return return
# Validate the range is above zero and less than int32 max # Validate the range is above zero and less than uint32_t max
# otherwise, Whoosh can't handle it in the index # otherwise, Whoosh can't handle it in the index
if self.override_asn < 0 or self.override_asn > 2_147_483_647: if self.override_asn < 0 or self.override_asn > 0xFF_FF_FF_FF:
self._fail( self._fail(
MESSAGE_ASN_RANGE, MESSAGE_ASN_RANGE,
f"Not consuming {self.filename}: " f"Not consuming {self.filename}: "
"Given ASN is out of range [0, 2147483647]", f"Given ASN {self.override_asn} is out of range [0, 4,294,967,295]",
) )
if Document.objects.filter(archive_serial_number=self.override_asn).exists(): if Document.objects.filter(archive_serial_number=self.override_asn).exists():
self._fail( self._fail(

View File

@ -34,7 +34,7 @@ def get_schema():
id=NUMERIC(stored=True, unique=True), id=NUMERIC(stored=True, unique=True),
title=TEXT(sortable=True), title=TEXT(sortable=True),
content=TEXT(), content=TEXT(),
asn=NUMERIC(sortable=True), asn=NUMERIC(sortable=True, signed=False),
correspondent=TEXT(sortable=True), correspondent=TEXT(sortable=True),
correspondent_id=NUMERIC(), correspondent_id=NUMERIC(),
has_correspondent=BOOLEAN(), has_correspondent=BOOLEAN(),

View File

@ -0,0 +1,30 @@
# Generated by Django 4.1.4 on 2023-01-24 17:56
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("documents", "1028_remove_paperlesstask_task_args_and_more"),
]
operations = [
migrations.AlterField(
model_name="document",
name="archive_serial_number",
field=models.PositiveIntegerField(
blank=True,
db_index=True,
help_text="The position of this document in your physical document archive.",
null=True,
unique=True,
validators=[
django.core.validators.MaxValueValidator(4294967295),
django.core.validators.MinValueValidator(0),
],
verbose_name="archive serial number",
),
),
]

View File

@ -10,6 +10,8 @@ import pathvalidate
from celery import states from celery import states
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator
from django.core.validators import MinValueValidator
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -227,12 +229,16 @@ class Document(models.Model):
help_text=_("The original name of the file when it was uploaded"), help_text=_("The original name of the file when it was uploaded"),
) )
archive_serial_number = models.IntegerField( archive_serial_number = models.PositiveIntegerField(
_("archive serial number"), _("archive serial number"),
blank=True, blank=True,
null=True, null=True,
unique=True, unique=True,
db_index=True, db_index=True,
validators=[
MaxValueValidator(0xFF_FF_FF_FF),
MinValueValidator(0),
],
help_text=_( help_text=_(
"The position of this document in your physical document " "archive.", "The position of this document in your physical document " "archive.",
), ),

View File

@ -9,6 +9,7 @@ from django.test import override_settings
from django.test import TestCase from django.test import TestCase
from documents import barcodes from documents import barcodes
from documents import tasks from documents import tasks
from documents.consumer import ConsumerError
from documents.tests.utils import DirectoriesMixin from documents.tests.utils import DirectoriesMixin
from PIL import Image from PIL import Image
@ -804,3 +805,23 @@ class TestBarcode(DirectoriesMixin, TestCase):
args, kwargs = mocked_call.call_args args, kwargs = mocked_call.call_args
self.assertEqual(kwargs["override_asn"], 123) self.assertEqual(kwargs["override_asn"], 123)
@override_settings(CONSUMER_ENABLE_ASN_BARCODE=True)
def test_asn_too_large(self):
src = os.path.join(
os.path.dirname(__file__),
"samples",
"barcodes",
"barcode-128-asn-too-large.pdf",
)
dst = os.path.join(self.dirs.scratch_dir, "barcode-128-asn-too-large.pdf")
shutil.copy(src, dst)
with mock.patch("documents.consumer.Consumer._send_progress"):
self.assertRaisesMessage(
ConsumerError,
"Given ASN 4294967296 is out of range [0, 4,294,967,295]",
tasks.consume_file,
dst,
)