[MM-43393]: replace .Decoder() method with .Token() (#19988)
Automatic Merge
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
4e7cfc2095
Коммит
bb308b1a87
@@ -5,9 +5,9 @@ package imaging
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -20,39 +20,67 @@ type SVGInfo struct {
|
||||
|
||||
// ParseSVG returns information for the given SVG input data.
|
||||
func ParseSVG(svgReader io.Reader) (SVGInfo, error) {
|
||||
var parsedSVG struct {
|
||||
Width string `xml:"width,attr,omitempty"`
|
||||
Height string `xml:"height,attr,omitempty"`
|
||||
ViewBox string `xml:"viewBox,attr,omitempty"`
|
||||
}
|
||||
svgInfo := SVGInfo{
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
}
|
||||
viewBoxPattern := regexp.MustCompile("^([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)$")
|
||||
dimensionPattern := regexp.MustCompile("(?i)^([0-9]+)(?:px)?$")
|
||||
|
||||
// decode provided SVG
|
||||
if err := xml.NewDecoder(svgReader).Decode(&parsedSVG); err != nil {
|
||||
return svgInfo, err
|
||||
}
|
||||
decoder := xml.NewDecoder(svgReader)
|
||||
|
||||
// prefer viewbox for SVG dimensions over width/height
|
||||
if viewBoxMatches := viewBoxPattern.FindStringSubmatch(parsedSVG.ViewBox); len(viewBoxMatches) == 5 {
|
||||
svgInfo.Width, _ = strconv.Atoi(viewBoxMatches[3])
|
||||
svgInfo.Height, _ = strconv.Atoi(viewBoxMatches[4])
|
||||
} else if parsedSVG.Width != "" && parsedSVG.Height != "" {
|
||||
widthMatches := dimensionPattern.FindStringSubmatch(parsedSVG.Width)
|
||||
heightMatches := dimensionPattern.FindStringSubmatch(parsedSVG.Height)
|
||||
if len(widthMatches) == 2 && len(heightMatches) == 2 {
|
||||
svgInfo.Width, _ = strconv.Atoi(widthMatches[1])
|
||||
svgInfo.Height, _ = strconv.Atoi(heightMatches[1])
|
||||
for {
|
||||
token, err := decoder.Token()
|
||||
if err != nil {
|
||||
return svgInfo, err
|
||||
}
|
||||
switch t := token.(type) {
|
||||
case xml.StartElement:
|
||||
for _, attr := range t.Attr {
|
||||
if attr.Name.Local == "viewBox" {
|
||||
values := strings.Fields(attr.Value)
|
||||
if len(values) == 4 {
|
||||
width := 0
|
||||
_, widthErr := fmt.Sscan(values[2], &width)
|
||||
|
||||
height := 0
|
||||
_, heightErr := fmt.Sscan(values[3], &height)
|
||||
|
||||
if widthErr != nil || heightErr != nil {
|
||||
return svgInfo, err
|
||||
}
|
||||
|
||||
svgInfo.Width = width
|
||||
svgInfo.Height = height
|
||||
|
||||
return svgInfo, nil
|
||||
}
|
||||
}
|
||||
if attr.Name.Local == "width" {
|
||||
width := 0
|
||||
_, err := fmt.Sscan(attr.Value, &width)
|
||||
|
||||
if err != nil {
|
||||
return svgInfo, err
|
||||
}
|
||||
|
||||
svgInfo.Width = width
|
||||
}
|
||||
if attr.Name.Local == "height" {
|
||||
height := 0
|
||||
_, err := fmt.Sscan(attr.Value, &height)
|
||||
|
||||
if err != nil {
|
||||
return svgInfo, err
|
||||
}
|
||||
|
||||
svgInfo.Height = height
|
||||
}
|
||||
}
|
||||
|
||||
if svgInfo.Width == 0 || svgInfo.Height == 0 {
|
||||
return svgInfo, errors.New("unable to extract SVG dimensions")
|
||||
}
|
||||
|
||||
return svgInfo, nil
|
||||
}
|
||||
}
|
||||
|
||||
// if width and/or height are still zero, create new error
|
||||
if svgInfo.Width == 0 || svgInfo.Height == 0 {
|
||||
return svgInfo, errors.New("unable to extract SVG dimensions")
|
||||
}
|
||||
return svgInfo, nil
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
//nolint:unparam
|
||||
@@ -74,3 +76,11 @@ func TestParseInvalidSVGData(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseProcInstOnlySVGData(t *testing.T) {
|
||||
svg := strings.NewReader("<?xml version='1.0' encoding='utf-8'?>")
|
||||
svgInfo, err := ParseSVG(svg)
|
||||
require.Error(t, err)
|
||||
require.Equal(t, 0, svgInfo.Width)
|
||||
require.Equal(t, 0, svgInfo.Height)
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user