Repository: python-pillow/Pillow

Issue:
Exif tag 'IptcNaaInfo' (33723) causes crash when saving TIFF as JPEG ('TypeError: object of type 'int' has no len()')
<!--
Thank you for reporting an issue.

Follow these guidelines to ensure your issue is handled properly.

If you have a ...

1.  General question: consider asking the question on Stack Overflow
    with the python-imaging-library tag:

    * https://stackoverflow.com/questions/tagged/python-imaging-library

    Do not ask a question in both places.

    If you think you have found a bug or have an unexplained exception
    then file a bug report here.

2.  Bug report: include a self-contained, copy-pastable example that
    generates the issue if possible. Be concise with code posted.
    Guidelines on how to provide a good bug report:

    * https://stackoverflow.com/help/mcve

    Bug reports which follow these guidelines are easier to diagnose,
    and are often handled much more quickly.

3.  Feature request: do a quick search of existing issues
    to make sure this has not been asked before.

We know asking good questions takes effort, and we appreciate your time.
Thank you.
-->

### What did you do?

Opened TIFF image, grabbed exif, tried to save TIFF as JPEG with exif.

### What did you expect to happen?

JPEG to be saved successfully.

### What actually happened?

Crash: `TypeError: object of type 'int' has no len()`

### What are your OS, Python and Pillow versions?

* OS:  EndeavourOS
* Python: 3.10 & 3.11
* Pillow: 9.4.0 and current git

<!--
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
-->

```python
from PIL import Image, ExifTags, TiffImagePlugin, ImageOps
Image.MAX_IMAGE_PIXELS = None
src_img = Image.open("7ba1a16b64cb74a285d0b8f0e5ea652d-2002-078-839.tif")
exif = src_img.getexif()
dst_img = ImageOps.exif_transpose(src_img).convert("RGB")
dst_img.save("test.jpg", quality=95, exif=exif)
```

Removing the tag allows the jpeg to be saved successfully. This seems to be at least related to the same tag as issue #5852.
[Image to reproduce](https://api.collectie.gent/storage/v1/download/7ba1a16b64cb74a285d0b8f0e5ea652d-2002-078-839.tif)



Discussion:

Resolving patch:
diff --git a/src/PIL/TiffImagePlugin.py b/src/PIL/TiffImagePlugin.py
--- a/src/PIL/TiffImagePlugin.py
+++ b/src/PIL/TiffImagePlugin.py
@@ -764,6 +764,8 @@ def load_undefined(self, data, legacy_api=True):
 
     @_register_writer(7)
     def write_undefined(self, value):
+        if isinstance(value, int):
+            value = str(value).encode("ascii", "replace")
         return value
 
     @_register_loader(10, 8)


Test patch:
diff --git a/Tests/test_file_tiff_metadata.py b/Tests/test_file_tiff_metadata.py
--- a/Tests/test_file_tiff_metadata.py
+++ b/Tests/test_file_tiff_metadata.py
@@ -216,6 +216,22 @@ def test_writing_other_types_to_bytes(value, tmp_path):
         assert reloaded.tag_v2[700] == b"\x01"
 
 
+def test_writing_other_types_to_undefined(tmp_path):
+    im = hopper()
+    info = TiffImagePlugin.ImageFileDirectory_v2()
+
+    tag = TiffTags.TAGS_V2[33723]
+    assert tag.type == TiffTags.UNDEFINED
+
+    info[33723] = 1
+
+    out = str(tmp_path / "temp.tiff")
+    im.save(out, tiffinfo=info)
+
+    with Image.open(out) as reloaded:
+        assert reloaded.tag_v2[33723] == b"1"
+
+
 def test_undefined_zero(tmp_path):
     # Check that the tag has not been changed since this test was created
     tag = TiffTags.TAGS_V2[45059]