[MM-43393]: replace .Decoder() method with .Token() (#19988)
Automatic Merge
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
4e7cfc2095
Коммит
bb308b1a87
@@ -5,9 +5,9 @@ package imaging
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"strings"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@@ -20,39 +20,67 @@ type SVGInfo struct {
|
|||||||
|
|
||||||
// ParseSVG returns information for the given SVG input data.
|
// ParseSVG returns information for the given SVG input data.
|
||||||
func ParseSVG(svgReader io.Reader) (SVGInfo, error) {
|
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{
|
svgInfo := SVGInfo{
|
||||||
Width: 0,
|
Width: 0,
|
||||||
Height: 0,
|
Height: 0,
|
||||||
}
|
}
|
||||||
viewBoxPattern := regexp.MustCompile("^([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)$")
|
|
||||||
dimensionPattern := regexp.MustCompile("(?i)^([0-9]+)(?:px)?$")
|
|
||||||
|
|
||||||
// decode provided SVG
|
decoder := xml.NewDecoder(svgReader)
|
||||||
if err := xml.NewDecoder(svgReader).Decode(&parsedSVG); err != nil {
|
|
||||||
return svgInfo, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// prefer viewbox for SVG dimensions over width/height
|
for {
|
||||||
if viewBoxMatches := viewBoxPattern.FindStringSubmatch(parsedSVG.ViewBox); len(viewBoxMatches) == 5 {
|
token, err := decoder.Token()
|
||||||
svgInfo.Width, _ = strconv.Atoi(viewBoxMatches[3])
|
if err != nil {
|
||||||
svgInfo.Height, _ = strconv.Atoi(viewBoxMatches[4])
|
return svgInfo, err
|
||||||
} else if parsedSVG.Width != "" && parsedSVG.Height != "" {
|
}
|
||||||
widthMatches := dimensionPattern.FindStringSubmatch(parsedSVG.Width)
|
switch t := token.(type) {
|
||||||
heightMatches := dimensionPattern.FindStringSubmatch(parsedSVG.Height)
|
case xml.StartElement:
|
||||||
if len(widthMatches) == 2 && len(heightMatches) == 2 {
|
for _, attr := range t.Attr {
|
||||||
svgInfo.Width, _ = strconv.Atoi(widthMatches[1])
|
if attr.Name.Local == "viewBox" {
|
||||||
svgInfo.Height, _ = strconv.Atoi(heightMatches[1])
|
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"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
//nolint:unparam
|
//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