mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 08:46:55 +08:00
1 parent
f322daa616
commit
4fee3dfd8e
3 files changed
+81
-21
No files matched your search
@@ -963,7 +963,7 @@ func pruneUnreferencedFiles(ctx context.Context, reader *Reader, candidates ...s
|
||||
if root == "" {
|
||||
root = node.Name.Local
|
||||
}
|
||||
if classifyOFDNamespace(node.Name.Space) == ofdXMLUnknown || slices.Contains([]string{"CustomTags", "Extensions", "ExtendData", "Data"}, node.Name.Local) {
|
||||
if classifyOFDNamespace(node.Name.Space) == ofdXMLUnknown || root == "CustomTags" || slices.Contains([]string{"Extensions", "ExtendData", "Data"}, node.Name.Local) {
|
||||
uncertain = true
|
||||
return fmt.Errorf("unknown file dependencies in %s", name)
|
||||
}
|
||||
@@ -990,7 +990,19 @@ func pruneUnreferencedFiles(ctx context.Context, reader *Reader, candidates ...s
|
||||
versions[name] = append(versions[name], versionEditLink{node: node, target: target})
|
||||
}
|
||||
}
|
||||
if err := reader.scanDocumentFileReferences(ctx, name, true, add, record, inspect); err != nil {
|
||||
err := reader.scanDocumentFileReferences(ctx, name, true, add, record, inspect)
|
||||
if uncertain && (root == "CustomTags" || root == "RichText") {
|
||||
data, readErr := reader.readFileViewContext(ctx, name)
|
||||
if readErr != nil {
|
||||
return readErr
|
||||
}
|
||||
refs := &editorResourceRefs{ids: make(map[string]bool), files: make(map[string]bool), fonts: make(map[string]*editorFontUsage)}
|
||||
if _, safe := refs.scanContext(ctx, bytes.NewReader(data), name); safe {
|
||||
uncertain = false
|
||||
err = reader.scanDocumentFileReferences(ctx, name, true, add, record, nil)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
var syntax *xml.SyntaxError
|
||||
if uncertain || errors.As(err, &syntax) {
|
||||
return ctx.Err()
|
||||
|
||||
@@ -53,6 +53,7 @@ type editorReferenceScan struct {
|
||||
stack []string
|
||||
fonts []*editorFontUsage
|
||||
text strings.Builder
|
||||
richText strings.Builder
|
||||
resource bool
|
||||
capture bool
|
||||
safe bool
|
||||
@@ -140,14 +141,39 @@ func (s *editorReferenceScan) accept(token xml.Token) bool {
|
||||
}
|
||||
switch token := token.(type) {
|
||||
case xml.StartElement:
|
||||
if classifyOFDNamespace(token.Name.Space) == ofdXMLUnknown {
|
||||
rich := token.Name.Space == richTextNamespace
|
||||
known := classifyOFDNamespace(token.Name.Space) != ofdXMLUnknown
|
||||
if rich {
|
||||
known = len(s.stack) == 0 && token.Name.Local == "RichText" || len(s.stack) == 1 && s.stack[0] == "RichText" && token.Name.Local == "ObjectRef"
|
||||
} else if len(s.stack) > 0 && s.stack[0] == "RichText" {
|
||||
known = false
|
||||
}
|
||||
if len(s.stack) > 0 && s.stack[0] == "CustomTags" {
|
||||
known = known && (len(s.stack) == 1 && token.Name.Local == "CustomTag" || len(s.stack) == 2 && s.stack[1] == "CustomTag" && (token.Name.Local == "FileLoc" || token.Name.Local == "SchemaLoc"))
|
||||
}
|
||||
if !known {
|
||||
s.safe = false
|
||||
return false
|
||||
}
|
||||
if token.Name.Local == "CustomTags" || token.Name.Local == "Extensions" || token.Name.Local == "ExtendData" || token.Name.Local == "Data" {
|
||||
if token.Name.Local == "Extensions" || token.Name.Local == "ExtendData" || token.Name.Local == "Data" {
|
||||
s.safe = false
|
||||
return false
|
||||
}
|
||||
if token.Name.Local == "CustomTag" {
|
||||
var kind, namespace string
|
||||
for _, attr := range token.Attr {
|
||||
if attr.Name.Space == "" && attr.Name.Local == "TypeID" {
|
||||
kind = attr.Value
|
||||
}
|
||||
if attr.Name.Space == "" && attr.Name.Local == "NameSpace" {
|
||||
namespace = attr.Value
|
||||
}
|
||||
}
|
||||
if kind != richTextTagType || namespace != richTextNamespace {
|
||||
s.safe = false
|
||||
return false
|
||||
}
|
||||
}
|
||||
if len(s.stack) == 0 {
|
||||
if s.seen {
|
||||
s.safe = false
|
||||
@@ -184,7 +210,8 @@ func (s *editorReferenceScan) accept(token xml.Token) bool {
|
||||
if attr.Name.Space == "xmlns" || attr.Name.Local == "xmlns" || attr.Name.Local == "xmlns:ofd" || attr.Name.Space == XMLNamespace {
|
||||
continue
|
||||
}
|
||||
if attr.Name.Space != "" {
|
||||
custom := len(s.stack) == 0 && token.Name.Local == "CustomTags" || len(s.stack) > 0 && s.stack[0] == "CustomTags"
|
||||
if attr.Name.Space != "" || rich && (token.Name.Local != "ObjectRef" || attr.Name.Local != "PageRef") || custom && (token.Name.Local != "CustomTag" || attr.Name.Local != "TypeID" && attr.Name.Local != "NameSpace") {
|
||||
s.safe = false
|
||||
return false
|
||||
}
|
||||
@@ -225,6 +252,9 @@ func (s *editorReferenceScan) accept(token xml.Token) bool {
|
||||
s.capture = true
|
||||
}
|
||||
case xml.CharData:
|
||||
if len(s.stack) == 1 && s.stack[0] == "RichText" {
|
||||
s.richText.Write(token)
|
||||
}
|
||||
if len(s.stack) == 0 && len(bytes.Trim(token, " \t\r\n")) != 0 {
|
||||
s.safe = false
|
||||
return false
|
||||
@@ -233,6 +263,14 @@ func (s *editorReferenceScan) accept(token xml.Token) bool {
|
||||
s.text.Write(token)
|
||||
}
|
||||
case xml.EndElement:
|
||||
if len(s.stack) == 3 && s.stack[0] == "CustomTags" && token.Name.Local == "SchemaLoc" && strings.TrimSpace(s.text.String()) != "" {
|
||||
s.safe = false
|
||||
return false
|
||||
}
|
||||
if len(s.stack) == 1 && s.stack[0] == "RichText" && !richTextMetadataFontSafe(s.richText.String()) {
|
||||
s.safe = false
|
||||
return false
|
||||
}
|
||||
if len(s.stack) == 0 || s.stack[len(s.stack)-1] != token.Name.Local {
|
||||
s.safe = false
|
||||
return false
|
||||
|
||||
+26
-16
@@ -909,22 +909,7 @@ func richTextTagsFontSafe(ctx context.Context, reader *Reader, index int) (bool,
|
||||
if root.Name != "RichText" || root.Namespace != richTextNamespace || len(root.Attributes) != 0 {
|
||||
return false, nil
|
||||
}
|
||||
var meta richTextMetadata
|
||||
decoder := json.NewDecoder(bytes.NewBufferString(root.Text))
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(&meta); err != nil {
|
||||
return false, nil
|
||||
}
|
||||
if decoder.Decode(new(any)) != io.EOF || meta.Version != 1 {
|
||||
return false, nil
|
||||
}
|
||||
for i := range meta.Value.Runs {
|
||||
if meta.Value.Runs[i].Format.Font != "" {
|
||||
return false, nil
|
||||
}
|
||||
meta.Value.Runs[i].Format.Font = "1"
|
||||
}
|
||||
if err := meta.Value.Validate(); err != nil {
|
||||
if !richTextMetadataFontSafe(root.Text) {
|
||||
return false, nil
|
||||
}
|
||||
for _, child := range root.Children {
|
||||
@@ -935,3 +920,28 @@ func richTextTagsFontSafe(ctx context.Context, reader *Reader, index int) (bool,
|
||||
}
|
||||
return true, ctx.Err()
|
||||
}
|
||||
|
||||
// richTextMetadataFontSafe 核对本库富文本元数据不包含字体资源编号或未知字段
|
||||
// 入参: value 元数据JSON
|
||||
// 返回: bool 是否可由标准图元完整统计字体引用
|
||||
func richTextMetadataFontSafe(value string) bool {
|
||||
var meta richTextMetadata
|
||||
decoder := json.NewDecoder(bytes.NewBufferString(value))
|
||||
decoder.DisallowUnknownFields()
|
||||
if err := decoder.Decode(&meta); err != nil {
|
||||
return false
|
||||
}
|
||||
if decoder.Decode(new(any)) != io.EOF || meta.Version != 1 {
|
||||
return false
|
||||
}
|
||||
for i := range meta.Value.Runs {
|
||||
if meta.Value.Runs[i].Format.Font != "" {
|
||||
return false
|
||||
}
|
||||
meta.Value.Runs[i].Format.Font = "1"
|
||||
}
|
||||
if err := meta.Value.Validate(); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
Reference in new issue
Block a user