[Bf-blender-cvs] [96f565b380a] master: Fix T54477: Broken utf8 strings in old .blend files

Bastien Montagne noreply at git.blender.org
Tue Apr 3 16:03:36 CEST 2018


Commit: 96f565b380a8552e91151b9879746a1992283a35
Author: Bastien Montagne
Date:   Tue Apr 3 15:50:49 2018 +0200
Branches: master
https://developer.blender.org/rB96f565b380a8552e91151b9879746a1992283a35

Fix T54477: Broken utf8 strings in old .blend files

Back in the days (2.4x and before), it was rather easy to get some
invalid utf-8 strings in Blender. This is totally breaking modern code,
so this commit adds a simple 'check & fix strings' operator, available
from the main File menu.

===================================================================

M	release/scripts/startup/bl_operators/file.py
M	release/scripts/startup/bl_ui/space_info.py

===================================================================

diff --git a/release/scripts/startup/bl_operators/file.py b/release/scripts/startup/bl_operators/file.py
index 1b51906a032..4ab8d59f263 100644
--- a/release/scripts/startup/bl_operators/file.py
+++ b/release/scripts/startup/bl_operators/file.py
@@ -249,7 +249,61 @@ class WM_OT_previews_batch_clear(Operator):
         return {'FINISHED'}
 
 
+class WM_OT_blend_strings_utf8_validate(Operator):
+    """Check and fix all strings in current .blend file to be valid UTF-8 Unicode (needed for some old, 2.4x area files)"""
+    bl_idname = "wm.blend_strings_utf8_validate"
+    bl_label = "Validate .blend strings"
+    bl_options = {'REGISTER'}
+
+    def validate_strings(self, item, done_items):
+        if item is None:
+            return False
+
+        if item in done_items:
+            return False
+        done_items.add(item)
+
+        if getattr(item, 'library', None) is not None:
+            return False  # No point in checking library data, we cannot fix it anyway...
+
+        changed = False
+        for prop in item.bl_rna.properties:
+            if prop.identifier in {'bl_rna', 'rna_type'}:
+                continue  # Or we'd recurse 'till Hell freezes.
+            if prop.is_readonly:
+                continue
+            if prop.type == 'STRING':
+                val_bytes = item.path_resolve(prop.identifier, False).as_bytes()
+                val_utf8 = val_bytes.decode('utf-8', 'replace')
+                val_bytes_valid = val_utf8.encode('utf-8')
+                if val_bytes_valid != val_bytes:
+                    print("found bad utf8 encoded string %r, fixing to %r (%r)..."
+                          "" % (val_bytes, val_bytes_valid, val_utf8))
+                    setattr(item, prop.identifier, val_utf8)
+                    changed = True
+            elif prop.type == 'POINTER':
+                it = getattr(item, prop.identifier)
+                changed |= self.validate_strings(it, done_items)
+            elif prop.type == 'COLLECTION':
+                for it in getattr(item, prop.identifier):
+                    changed |= self.validate_strings(it, done_items)
+        return changed
+
+    def execute(self, context):
+        changed = False
+        done_items = set()
+        for prop in bpy.data.bl_rna.properties:
+            if prop.type == 'COLLECTION':
+                for it in getattr(bpy.data, prop.identifier):
+                    changed |= self.validate_strings(it, done_items)
+        if changed:
+            self.report({'WARNING'},
+                        "Some strings were fixed, don't forget to save the .blend file to keep those changes")
+        return {'FINISHED'}
+
+
 classes = (
     WM_OT_previews_batch_clear,
     WM_OT_previews_batch_generate,
+    WM_OT_blend_strings_utf8_validate,
 )
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index a7b518dfd2e..180e48af386 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -154,6 +154,7 @@ class INFO_MT_file(Menu):
         layout.separator()
 
         layout.menu("INFO_MT_file_external_data", icon='EXTERNAL_DATA')
+        layout.operator("wm.blend_strings_utf8_validate", icon='FILE_BLEND')
 
         layout.separator()



More information about the Bf-blender-cvs mailing list