LettError / designSpaceRoboFontExtension

A RoboFont extension for creating and editing designspace documents.
MIT License
27 stars 6 forks source link

addSourceFromFont can generate duplicate source names. #93

Open typesupply opened 2 weeks ago

typesupply commented 2 weeks ago

I just ran into a situation that was very hard to debug. DSE was opening a designspace file seemingly fine, but Prepolator was choking and my previews looked weird. I figured out that it was an issue in the designspace file created by DSE. Here's how I made the "broken" file:

  1. I had 4 sources in the designspace, all with the automatic names: source.1, source.2, source.3, source.4.
  2. I deleted source.1 and source.2 in DSE.
  3. I dragged new sources into DSE.
  4. I gave the new sources locations that the previous sources had.
  5. I saved the designspace.

The problem was that the newly added sources were also named source.3 and source.4. The line of code that generates the source name is here.

name=f"source.{len(self.operator.sources) + 1}",

Because the operator now had two sources, it assumed that it could start numbering with three. It would be nice if there was a more robust test. Here's a quick implementation:

import uuid

existingNames = set(self.operator.sources.keys())
name = None
# try everything from source.1 to source.50000
# until an unused name is found.
for i in range(1, 5001):
    n = f"source.{i}"
    if n not in existingNames:
        name = n
        break
# if no name was available, wow someone has 50,000 sources!
# go to uuid to make a unique string.
if name is None:
    name = f"source.{uuid.uuid4()}"
# final sanity check.
if name in existingNames:
    raise DSEError(
        "A source name could not be generated for this font. "
        "Please add the source into the .designspace manually "
        "in a code editor."
    )
typemytype commented 2 weeks ago

I came across this issue before, thanks for debugging...