Skip to content

Commit

Permalink
serialize the access to mutable shared state in System.IO.Packaging (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
adamsitnik committed Jul 27, 2021
1 parent 95f4fd0 commit 72393ff
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime" />
<Reference Include="System.Xml.ReaderWriter" />
<Reference Include="System.Threading" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,63 +12,63 @@ namespace System.IO.Packaging
internal static class PackageXmlStringTable
{
// Fields
private static readonly NameTable s_nameTable = new NameTable();
private static readonly ThreadSafeNameTable s_nameTable = new ThreadSafeNameTable();
private static readonly XmlStringTableStruct[] s_xmlstringtable = new XmlStringTableStruct[0x1b];

// Methods
static PackageXmlStringTable()
{
object nameString = s_nameTable.Add("http://www.w3.org/2001/XMLSchema-instance");
object nameString = s_nameTable.AddNoLock("http://www.w3.org/2001/XMLSchema-instance");
s_xmlstringtable[1] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("xsi");
nameString = s_nameTable.AddNoLock("xsi");
s_xmlstringtable[2] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("xmlns");
nameString = s_nameTable.AddNoLock("xmlns");
s_xmlstringtable[3] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
nameString = s_nameTable.AddNoLock("http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
s_xmlstringtable[4] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("http://purl.org/dc/elements/1.1/");
nameString = s_nameTable.AddNoLock("http://purl.org/dc/elements/1.1/");
s_xmlstringtable[5] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("http://purl.org/dc/terms/");
nameString = s_nameTable.AddNoLock("http://purl.org/dc/terms/");
s_xmlstringtable[6] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("dc");
nameString = s_nameTable.AddNoLock("dc");
s_xmlstringtable[7] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("dcterms");
nameString = s_nameTable.AddNoLock("dcterms");
s_xmlstringtable[8] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, null);
nameString = s_nameTable.Add("coreProperties");
nameString = s_nameTable.AddNoLock("coreProperties");
s_xmlstringtable[9] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "NotSpecified");
nameString = s_nameTable.Add("type");
nameString = s_nameTable.AddNoLock("type");
s_xmlstringtable[10] = new XmlStringTableStruct(nameString, PackageXmlEnum.NotDefined, "NotSpecified");
nameString = s_nameTable.Add("creator");
nameString = s_nameTable.AddNoLock("creator");
s_xmlstringtable[11] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("identifier");
nameString = s_nameTable.AddNoLock("identifier");
s_xmlstringtable[12] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("title");
nameString = s_nameTable.AddNoLock("title");
s_xmlstringtable[13] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("subject");
nameString = s_nameTable.AddNoLock("subject");
s_xmlstringtable[14] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("description");
nameString = s_nameTable.AddNoLock("description");
s_xmlstringtable[15] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("language");
nameString = s_nameTable.AddNoLock("language");
s_xmlstringtable[0x10] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("created");
nameString = s_nameTable.AddNoLock("created");
s_xmlstringtable[0x11] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCoreTermsNamespace, "DateTime");
nameString = s_nameTable.Add("modified");
nameString = s_nameTable.AddNoLock("modified");
s_xmlstringtable[0x12] = new XmlStringTableStruct(nameString, PackageXmlEnum.DublinCoreTermsNamespace, "DateTime");
nameString = s_nameTable.Add("contentType");
nameString = s_nameTable.AddNoLock("contentType");
s_xmlstringtable[0x13] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("keywords");
nameString = s_nameTable.AddNoLock("keywords");
s_xmlstringtable[20] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("category");
nameString = s_nameTable.AddNoLock("category");
s_xmlstringtable[0x15] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("version");
nameString = s_nameTable.AddNoLock("version");
s_xmlstringtable[0x16] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("lastModifiedBy");
nameString = s_nameTable.AddNoLock("lastModifiedBy");
s_xmlstringtable[0x17] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("contentStatus");
nameString = s_nameTable.AddNoLock("contentStatus");
s_xmlstringtable[0x18] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("revision");
nameString = s_nameTable.AddNoLock("revision");
s_xmlstringtable[0x19] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "String");
nameString = s_nameTable.Add("lastPrinted");
nameString = s_nameTable.AddNoLock("lastPrinted");
s_xmlstringtable[0x1a] = new XmlStringTableStruct(nameString, PackageXmlEnum.PackageCorePropertiesNamespace, "DateTime");
}

Expand Down Expand Up @@ -161,5 +161,43 @@ internal string? ValueType
}
}
}

private sealed class ThreadSafeNameTable : NameTable
{
public override string Add(char[] array, int offset, int length)
{
lock (this)
{
return base.Add(array, offset, length);
}
}

public override string Add(string array)
{
lock (this)
{
return base.Add(array);
}
}

// can be used only from static ctor (which is always executed by a single thread)
internal string AddNoLock(string array) => base.Add(array);

public override string? Get(char[] array, int offset, int length)
{
lock (this)
{
return base.Get(array, offset, length);
}
}

public override string? Get(string array)
{
lock (this)
{
return base.Get(array);
}
}
}
}
}

0 comments on commit 72393ff

Please sign in to comment.