mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-07-13 09:02:09 -04:00
build(deps): bump github.com/kovidgoyal/imaging from 1.8.21 to 1.8.22
Bumps [github.com/kovidgoyal/imaging](https://github.com/kovidgoyal/imaging) from 1.8.21 to 1.8.22. - [Release notes](https://github.com/kovidgoyal/imaging/releases) - [Commits](https://github.com/kovidgoyal/imaging/compare/v1.8.21...v1.8.22) --- updated-dependencies: - dependency-name: github.com/kovidgoyal/imaging dependency-version: 1.8.22 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
08bb6fe003
commit
2683b2db6f
4
go.mod
4
go.mod
@@ -49,7 +49,7 @@ require (
|
||||
github.com/jellydator/ttlcache/v3 v3.4.1
|
||||
github.com/jinzhu/now v1.1.5
|
||||
github.com/justinas/alice v1.2.0
|
||||
github.com/kovidgoyal/imaging v1.8.21
|
||||
github.com/kovidgoyal/imaging v1.8.22
|
||||
github.com/leonelquinteros/gotext v1.7.3-0.20260422134830-b012b4ccae69
|
||||
github.com/libregraph/idm v0.5.0
|
||||
github.com/libregraph/lico v0.67.0
|
||||
@@ -104,7 +104,7 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.44.0
|
||||
golang.org/x/crypto v0.53.0
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f
|
||||
golang.org/x/image v0.40.0
|
||||
golang.org/x/image v0.43.0
|
||||
golang.org/x/net v0.56.0
|
||||
golang.org/x/oauth2 v0.36.0
|
||||
golang.org/x/sync v0.21.0
|
||||
|
||||
8
go.sum
8
go.sum
@@ -734,8 +734,8 @@ github.com/kovidgoyal/go-parallel v1.1.1 h1:1OzpNjtrUkBPq3UaqrnvOoB2F9RttSt811ui
|
||||
github.com/kovidgoyal/go-parallel v1.1.1/go.mod h1:BJNIbe6+hxyFWv7n6oEDPj3PA5qSw5OCtf0hcVxWJiw=
|
||||
github.com/kovidgoyal/go-shm v1.0.0 h1:HJEel9D1F9YhULvClEHJLawoRSj/1u/EDV7MJbBPgQo=
|
||||
github.com/kovidgoyal/go-shm v1.0.0/go.mod h1:Yzb80Xf9L3kaoB2RGok9hHwMIt7Oif61kT6t3+VnZds=
|
||||
github.com/kovidgoyal/imaging v1.8.21 h1:95S2+dowTeKJJHNpf6lnScvIennTr2H0zQotu+ptNQw=
|
||||
github.com/kovidgoyal/imaging v1.8.21/go.mod h1:976F+zjiQeZ7sd87Pxlm0a64S/w9bImSIWg3sSk1rdQ=
|
||||
github.com/kovidgoyal/imaging v1.8.22 h1:CtpoRXQpS79xxJsKu8+LUJJE/0i4FLquJZy0QH+QNlM=
|
||||
github.com/kovidgoyal/imaging v1.8.22/go.mod h1:y8wo4JTv4D+skbtQf6fHg8nA1qtagvCcn8J2Nu5k2Jg=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@@ -1376,8 +1376,8 @@ golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJk
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.40.0 h1:Tw4GyDXMo+daZN1znreBRC3VayR1aLFUyUEOLUdW1a8=
|
||||
golang.org/x/image v0.40.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA=
|
||||
golang.org/x/image v0.43.0 h1:FLxcP4ec2350nTfOC8ysKtqYSIFbk/QGjw1ZHNP4tsY=
|
||||
golang.org/x/image v0.43.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
||||
2
vendor/github.com/kovidgoyal/imaging/publish.py
generated
vendored
2
vendor/github.com/kovidgoyal/imaging/publish.py
generated
vendored
@@ -5,7 +5,7 @@ import os
|
||||
import subprocess
|
||||
|
||||
|
||||
VERSION = "1.8.21"
|
||||
VERSION = "1.8.22"
|
||||
|
||||
|
||||
def run(*args: str):
|
||||
|
||||
15
vendor/github.com/kovidgoyal/imaging/webp/decode.go
generated
vendored
15
vendor/github.com/kovidgoyal/imaging/webp/decode.go
generated
vendored
@@ -92,6 +92,9 @@ func decode(r io.Reader, configOnly bool) (image.Image, image.Config, error) {
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
if seenVP8X && (fh.Width != int(widthMinusOne)+1 || fh.Height != int(heightMinusOne)+1) {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
if configOnly {
|
||||
return nil, image.Config{
|
||||
ColorModel: color.YCbCrModel,
|
||||
@@ -121,8 +124,16 @@ func decode(r io.Reader, configOnly bool) (image.Image, image.Config, error) {
|
||||
return nil, c, err
|
||||
}
|
||||
m, err := vp8l.Decode(chunkData)
|
||||
return m, image.Config{}, err
|
||||
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
if seenVP8X {
|
||||
bounds := m.Bounds()
|
||||
if bounds.Dx() != int(widthMinusOne)+1 || bounds.Dy() != int(heightMinusOne)+1 {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
}
|
||||
return m, image.Config{}, nil
|
||||
case fccVP8X:
|
||||
if seenVP8X {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
|
||||
277
vendor/github.com/kovidgoyal/imaging/webp/decode.go.orig
generated
vendored
277
vendor/github.com/kovidgoyal/imaging/webp/decode.go.orig
generated
vendored
@@ -1,277 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package webp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"image"
|
||||
"image/color"
|
||||
"io"
|
||||
|
||||
"golang.org/x/image/riff"
|
||||
"golang.org/x/image/vp8"
|
||||
"golang.org/x/image/vp8l"
|
||||
)
|
||||
|
||||
var errInvalidFormat = errors.New("webp: invalid format")
|
||||
|
||||
var (
|
||||
fccALPH = riff.FourCC{'A', 'L', 'P', 'H'}
|
||||
fccVP8 = riff.FourCC{'V', 'P', '8', ' '}
|
||||
fccVP8L = riff.FourCC{'V', 'P', '8', 'L'}
|
||||
fccVP8X = riff.FourCC{'V', 'P', '8', 'X'}
|
||||
fccWEBP = riff.FourCC{'W', 'E', 'B', 'P'}
|
||||
)
|
||||
|
||||
func decode(r io.Reader, configOnly bool) (image.Image, image.Config, error) {
|
||||
formType, riffReader, err := riff.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
if formType != fccWEBP {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
|
||||
var (
|
||||
alpha []byte
|
||||
alphaStride int
|
||||
wantAlpha bool
|
||||
seenVP8X bool
|
||||
widthMinusOne uint32
|
||||
heightMinusOne uint32
|
||||
buf [10]byte
|
||||
)
|
||||
for {
|
||||
chunkID, chunkLen, chunkData, err := riffReader.Next()
|
||||
if err == io.EOF {
|
||||
err = errInvalidFormat
|
||||
}
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
|
||||
switch chunkID {
|
||||
case fccALPH:
|
||||
if !wantAlpha {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
wantAlpha = false
|
||||
// Read the Pre-processing | Filter | Compression byte.
|
||||
if _, err := io.ReadFull(chunkData, buf[:1]); err != nil {
|
||||
if err == io.EOF {
|
||||
err = errInvalidFormat
|
||||
}
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
alpha, alphaStride, err = readAlpha(chunkData, widthMinusOne, heightMinusOne, buf[0]&0x03)
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
unfilterAlpha(alpha, alphaStride, (buf[0]>>2)&0x03)
|
||||
|
||||
case fccVP8:
|
||||
if wantAlpha || int32(chunkLen) < 0 {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
d := vp8.NewDecoder()
|
||||
d.Init(chunkData, int(chunkLen))
|
||||
fh, err := d.DecodeFrameHeader()
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
if configOnly {
|
||||
return nil, image.Config{
|
||||
ColorModel: color.YCbCrModel,
|
||||
Width: fh.Width,
|
||||
Height: fh.Height,
|
||||
}, nil
|
||||
}
|
||||
m, err := d.DecodeFrame()
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
if alpha != nil {
|
||||
return &image.NYCbCrA{
|
||||
YCbCr: *m,
|
||||
A: alpha,
|
||||
AStride: alphaStride,
|
||||
}, image.Config{}, nil
|
||||
}
|
||||
return m, image.Config{}, nil
|
||||
|
||||
case fccVP8L:
|
||||
if wantAlpha || alpha != nil {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
if configOnly {
|
||||
c, err := vp8l.DecodeConfig(chunkData)
|
||||
return nil, c, err
|
||||
}
|
||||
m, err := vp8l.Decode(chunkData)
|
||||
return m, image.Config{}, err
|
||||
|
||||
case fccVP8X:
|
||||
if seenVP8X {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
seenVP8X = true
|
||||
if chunkLen != 10 {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
if _, err := io.ReadFull(chunkData, buf[:10]); err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
const (
|
||||
animationBit = 1 << 1
|
||||
xmpMetadataBit = 1 << 2
|
||||
exifMetadataBit = 1 << 3
|
||||
alphaBit = 1 << 4
|
||||
iccProfileBit = 1 << 5
|
||||
)
|
||||
wantAlpha = (buf[0] & alphaBit) != 0
|
||||
widthMinusOne = uint32(buf[4]) | uint32(buf[5])<<8 | uint32(buf[6])<<16
|
||||
heightMinusOne = uint32(buf[7]) | uint32(buf[8])<<8 | uint32(buf[9])<<16
|
||||
if configOnly {
|
||||
if wantAlpha {
|
||||
return nil, image.Config{
|
||||
ColorModel: color.NYCbCrAModel,
|
||||
Width: int(widthMinusOne) + 1,
|
||||
Height: int(heightMinusOne) + 1,
|
||||
}, nil
|
||||
}
|
||||
return nil, image.Config{
|
||||
ColorModel: color.YCbCrModel,
|
||||
Width: int(widthMinusOne) + 1,
|
||||
Height: int(heightMinusOne) + 1,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readAlpha(chunkData io.Reader, widthMinusOne, heightMinusOne uint32, compression byte) (
|
||||
alpha []byte, alphaStride int, err error) {
|
||||
|
||||
switch compression {
|
||||
case 0:
|
||||
w := int(widthMinusOne) + 1
|
||||
h := int(heightMinusOne) + 1
|
||||
alpha = make([]byte, w*h)
|
||||
if _, err := io.ReadFull(chunkData, alpha); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return alpha, w, nil
|
||||
|
||||
case 1:
|
||||
// Read the VP8L-compressed alpha values. First, synthesize a 5-byte VP8L header:
|
||||
// a 1-byte magic number, a 14-bit widthMinusOne, a 14-bit heightMinusOne,
|
||||
// a 1-bit (ignored, zero) alphaIsUsed and a 3-bit (zero) version.
|
||||
// TODO(nigeltao): be more efficient than decoding an *image.NRGBA just to
|
||||
// extract the green values to a separately allocated []byte. Fixing this
|
||||
// will require changes to the vp8l package's API.
|
||||
if widthMinusOne > 0x3fff || heightMinusOne > 0x3fff {
|
||||
return nil, 0, errors.New("webp: invalid format")
|
||||
}
|
||||
alphaImage, err := vp8l.Decode(io.MultiReader(
|
||||
bytes.NewReader([]byte{
|
||||
0x2f, // VP8L magic number.
|
||||
uint8(widthMinusOne),
|
||||
uint8(widthMinusOne>>8) | uint8(heightMinusOne<<6),
|
||||
uint8(heightMinusOne >> 2),
|
||||
uint8(heightMinusOne >> 10),
|
||||
}),
|
||||
chunkData,
|
||||
))
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
// The green values of the inner NRGBA image are the alpha values of the
|
||||
// outer NYCbCrA image.
|
||||
pix := alphaImage.(*image.NRGBA).Pix
|
||||
alpha = make([]byte, len(pix)/4)
|
||||
for i := range alpha {
|
||||
alpha[i] = pix[4*i+1]
|
||||
}
|
||||
return alpha, int(widthMinusOne) + 1, nil
|
||||
}
|
||||
return nil, 0, errInvalidFormat
|
||||
}
|
||||
|
||||
func unfilterAlpha(alpha []byte, alphaStride int, filter byte) {
|
||||
if len(alpha) == 0 || alphaStride == 0 {
|
||||
return
|
||||
}
|
||||
switch filter {
|
||||
case 1: // Horizontal filter.
|
||||
for i := 1; i < alphaStride; i++ {
|
||||
alpha[i] += alpha[i-1]
|
||||
}
|
||||
for i := alphaStride; i < len(alpha); i += alphaStride {
|
||||
// The first column is equivalent to the vertical filter.
|
||||
alpha[i] += alpha[i-alphaStride]
|
||||
|
||||
for j := 1; j < alphaStride; j++ {
|
||||
alpha[i+j] += alpha[i+j-1]
|
||||
}
|
||||
}
|
||||
|
||||
case 2: // Vertical filter.
|
||||
// The first row is equivalent to the horizontal filter.
|
||||
for i := 1; i < alphaStride; i++ {
|
||||
alpha[i] += alpha[i-1]
|
||||
}
|
||||
|
||||
for i := alphaStride; i < len(alpha); i++ {
|
||||
alpha[i] += alpha[i-alphaStride]
|
||||
}
|
||||
|
||||
case 3: // Gradient filter.
|
||||
// The first row is equivalent to the horizontal filter.
|
||||
for i := 1; i < alphaStride; i++ {
|
||||
alpha[i] += alpha[i-1]
|
||||
}
|
||||
|
||||
for i := alphaStride; i < len(alpha); i += alphaStride {
|
||||
// The first column is equivalent to the vertical filter.
|
||||
alpha[i] += alpha[i-alphaStride]
|
||||
|
||||
// The interior is predicted on the three top/left pixels.
|
||||
for j := 1; j < alphaStride; j++ {
|
||||
c := int(alpha[i+j-alphaStride-1])
|
||||
b := int(alpha[i+j-alphaStride])
|
||||
a := int(alpha[i+j-1])
|
||||
x := a + b - c
|
||||
if x < 0 {
|
||||
x = 0
|
||||
} else if x > 255 {
|
||||
x = 255
|
||||
}
|
||||
alpha[i+j] += uint8(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decode reads a WEBP image from r and returns it as an image.Image.
|
||||
func Decode(r io.Reader) (image.Image, error) {
|
||||
m, _, err := decode(r, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// DecodeConfig returns the color model and dimensions of a WEBP image without
|
||||
// decoding the entire image.
|
||||
func DecodeConfig(r io.Reader) (image.Config, error) {
|
||||
_, c, err := decode(r, true)
|
||||
return c, err
|
||||
}
|
||||
|
||||
func init() {
|
||||
image.RegisterFormat("webp", "RIFF????WEBPVP8", Decode, DecodeConfig)
|
||||
}
|
||||
|
||||
23
vendor/golang.org/x/image/bmp/reader.go
generated
vendored
23
vendor/golang.org/x/image/bmp/reader.go
generated
vendored
@@ -12,12 +12,16 @@ import (
|
||||
"image"
|
||||
"image/color"
|
||||
"io"
|
||||
|
||||
"golang.org/x/image/internal/safemath"
|
||||
)
|
||||
|
||||
// ErrUnsupported means that the input BMP image uses a valid but unsupported
|
||||
// feature.
|
||||
var ErrUnsupported = errors.New("bmp: unsupported BMP image")
|
||||
|
||||
var errInvalidPaletteIndex = errors.New("bmp: invalid palette index")
|
||||
|
||||
func readUint16(b []byte) uint16 {
|
||||
return uint16(b[0]) | uint16(b[1])<<8
|
||||
}
|
||||
@@ -29,7 +33,8 @@ func readUint32(b []byte) uint32 {
|
||||
// decodePaletted reads a 1, 2, 4 or 8 bit-per-pixel BMP image from r.
|
||||
// If topDown is false, the image rows will be read bottom-up.
|
||||
func decodePaletted(r io.Reader, c image.Config, topDown bool, bpp int) (image.Image, error) {
|
||||
paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), c.ColorModel.(color.Palette))
|
||||
palette := c.ColorModel.(color.Palette)
|
||||
paletted := image.NewPaletted(image.Rect(0, 0, c.Width, c.Height), palette)
|
||||
if c.Width == 0 || c.Height == 0 {
|
||||
return paletted, nil
|
||||
}
|
||||
@@ -51,7 +56,11 @@ func decodePaletted(r io.Reader, c image.Config, topDown bool, bpp int) (image.I
|
||||
byteIndex, bitIndex, mask := 0, 8, byte((1<<bpp)-1)
|
||||
for pixIndex := 0; pixIndex < c.Width; pixIndex++ {
|
||||
bitIndex -= bpp
|
||||
p[pixIndex] = (b[byteIndex]) >> bitIndex & mask
|
||||
paletteIndex := (b[byteIndex]) >> bitIndex & mask
|
||||
if int(paletteIndex) >= len(palette) {
|
||||
return nil, errInvalidPaletteIndex
|
||||
}
|
||||
p[pixIndex] = paletteIndex
|
||||
if bitIndex == 0 {
|
||||
byteIndex++
|
||||
bitIndex = 8
|
||||
@@ -183,6 +192,16 @@ func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown b
|
||||
if width < 0 || height < 0 {
|
||||
return image.Config{}, 0, false, false, ErrUnsupported
|
||||
}
|
||||
if (width == 0) != (height == 0) {
|
||||
// We'll take 0x0, but Nx0 or 0xN is suspicious.
|
||||
return image.Config{}, 0, false, false, ErrUnsupported
|
||||
}
|
||||
// Check that the image fits in memory.
|
||||
// This conservatively assumes 4 bytes per pixel,
|
||||
// rather than using the actual pixel size.
|
||||
if _, ok := safemath.Mul3(width, height, 4); !ok {
|
||||
return image.Config{}, 0, false, false, ErrUnsupported
|
||||
}
|
||||
// We only support 1 plane and 8, 24 or 32 bits per pixel and no
|
||||
// compression.
|
||||
planes, bpp, compression := readUint16(b[26:28]), readUint16(b[28:30]), readUint32(b[30:34])
|
||||
|
||||
6
vendor/golang.org/x/image/font/sfnt/gpos.go
generated
vendored
6
vendor/golang.org/x/image/font/sfnt/gpos.go
generated
vendored
@@ -348,6 +348,9 @@ func makeCachedPairPosGlyph(cov indexLookupFunc, num int, buf []byte) kernFunc {
|
||||
|
||||
count := int(u16(glyphs[offset:]))
|
||||
for i := 0; i < count; i++ {
|
||||
if offset+2+i*4+4 > len(glyphs) {
|
||||
return 0, errInvalidGPOSTable
|
||||
}
|
||||
secondGlyphIndex := GlyphIndex(int(u16(glyphs[offset+2+i*4:])))
|
||||
if secondGlyphIndex == b {
|
||||
return int16(u16(glyphs[offset+2+i*4+2:])), nil
|
||||
@@ -372,6 +375,9 @@ func makeCachedPairPosClass(cov indexLookupFunc, num1, num2 int, cdef1, cdef2 cl
|
||||
}
|
||||
idxa := cdef1(a)
|
||||
idxb := cdef2(b)
|
||||
if idxa < 0 || idxa >= num1 || idxb < 0 || idxb >= num2 {
|
||||
return 0, errInvalidGPOSTable
|
||||
}
|
||||
return int16(u16(glyphs[(idxb+idxa*num2)*2:])), nil
|
||||
}
|
||||
}
|
||||
|
||||
31
vendor/golang.org/x/image/internal/safemath/safemath.go
generated
vendored
Normal file
31
vendor/golang.org/x/image/internal/safemath/safemath.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2026 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package safemath contains overflow-safe math functions.
|
||||
package safemath
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// Mul3 returns (x * y * z), unless at least one argument is negative or if the
|
||||
// computation overflows the int type.
|
||||
func Mul3(x, y, z int) (_ int, ok bool) {
|
||||
// The following is copied from image/geom.go in std,
|
||||
// but returns an explicit ok/not-ok rather than using -1 to indicate an error.
|
||||
if x < 0 || y < 0 || z < 0 {
|
||||
return -1, false
|
||||
}
|
||||
hi, lo := bits.Mul64(uint64(x), uint64(y))
|
||||
if hi != 0 {
|
||||
return -1, false
|
||||
}
|
||||
hi, lo = bits.Mul64(lo, uint64(z))
|
||||
if hi != 0 {
|
||||
return -1, false
|
||||
}
|
||||
a := int(lo)
|
||||
if a < 0 || uint64(a) != lo {
|
||||
return -1, false
|
||||
}
|
||||
return a, true
|
||||
}
|
||||
26
vendor/golang.org/x/image/tiff/buffer.go
generated
vendored
26
vendor/golang.org/x/image/tiff/buffer.go
generated
vendored
@@ -5,7 +5,9 @@
|
||||
package tiff
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"slices"
|
||||
)
|
||||
|
||||
@@ -35,22 +37,34 @@ func (b *buffer) fill(end int) error {
|
||||
}
|
||||
|
||||
func (b *buffer) ReadAt(p []byte, off int64) (int, error) {
|
||||
o := int(off)
|
||||
end := o + len(p)
|
||||
if int64(end) != off+int64(len(p)) {
|
||||
if off < 0 {
|
||||
// Impossible in correct usage, but check for safety.
|
||||
return 0, fmt.Errorf("invalid ReadAt offset %v (bug)", off)
|
||||
}
|
||||
end64 := off + int64(len(p))
|
||||
if end64 < off || end64 > math.MaxInt {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
end := int(end64)
|
||||
|
||||
err := b.fill(end)
|
||||
end = min(end, len(b.buf))
|
||||
return copy(p, b.buf[min(o, end):end]), err
|
||||
return copy(p, b.buf[min(int(off), end):end]), err
|
||||
}
|
||||
|
||||
// Slice returns a slice of the underlying buffer. The slice contains
|
||||
// n bytes starting at offset off.
|
||||
func (b *buffer) Slice(off, n int) ([]byte, error) {
|
||||
func (b *buffer) Slice(off, n int64) ([]byte, error) {
|
||||
if off < 0 || n < 0 {
|
||||
// Impossible in correct usage, but check for safety.
|
||||
return nil, fmt.Errorf("invalid negative input to Slice(%v, %v) (bug)", off, n)
|
||||
}
|
||||
end := off + n
|
||||
if err := b.fill(end); err != nil {
|
||||
if end < 0 || end > math.MaxInt {
|
||||
// end is too large. Treat this as a read error.
|
||||
return nil, io.ErrUnexpectedEOF
|
||||
}
|
||||
if err := b.fill(int(end)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b.buf[off:end], nil
|
||||
|
||||
8
vendor/golang.org/x/image/tiff/compress.go
generated
vendored
8
vendor/golang.org/x/image/tiff/compress.go
generated
vendored
@@ -15,11 +15,12 @@ type byteReader interface {
|
||||
}
|
||||
|
||||
// unpackBits decodes the PackBits-compressed data in src and returns the
|
||||
// uncompressed data.
|
||||
// uncompressed data. The output size is limited to lim bytes to prevent
|
||||
// decompression bombs.
|
||||
//
|
||||
// The PackBits compression format is described in section 9 (p. 42)
|
||||
// of the TIFF spec.
|
||||
func unpackBits(r io.Reader) ([]byte, error) {
|
||||
func unpackBits(r io.Reader, lim int64) ([]byte, error) {
|
||||
buf := make([]byte, 128)
|
||||
dst := make([]byte, 0, 1024)
|
||||
br, ok := r.(byteReader)
|
||||
@@ -54,5 +55,8 @@ func unpackBits(r io.Reader) ([]byte, error) {
|
||||
}
|
||||
dst = append(dst, buf[:1-code]...)
|
||||
}
|
||||
if int64(len(dst)) > lim {
|
||||
return nil, FormatError("PackBits: decompressed data too large")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
164
vendor/golang.org/x/image/tiff/reader.go
generated
vendored
164
vendor/golang.org/x/image/tiff/reader.go
generated
vendored
@@ -11,7 +11,6 @@ import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
@@ -19,6 +18,7 @@ import (
|
||||
"math"
|
||||
|
||||
"golang.org/x/image/ccitt"
|
||||
"golang.org/x/image/internal/safemath"
|
||||
"golang.org/x/image/tiff/lzw"
|
||||
)
|
||||
|
||||
@@ -95,6 +95,7 @@ type decoder struct {
|
||||
mode imageMode
|
||||
bpp uint
|
||||
features map[int][]uint
|
||||
ifd map[int][ifdLen]byte
|
||||
palette []color.Color
|
||||
|
||||
buf []byte
|
||||
@@ -113,9 +114,23 @@ func (d *decoder) firstVal(tag int) uint {
|
||||
return f[0]
|
||||
}
|
||||
|
||||
// firstIntVal returns the first int of the features entry with the given tag,
|
||||
// or 0 if the tag does not exist.
|
||||
// If the tag overflows an int, it returns an error.
|
||||
func (d *decoder) firstIntVal(tag int) (int, error) {
|
||||
v := d.firstVal(tag)
|
||||
if v > math.MaxInt {
|
||||
return 0, FormatError("IFD value too large")
|
||||
}
|
||||
return int(v), nil
|
||||
}
|
||||
|
||||
// ifdUint decodes the IFD entry in p, which must be of the Byte, Short
|
||||
// or Long type, and returns the decoded uint values.
|
||||
func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
|
||||
//
|
||||
// maxCount limits the number of values.
|
||||
// If the entry contains more than maxCount values, only the first maxCount are parsed.
|
||||
func (d *decoder) ifdUint(p []byte, maxCount int) (u []uint, err error) {
|
||||
var raw []byte
|
||||
if len(p) < ifdLen {
|
||||
return nil, FormatError("bad IFD entry")
|
||||
@@ -130,9 +145,11 @@ func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
|
||||
if count > math.MaxInt32/lengths[datatype] {
|
||||
return nil, FormatError("IFD data too large")
|
||||
}
|
||||
truncatedCount := min(int(count), maxCount)
|
||||
if datalen := lengths[datatype] * count; datalen > 4 {
|
||||
truncatedLen := uint64(lengths[datatype]) * uint64(truncatedCount)
|
||||
// The IFD contains a pointer to the real value.
|
||||
raw, err = safeReadAt(d.r, uint64(datalen), int64(d.byteOrder.Uint32(p[8:12])))
|
||||
raw, err = safeReadAt(d.r, truncatedLen, int64(d.byteOrder.Uint32(p[8:12])))
|
||||
} else {
|
||||
raw = p[8 : 8+datalen]
|
||||
}
|
||||
@@ -140,18 +157,18 @@ func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
u = make([]uint, count)
|
||||
u = make([]uint, truncatedCount)
|
||||
switch datatype {
|
||||
case dtByte:
|
||||
for i := uint32(0); i < count; i++ {
|
||||
for i := range u {
|
||||
u[i] = uint(raw[i])
|
||||
}
|
||||
case dtShort:
|
||||
for i := uint32(0); i < count; i++ {
|
||||
for i := range u {
|
||||
u[i] = uint(d.byteOrder.Uint16(raw[2*i : 2*(i+1)]))
|
||||
}
|
||||
case dtLong:
|
||||
for i := uint32(0); i < count; i++ {
|
||||
for i := range u {
|
||||
u[i] = uint(d.byteOrder.Uint32(raw[4*i : 4*(i+1)]))
|
||||
}
|
||||
default:
|
||||
@@ -160,10 +177,30 @@ func (d *decoder) ifdUint(p []byte) (u []uint, err error) {
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// parseIFDOffsets parses an IFD entry stored in d.ifd using ifdUint.
|
||||
// For IFD entries which can be large, we delay reading and parsing the entry
|
||||
// until we know the image size, which lets us set reasonable bounds on the IFD entry.
|
||||
func (d *decoder) parseIFDOffsets(tag int, maxCount int) (u []uint, err error) {
|
||||
p, ok := d.ifd[tag]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return d.ifdUint(p[:], maxCount)
|
||||
}
|
||||
|
||||
// parseIFD decides whether the IFD entry in p is "interesting" and
|
||||
// stows away the data in the decoder. It returns the tag number of the
|
||||
// entry and an error, if any.
|
||||
func (d *decoder) parseIFD(p []byte) (int, error) {
|
||||
// smallEntryMaxCount is the limit to use for parsed IFD entries that
|
||||
// don't scale with the image size.
|
||||
//
|
||||
// We could be more precise and limit the number of entries to exactly the
|
||||
// correct limit (for example, tTileWidth should always have exactly one value),
|
||||
// but 16 is small enough to prevent excessive allocation and large enough to
|
||||
// allow for any multi-value entry.
|
||||
const smallEntryMaxCount = 16
|
||||
|
||||
tag := d.byteOrder.Uint16(p[0:2])
|
||||
switch tag {
|
||||
case tBitsPerSample,
|
||||
@@ -171,30 +208,36 @@ func (d *decoder) parseIFD(p []byte) (int, error) {
|
||||
tPhotometricInterpretation,
|
||||
tCompression,
|
||||
tPredictor,
|
||||
tStripOffsets,
|
||||
tStripByteCounts,
|
||||
tRowsPerStrip,
|
||||
tTileWidth,
|
||||
tTileLength,
|
||||
tTileOffsets,
|
||||
tTileByteCounts,
|
||||
tImageLength,
|
||||
tImageWidth,
|
||||
tFillOrder,
|
||||
tT4Options,
|
||||
tT6Options:
|
||||
val, err := d.ifdUint(p)
|
||||
val, err := d.ifdUint(p, smallEntryMaxCount)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
d.features[int(tag)] = val
|
||||
case tStripOffsets,
|
||||
tStripByteCounts,
|
||||
tTileOffsets,
|
||||
tTileByteCounts:
|
||||
// These keys may contain many values.
|
||||
// Stash the IFD entry for later parsing.
|
||||
var v [ifdLen]byte
|
||||
copy(v[:], p)
|
||||
d.ifd[int(tag)] = v
|
||||
case tColorMap:
|
||||
val, err := d.ifdUint(p)
|
||||
const maxColors = 256
|
||||
val, err := d.ifdUint(p, (3*maxColors)+1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
numcolors := len(val) / 3
|
||||
if len(val)%3 != 0 || numcolors <= 0 || numcolors > 256 {
|
||||
if len(val)%3 != 0 || numcolors <= 0 || numcolors > maxColors {
|
||||
return 0, FormatError("bad ColorMap length")
|
||||
}
|
||||
d.palette = make([]color.Color, numcolors)
|
||||
@@ -211,7 +254,7 @@ func (d *decoder) parseIFD(p []byte) (int, error) {
|
||||
// the value is not 1 [= unsigned integer data], a Baseline
|
||||
// TIFF reader that cannot handle the SampleFormat value
|
||||
// must terminate the import process gracefully.
|
||||
val, err := d.ifdUint(p)
|
||||
val, err := d.ifdUint(p, smallEntryMaxCount)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -450,10 +493,15 @@ func (d *decoder) decode(dst image.Image, xmin, ymin, xmax, ymax int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// maxBytesPerPixel is the maximum possible bytes-per-pixel,
|
||||
// used for conservative bounds checking.
|
||||
const maxBytesPerPixel = 8
|
||||
|
||||
func newDecoder(r io.Reader) (*decoder, error) {
|
||||
d := &decoder{
|
||||
r: newReaderAt(r),
|
||||
features: make(map[int][]uint),
|
||||
ifd: make(map[int][ifdLen]byte),
|
||||
}
|
||||
|
||||
p := make([]byte, 8)
|
||||
@@ -499,10 +547,20 @@ func newDecoder(r io.Reader) (*decoder, error) {
|
||||
prevTag = tag
|
||||
}
|
||||
|
||||
d.config.Width = int(d.firstVal(tImageWidth))
|
||||
d.config.Height = int(d.firstVal(tImageLength))
|
||||
if d.config.Width, err = d.firstIntVal(tImageWidth); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if d.config.Height, err = d.firstIntVal(tImageLength); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if d.config.Width == 0 || d.config.Height == 0 {
|
||||
return nil, errors.New("tiff: zero-size image")
|
||||
return nil, FormatError("zero-size image")
|
||||
}
|
||||
// Check that the image fits in memory.
|
||||
// This conservatively assumes 8 bytes per pixel,
|
||||
// rather than using the actual pixel size.
|
||||
if _, ok := safemath.Mul3(d.config.Width, d.config.Height, maxBytesPerPixel); !ok {
|
||||
return nil, FormatError("image too large")
|
||||
}
|
||||
|
||||
if _, ok := d.features[tBitsPerSample]; !ok {
|
||||
@@ -640,11 +698,15 @@ func Decode(r io.Reader) (img image.Image, err error) {
|
||||
|
||||
var blockOffsets, blockCounts []uint
|
||||
|
||||
if int(d.firstVal(tTileWidth)) != 0 {
|
||||
if d.firstVal(tTileWidth) != 0 {
|
||||
blockPadding = true
|
||||
|
||||
blockWidth = int(d.firstVal(tTileWidth))
|
||||
blockHeight = int(d.firstVal(tTileLength))
|
||||
if blockWidth, err = d.firstIntVal(tTileWidth); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if blockHeight, err = d.firstIntVal(tTileLength); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The specification says that tile widths and lengths must be a multiple of 16.
|
||||
// We currently permit invalid sizes, but reject anything too small to limit the
|
||||
@@ -652,7 +714,30 @@ func Decode(r io.Reader) (img image.Image, err error) {
|
||||
if blockWidth < 8 || blockHeight < 8 {
|
||||
return nil, FormatError("tile size is too small")
|
||||
}
|
||||
|
||||
// Same conservative assumption on bytes-per-pixel as for the image dimensions.
|
||||
if _, ok := safemath.Mul3(blockWidth, blockHeight, maxBytesPerPixel); !ok {
|
||||
return nil, FormatError("tile size is too large")
|
||||
}
|
||||
if blockWidth-d.config.Width > 16 || blockHeight-d.config.Height > 16 {
|
||||
// Tiles may be padded to the nearest multiple of 16, but one of
|
||||
// the dimensions of the tile exceeds the image dimension by more
|
||||
// than padding would require.
|
||||
//
|
||||
// Typical TIFF tiles are 256x256, but 1024x1024 appears to be
|
||||
// in occasional use. If the tile is both larger than the image
|
||||
// and has more than 1024 pixels in one dimension, it's
|
||||
// probably malicious input.
|
||||
//
|
||||
// Note that this still permits very large tiles,
|
||||
// so long as the tile is smaller than the image dimensions.
|
||||
// A gigapixel image with a 2048x2048 tile size
|
||||
// (used in some GIS applications)
|
||||
// will be valid because the image dimensions are much larger
|
||||
// than the tile size.
|
||||
if blockWidth > 1024 || blockHeight > 1024 {
|
||||
return nil, FormatError("tile size exceeds image size")
|
||||
}
|
||||
}
|
||||
if blockWidth != 0 {
|
||||
blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth
|
||||
}
|
||||
@@ -660,20 +745,34 @@ func Decode(r io.Reader) (img image.Image, err error) {
|
||||
blocksDown = (d.config.Height + blockHeight - 1) / blockHeight
|
||||
}
|
||||
|
||||
blockCounts = d.features[tTileByteCounts]
|
||||
blockOffsets = d.features[tTileOffsets]
|
||||
|
||||
blockOffsets, err = d.parseIFDOffsets(tTileOffsets, blocksAcross*blocksDown)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockCounts, err = d.parseIFDOffsets(tTileByteCounts, blocksAcross*blocksDown)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
if int(d.firstVal(tRowsPerStrip)) != 0 {
|
||||
blockHeight = int(d.firstVal(tRowsPerStrip))
|
||||
|
||||
if v := d.firstVal(tRowsPerStrip); v > 0 && v < uint(blockHeight) {
|
||||
blockHeight = int(v)
|
||||
}
|
||||
|
||||
if blockHeight != 0 {
|
||||
// This can't overflow: We require that w*h*8 not overflow and
|
||||
// blockHeight is no more than d.config.Height.
|
||||
blocksDown = (d.config.Height + blockHeight - 1) / blockHeight
|
||||
}
|
||||
|
||||
blockOffsets = d.features[tStripOffsets]
|
||||
blockCounts = d.features[tStripByteCounts]
|
||||
blockOffsets, err = d.parseIFDOffsets(tStripOffsets, blocksDown)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockCounts, err = d.parseIFDOffsets(tStripByteCounts, blocksDown)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we have the right number of strips/tiles, offsets and counts.
|
||||
@@ -728,8 +827,11 @@ func Decode(r io.Reader) (img image.Image, err error) {
|
||||
// but some tools interpret a missing Compression value as none, so we do
|
||||
// the same.
|
||||
case cNone, 0:
|
||||
if n > blockMaxDataSize {
|
||||
return nil, FormatError("block data size too large")
|
||||
}
|
||||
if b, ok := d.r.(*buffer); ok {
|
||||
d.buf, err = b.Slice(int(offset), int(n))
|
||||
d.buf, err = b.Slice(offset, n)
|
||||
} else {
|
||||
d.buf, err = safeReadAt(d.r, uint64(n), offset)
|
||||
}
|
||||
@@ -756,7 +858,7 @@ func Decode(r io.Reader) (img image.Image, err error) {
|
||||
d.buf, err = readBuf(r, d.buf, blockMaxDataSize)
|
||||
r.Close()
|
||||
case cPackBits:
|
||||
d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n))
|
||||
d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n), blockMaxDataSize)
|
||||
default:
|
||||
err = UnsupportedError(fmt.Sprintf("compression value %d", d.firstVal(tCompression)))
|
||||
}
|
||||
|
||||
20
vendor/golang.org/x/image/webp/decode.go
generated
vendored
20
vendor/golang.org/x/image/webp/decode.go
generated
vendored
@@ -82,6 +82,9 @@ func decode(r io.Reader, configOnly bool) (image.Image, image.Config, error) {
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
if seenVP8X && (fh.Width != int(widthMinusOne)+1 || fh.Height != int(heightMinusOne)+1) {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
if configOnly {
|
||||
return nil, image.Config{
|
||||
ColorModel: color.YCbCrModel,
|
||||
@@ -111,7 +114,16 @@ func decode(r io.Reader, configOnly bool) (image.Image, image.Config, error) {
|
||||
return nil, c, err
|
||||
}
|
||||
m, err := vp8l.Decode(chunkData)
|
||||
return m, image.Config{}, err
|
||||
if err != nil {
|
||||
return nil, image.Config{}, err
|
||||
}
|
||||
if seenVP8X {
|
||||
bounds := m.Bounds()
|
||||
if bounds.Dx() != int(widthMinusOne)+1 || bounds.Dy() != int(heightMinusOne)+1 {
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
}
|
||||
return m, image.Config{}, nil
|
||||
|
||||
case fccVP8X:
|
||||
if seenVP8X {
|
||||
@@ -134,10 +146,12 @@ func decode(r io.Reader, configOnly bool) (image.Image, image.Config, error) {
|
||||
wantAlpha = (buf[0] & alphaBit) != 0
|
||||
widthMinusOne = uint32(buf[4]) | uint32(buf[5])<<8 | uint32(buf[6])<<16
|
||||
heightMinusOne = uint32(buf[7]) | uint32(buf[8])<<8 | uint32(buf[9])<<16
|
||||
if uint64(widthMinusOne+1)*uint64(heightMinusOne+1) > 1<<32-1 {
|
||||
w := uint64(widthMinusOne) + 1
|
||||
h := uint64(heightMinusOne) + 1
|
||||
if w*h > 1<<31-1 {
|
||||
// The product of _Canvas Width_ and _Canvas Height_ MUST be
|
||||
// at most 2^32 - 1.
|
||||
// https://www.rfc-editor.org/rfc/rfc9649.html#section-2.7-12
|
||||
// But it also needs to fit in an int, so limit it to MaxInt32.
|
||||
return nil, image.Config{}, errInvalidFormat
|
||||
}
|
||||
if configOnly {
|
||||
|
||||
5
vendor/modules.txt
vendored
5
vendor/modules.txt
vendored
@@ -872,7 +872,7 @@ github.com/kovidgoyal/go-parallel
|
||||
# github.com/kovidgoyal/go-shm v1.0.0
|
||||
## explicit; go 1.24.0
|
||||
github.com/kovidgoyal/go-shm
|
||||
# github.com/kovidgoyal/imaging v1.8.21
|
||||
# github.com/kovidgoyal/imaging v1.8.22
|
||||
## explicit; go 1.25.0
|
||||
github.com/kovidgoyal/imaging
|
||||
github.com/kovidgoyal/imaging/apng
|
||||
@@ -2444,7 +2444,7 @@ golang.org/x/exp/slices
|
||||
golang.org/x/exp/slog
|
||||
golang.org/x/exp/slog/internal
|
||||
golang.org/x/exp/slog/internal/buffer
|
||||
# golang.org/x/image v0.40.0
|
||||
# golang.org/x/image v0.43.0
|
||||
## explicit; go 1.25.0
|
||||
golang.org/x/image/bmp
|
||||
golang.org/x/image/ccitt
|
||||
@@ -2452,6 +2452,7 @@ golang.org/x/image/font
|
||||
golang.org/x/image/font/gofont/goregular
|
||||
golang.org/x/image/font/opentype
|
||||
golang.org/x/image/font/sfnt
|
||||
golang.org/x/image/internal/safemath
|
||||
golang.org/x/image/math/fixed
|
||||
golang.org/x/image/riff
|
||||
golang.org/x/image/tiff
|
||||
|
||||
Reference in New Issue
Block a user