mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 10:56:10 +01:00 
			
		
		
		
	Refactor backend SVG package and add tests (#26335)
Introduce a well-tested `svg.Normalize` function. Make `RenderHTML` faster and more stable.
This commit is contained in:
		
							
								
								
									
										59
									
								
								modules/svg/processor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								modules/svg/processor.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,59 @@ | ||||
| // Copyright 2023 The Gitea Authors. All rights reserved. | ||||
| // SPDX-License-Identifier: MIT | ||||
|  | ||||
| package svg | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"regexp" | ||||
| 	"sync" | ||||
| ) | ||||
|  | ||||
| type normalizeVarsStruct struct { | ||||
| 	reXMLDoc, | ||||
| 	reComment, | ||||
| 	reAttrXMLNs, | ||||
| 	reAttrSize, | ||||
| 	reAttrClassPrefix *regexp.Regexp | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	normalizeVars     *normalizeVarsStruct | ||||
| 	normalizeVarsOnce sync.Once | ||||
| ) | ||||
|  | ||||
| // Normalize normalizes the SVG content: set default width/height, remove unnecessary tags/attributes | ||||
| // It's designed to work with valid SVG content. For invalid SVG content, the returned content is not guaranteed. | ||||
| func Normalize(data []byte, size int) []byte { | ||||
| 	normalizeVarsOnce.Do(func() { | ||||
| 		normalizeVars = &normalizeVarsStruct{ | ||||
| 			reXMLDoc:  regexp.MustCompile(`(?s)<\?xml.*?>`), | ||||
| 			reComment: regexp.MustCompile(`(?s)<!--.*?-->`), | ||||
|  | ||||
| 			reAttrXMLNs:       regexp.MustCompile(`(?s)\s+xmlns\s*=\s*"[^"]*"`), | ||||
| 			reAttrSize:        regexp.MustCompile(`(?s)\s+(width|height)\s*=\s*"[^"]+"`), | ||||
| 			reAttrClassPrefix: regexp.MustCompile(`(?s)\s+class\s*=\s*"`), | ||||
| 		} | ||||
| 	}) | ||||
| 	data = normalizeVars.reXMLDoc.ReplaceAll(data, nil) | ||||
| 	data = normalizeVars.reComment.ReplaceAll(data, nil) | ||||
|  | ||||
| 	data = bytes.TrimSpace(data) | ||||
| 	svgTag, svgRemaining, ok := bytes.Cut(data, []byte(">")) | ||||
| 	if !ok || !bytes.HasPrefix(svgTag, []byte(`<svg`)) { | ||||
| 		return data | ||||
| 	} | ||||
| 	normalized := bytes.Clone(svgTag) | ||||
| 	normalized = normalizeVars.reAttrXMLNs.ReplaceAll(normalized, nil) | ||||
| 	normalized = normalizeVars.reAttrSize.ReplaceAll(normalized, nil) | ||||
| 	normalized = normalizeVars.reAttrClassPrefix.ReplaceAll(normalized, []byte(` class="`)) | ||||
| 	normalized = bytes.TrimSpace(normalized) | ||||
| 	normalized = fmt.Appendf(normalized, ` width="%d" height="%d"`, size, size) | ||||
| 	if !bytes.Contains(normalized, []byte(` class="`)) { | ||||
| 		normalized = append(normalized, ` class="svg"`...) | ||||
| 	} | ||||
| 	normalized = append(normalized, '>') | ||||
| 	normalized = append(normalized, svgRemaining...) | ||||
| 	return normalized | ||||
| } | ||||
		Reference in New Issue
	
	Block a user