Page MenuHomePhorge

No OneTemporary

Authored By
Unknown
Size
14 KB
Referenced Files
None
Subscribers
None
diff --git a/changelog.d/exif-heic-gps.security b/changelog.d/exif-heic-gps.security
new file mode 100644
index 000000000..0ca439d0c
--- /dev/null
+++ b/changelog.d/exif-heic-gps.security
@@ -0,0 +1 @@
+Strip GPS data from WebP and HEIC/AVIF uploads; the Exiftool.StripLocation filter used to skip them
diff --git a/changelog.d/exif-stripper.change b/changelog.d/exif-stripper.change
new file mode 100644
index 000000000..ba8d47a19
--- /dev/null
+++ b/changelog.d/exif-stripper.change
@@ -0,0 +1 @@
+Exiftool upload filters are replaced by the built-in Exif.StripLocation and Exif.ReadDescription filters; exiftool is no longer required, old filter names still work but are deprecated
diff --git a/lib/pleroma/application_requirements.ex b/lib/pleroma/application_requirements.ex
index 87ecb7e2d..d9f4eb1d0 100644
--- a/lib/pleroma/application_requirements.ex
+++ b/lib/pleroma/application_requirements.ex
@@ -168,8 +168,6 @@ defmodule Pleroma.ApplicationRequirements do
defp check_system_commands!(:ok) do
filter_commands_statuses = [
- check_filter(Pleroma.Upload.Filter.Exiftool.StripLocation, "exiftool"),
- check_filter(Pleroma.Upload.Filter.Exiftool.ReadDescription, "exiftool"),
check_filter(Pleroma.Upload.Filter.Mogrify, "mogrify"),
check_filter(Pleroma.Upload.Filter.Mogrifun, "mogrify"),
check_filter(Pleroma.Upload.Filter.AnalyzeMetadata, "ffprobe")
diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex
index 934a4a02e..b383b646c 100644
--- a/lib/pleroma/config/deprecation_warnings.ex
+++ b/lib/pleroma/config/deprecation_warnings.ex
@@ -22,40 +22,44 @@ defmodule Pleroma.Config.DeprecationWarnings do
@logger_formatter_config_knobs [:colors, :format, :metadata, :truncate, :utc_log]
+ @exiftool_filter_replacements %{
+ Pleroma.Upload.Filter.Exiftool => Pleroma.Upload.Filter.Exif.StripLocation,
+ Pleroma.Upload.Filter.Exiftool.StripLocation => Pleroma.Upload.Filter.Exif.StripLocation,
+ Pleroma.Upload.Filter.Exiftool.ReadDescription => Pleroma.Upload.Filter.Exif.ReadDescription
+ }
+
def check_exiftool_filter do
filters = Config.get([Pleroma.Upload]) |> Keyword.get(:filters, [])
- if Pleroma.Upload.Filter.Exiftool in filters do
- Logger.warning("""
- !!!DEPRECATION WARNING!!!
- Your config is using Exiftool as a filter instead of Exiftool.StripLocation. This should work for now, but you are advised to change to the new configuration to prevent possible issues later:
-
- ```
- config :pleroma, Pleroma.Upload,
- filters: [Pleroma.Upload.Filter.Exiftool]
- ```
+ deprecated_filters =
+ filters
+ |> Enum.filter(&Map.has_key?(@exiftool_filter_replacements, &1))
+ |> Enum.uniq()
- Is now
+ case deprecated_filters do
+ [] ->
+ :ok
+ deprecated_filters ->
+ replacements =
+ Enum.map_join(deprecated_filters, fn filter ->
+ "\n* `#{inspect(filter)}` is now `#{inspect(@exiftool_filter_replacements[filter])}`"
+ end)
- ```
- config :pleroma, Pleroma.Upload,
- filters: [Pleroma.Upload.Filter.Exiftool.StripLocation]
- ```
- """)
+ Logger.warning("""
+ !!!DEPRECATION WARNING!!!
+ Your config is using Exiftool upload filters. Pleroma no longer needs exiftool, the filters were replaced by built-in ones. The old names should work for now, but you are advised to change to the new configuration to prevent possible issues later:
+ #{replacements}
+ """)
- new_config =
- filters
- |> Enum.map(fn
- Pleroma.Upload.Filter.Exiftool -> Pleroma.Upload.Filter.Exiftool.StripLocation
- filter -> filter
- end)
+ new_config =
+ filters
+ |> Enum.map(&Map.get(@exiftool_filter_replacements, &1, &1))
+ |> Enum.uniq()
- Config.put([Pleroma.Upload, :filters], new_config)
+ Config.put([Pleroma.Upload, :filters], new_config)
- :error
- else
- :ok
+ :error
end
end
diff --git a/lib/pleroma/upload/filter/exiftool.ex b/lib/pleroma/upload/filter/exiftool.ex
new file mode 100644
index 000000000..869ac8b2b
--- /dev/null
+++ b/lib/pleroma/upload/filter/exiftool.ex
@@ -0,0 +1,14 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Upload.Filter.Exiftool do
+ @moduledoc """
+ Deprecated: use `Pleroma.Upload.Filter.Exif.StripLocation`. This module delegates to it.
+ """
+
+ @behaviour Pleroma.Upload.Filter
+
+ @impl true
+ defdelegate filter(upload), to: Pleroma.Upload.Filter.Exif.StripLocation
+end
diff --git a/lib/pleroma/upload/filter/exiftool/read_description.ex b/lib/pleroma/upload/filter/exiftool/read_description.ex
index 8283b8643..c1c60dfdc 100644
--- a/lib/pleroma/upload/filter/exiftool/read_description.ex
+++ b/lib/pleroma/upload/filter/exiftool/read_description.ex
@@ -4,51 +4,11 @@
defmodule Pleroma.Upload.Filter.Exiftool.ReadDescription do
@moduledoc """
- Gets a valid description from the related EXIF tags and provides them in the response if no description is provided yet.
- It will first check ImageDescription, when that doesn't probide a valid description, it will check iptc:Caption-Abstract.
- A valid description means the fields are filled in and not too long (see `:instance, :description_limit`).
+ Deprecated: use `Pleroma.Upload.Filter.Exif.ReadDescription`. This module delegates to it.
"""
- @behaviour Pleroma.Upload.Filter
-
- def filter(%Pleroma.Upload{description: description})
- when is_binary(description),
- do: {:ok, :noop}
-
- def filter(%Pleroma.Upload{tempfile: file} = upload),
- do: {:ok, :filtered, upload |> Map.put(:description, read_description_from_exif_data(file))}
-
- def filter(_, _), do: {:ok, :noop}
- defp read_description_from_exif_data(file) do
- nil
- |> read_when_empty(file, "-ImageDescription")
- |> read_when_empty(file, "-iptc:Caption-Abstract")
- end
-
- defp read_when_empty(current_description, _, _) when is_binary(current_description),
- do: current_description
-
- defp read_when_empty(_, file, tag) do
- if File.exists?(file) do
- try do
- {tag_content, 0} =
- System.cmd("exiftool", ["-m", "-b", "-s3", tag, file],
- stderr_to_stdout: false,
- parallelism: true
- )
-
- tag_content = String.trim(tag_content)
+ @behaviour Pleroma.Upload.Filter
- if tag_content != "" and
- String.length(tag_content) <=
- Pleroma.Config.get([:instance, :description_limit]),
- do: tag_content,
- else: nil
- rescue
- _ in ErlangError -> nil
- end
- else
- nil
- end
- end
+ @impl true
+ defdelegate filter(upload), to: Pleroma.Upload.Filter.Exif.ReadDescription
end
diff --git a/lib/pleroma/upload/filter/exiftool/strip_location.ex b/lib/pleroma/upload/filter/exiftool/strip_location.ex
index 23346d234..3e64adca8 100644
--- a/lib/pleroma/upload/filter/exiftool/strip_location.ex
+++ b/lib/pleroma/upload/filter/exiftool/strip_location.ex
@@ -4,30 +4,11 @@
defmodule Pleroma.Upload.Filter.Exiftool.StripLocation do
@moduledoc """
- Strips GPS related EXIF tags and overwrites the file in place.
- Also strips or replaces filesystem metadata e.g., timestamps.
+ Deprecated: use `Pleroma.Upload.Filter.Exif.StripLocation`. This module delegates to it.
"""
- @behaviour Pleroma.Upload.Filter
-
- # Formats not compatible with exiftool at this time
- def filter(%Pleroma.Upload{content_type: "image/heic"}), do: {:ok, :noop}
- def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop}
- def filter(%Pleroma.Upload{content_type: "image/svg" <> _}), do: {:ok, :noop}
- def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
- try do
- case System.cmd("exiftool", ["-m", "-overwrite_original", "-gps:all=", "-png:all=", file],
- stderr_to_stdout: true,
- parallelism: true
- ) do
- {_response, 0} -> {:ok, :filtered}
- {error, _} -> {:error, error}
- end
- rescue
- e in ErlangError ->
- {:error, "#{__MODULE__}: #{inspect(e)}"}
- end
- end
+ @behaviour Pleroma.Upload.Filter
- def filter(_), do: {:ok, :noop}
+ @impl true
+ defdelegate filter(upload), to: Pleroma.Upload.Filter.Exif.StripLocation
end
diff --git a/test/pleroma/config/deprecation_warnings_test.exs b/test/pleroma/config/deprecation_warnings_test.exs
index 62f5bdeea..65b6a3d98 100644
--- a/test/pleroma/config/deprecation_warnings_test.exs
+++ b/test/pleroma/config/deprecation_warnings_test.exs
@@ -15,38 +15,37 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
test "gives warning when still used" do
clear_config(
[Pleroma.Upload, :filters],
- [Pleroma.Upload.Filter.Exiftool]
+ [Pleroma.Upload.Filter.Exiftool, Pleroma.Upload.Filter.Exiftool.ReadDescription]
)
- assert capture_log(fn -> DeprecationWarnings.check_exiftool_filter() end) =~
- """
- !!!DEPRECATION WARNING!!!
- Your config is using Exiftool as a filter instead of Exiftool.StripLocation. This should work for now, but you are advised to change to the new configuration to prevent possible issues later:
+ log = capture_log(fn -> DeprecationWarnings.check_exiftool_filter() end)
- ```
- config :pleroma, Pleroma.Upload,
- filters: [Pleroma.Upload.Filter.Exiftool]
- ```
+ assert log =~ "!!!DEPRECATION WARNING!!!"
- Is now
+ assert log =~
+ "* `Pleroma.Upload.Filter.Exiftool` is now `Pleroma.Upload.Filter.Exif.StripLocation`"
+ assert log =~
+ "* `Pleroma.Upload.Filter.Exiftool.ReadDescription` is now `Pleroma.Upload.Filter.Exif.ReadDescription`"
- ```
- config :pleroma, Pleroma.Upload,
- filters: [Pleroma.Upload.Filter.Exiftool.StripLocation]
- ```
- """
+ refute log =~ "Exiftool.StripLocation`"
end
- test "changes setting to exiftool strip location" do
+ test "changes setting to the Exif filters" do
clear_config(
[Pleroma.Upload, :filters],
- [Pleroma.Upload.Filter.Exiftool, Pleroma.Upload.Filter.Exiftool.ReadDescription]
+ [
+ Pleroma.Upload.Filter.Dedupe,
+ Pleroma.Upload.Filter.Exiftool,
+ Pleroma.Upload.Filter.Exiftool.StripLocation,
+ Pleroma.Upload.Filter.Exiftool.ReadDescription
+ ]
)
expected_config = [
- Pleroma.Upload.Filter.Exiftool.StripLocation,
- Pleroma.Upload.Filter.Exiftool.ReadDescription
+ Pleroma.Upload.Filter.Dedupe,
+ Pleroma.Upload.Filter.Exif.StripLocation,
+ Pleroma.Upload.Filter.Exif.ReadDescription
]
capture_log(fn -> DeprecationWarnings.warn() end)
@@ -58,8 +57,8 @@ defmodule Pleroma.Config.DeprecationWarningsTest do
clear_config(
[Pleroma.Upload, :filters],
[
- Pleroma.Upload.Filter.Exiftool.StripLocation,
- Pleroma.Upload.Filter.Exiftool.ReadDescription
+ Pleroma.Upload.Filter.Exif.StripLocation,
+ Pleroma.Upload.Filter.Exif.ReadDescription
]
)
diff --git a/test/pleroma/upload/filter/exiftool/strip_location_test.exs b/test/pleroma/upload/filter/exiftool/strip_location_test.exs
deleted file mode 100644
index 485060215..000000000
--- a/test/pleroma/upload/filter/exiftool/strip_location_test.exs
+++ /dev/null
@@ -1,51 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Upload.Filter.Exiftool.StripLocationTest do
- use Pleroma.DataCase, async: true
- alias Pleroma.Upload.Filter
-
- test "apply exiftool filter" do
- assert Pleroma.Utils.command_available?("exiftool")
-
- ~w{jpg png}
- |> Enum.map(fn type ->
- File.cp!(
- "test/fixtures/DSCN0010.#{type}",
- "test/fixtures/DSCN0010_tmp.#{type}"
- )
-
- upload = %Pleroma.Upload{
- name: "image_with_GPS_data.#{type}",
- content_type: "image/jpeg",
- path: Path.absname("test/fixtures/DSCN0010.#{type}"),
- tempfile: Path.absname("test/fixtures/DSCN0010_tmp.#{type}")
- }
-
- assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :filtered}
-
- {exif_original, 0} = System.cmd("exiftool", ["-m", "test/fixtures/DSCN0010.#{type}"])
- {exif_filtered, 0} = System.cmd("exiftool", ["-m", "test/fixtures/DSCN0010_tmp.#{type}"])
-
- assert String.match?(exif_original, ~r/GPS/)
- refute String.match?(exif_filtered, ~r/GPS/)
- end)
- end
-
- test "verify webp, heic, svg files are skipped" do
- uploads =
- ~w{webp heic svg svg+xml}
- |> Enum.map(fn type ->
- %Pleroma.Upload{
- name: "sample.#{type}",
- content_type: "image/#{type}"
- }
- end)
-
- uploads
- |> Enum.each(fn upload ->
- assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :noop}
- end)
- end
-end
diff --git a/test/pleroma/upload/filter/exiftool_test.exs b/test/pleroma/upload/filter/exiftool_test.exs
new file mode 100644
index 000000000..c3ee3c59c
--- /dev/null
+++ b/test/pleroma/upload/filter/exiftool_test.exs
@@ -0,0 +1,31 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2026 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Upload.Filter.ExiftoolTest do
+ # Instances may still configure the deprecated Exiftool filter names.
+ # They must keep working, including for formats exiftool used to skip.
+ use Pleroma.DataCase, async: true
+
+ import Pleroma.Tests.ExifHelpers
+
+ for filter <- [Pleroma.Upload.Filter.Exiftool, Pleroma.Upload.Filter.Exiftool.StripLocation] do
+ test "#{inspect(filter)} strips GPS data from HEIC uploads" do
+ upload = upload_copy("strip_location_gps.heic", "image/heic")
+ assert gps_tags(upload.tempfile) =~ "GPS Latitude"
+
+ assert Pleroma.Upload.Filter.filter([unquote(filter)], upload) == {:ok, upload}
+ assert gps_tags(upload.tempfile) == ""
+ end
+ end
+
+ test "Exiftool.ReadDescription reads the description" do
+ upload = upload_copy("strip_location_gps.heic", "image/heic", description: nil)
+
+ assert {:ok, %{description: "a heic with a location"}} =
+ Pleroma.Upload.Filter.filter(
+ [Pleroma.Upload.Filter.Exiftool.ReadDescription],
+ upload
+ )
+ end
+end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Nov 1, 11:49 PM (13 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1803435
Default Alt Text
(14 KB)

Event Timeline