• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

qmuntal / gltf / 26563627387

28 May 2026 08:26AM UTC coverage: 88.252% (-0.2%) from 88.413%
26563627387

push

github

web-flow
Merge pull request #102 from qmuntal/fix/modeler-read-validation

Fix modeler read validation

113 of 127 new or added lines in 3 files covered. (88.98%)

6 existing lines in 2 files now uncovered.

2817 of 3192 relevant lines covered (88.25%)

101.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.25
/binary/encode.go
1
package binary
2

3
import (
4
        "bytes"
5
        "encoding/binary"
6
        "fmt"
7
        "image/color"
8
        "io"
9
        "math"
10

11
        "github.com/qmuntal/gltf"
12
)
13

14
// Read reads structured binary data from b into data.
15
// byteStride can be zero for non-interleaved buffer views.
16
//
17
// Data should be a slice of glTF predefined fixed-size types.
18
// If data length is greater than the length of b, Read returns io.ErrShortBuffer.
19
func Read(b []byte, byteStride int, data any) error {
336✔
20
        c, t, n := Type(data)
336✔
21
        size := gltf.SizeOfElement(c, t)
336✔
22
        if byteStride < 0 {
342✔
23
                return fmt.Errorf("gltf: byte stride %d not allowed", byteStride)
6✔
24
        }
6✔
25
        if byteStride == 0 {
654✔
26
                byteStride = size
324✔
27
        }
324✔
28
        if byteStride < size {
336✔
29
                return fmt.Errorf("gltf: byte stride %d smaller than element size %d", byteStride, size)
6✔
30
        }
6✔
31
        if n == 0 {
330✔
32
                return nil
6✔
33
        }
6✔
34
        if n > 1 && byteStride > (math.MaxInt-size)/(n-1) {
318✔
NEW
35
                return io.ErrShortBuffer
×
UNCOV
36
        }
×
37
        e := byteStride
318✔
38
        high := size + (n-1)*byteStride
318✔
39
        if len(b) < high {
324✔
40
                return io.ErrShortBuffer
6✔
41
        }
6✔
42
        switch data := data.(type) {
312✔
43
        case []color.RGBA:
6✔
44
                for i := range data {
18✔
45
                        c := Ubyte.Vec4(b[e*i:])
12✔
46
                        data[i] = color.RGBA{R: c[0], G: c[1], B: c[2], A: c[3]}
12✔
47
                }
12✔
48
        case []color.RGBA64:
6✔
49
                for i := range data {
18✔
50
                        c := Ushort.Vec4(b[e*i:])
12✔
51
                        data[i] = color.RGBA64{R: c[0], G: c[1], B: c[2], A: c[3]}
12✔
52
                }
12✔
53
        case []int8:
12✔
54
                for i := range data {
42✔
55
                        data[i] = Byte.Scalar(b[e*i:])
30✔
56
                }
30✔
57
        case [][2]int8:
6✔
58
                for i := range data {
18✔
59
                        data[i] = Byte.Vec2(b[e*i:])
12✔
60
                }
12✔
61
        case [][3]int8:
6✔
62
                for i := range data {
18✔
63
                        data[i] = Byte.Vec3(b[e*i:])
12✔
64
                }
12✔
65
        case [][4]int8:
6✔
66
                for i := range data {
18✔
67
                        data[i] = Byte.Vec4(b[e*i:])
12✔
68
                }
12✔
69
        case [][2][2]int8:
6✔
70
                for i := range data {
18✔
71
                        data[i] = Byte.Mat2(b[e*i:])
12✔
72
                }
12✔
73
        case [][3][3]int8:
6✔
74
                for i := range data {
18✔
75
                        data[i] = Byte.Mat3(b[e*i:])
12✔
76
                }
12✔
77
        case [][4][4]int8:
6✔
78
                for i := range data {
18✔
79
                        data[i] = Byte.Mat4(b[e*i:])
12✔
80
                }
12✔
81
        case []uint8:
18✔
82
                for i := range data {
156✔
83
                        data[i] = Ubyte.Scalar(b[e*i:])
138✔
84
                }
138✔
85
        case [][2]uint8:
6✔
86
                for i := range data {
18✔
87
                        data[i] = Ubyte.Vec2(b[e*i:])
12✔
88
                }
12✔
89
        case [][3]uint8:
6✔
90
                for i := range data {
18✔
91
                        data[i] = Ubyte.Vec3(b[e*i:])
12✔
92
                }
12✔
93
        case [][4]uint8:
6✔
94
                for i := range data {
18✔
95
                        data[i] = Ubyte.Vec4(b[e*i:])
12✔
96
                }
12✔
97
        case [][2][2]uint8:
6✔
98
                for i := range data {
18✔
99
                        data[i] = Ubyte.Mat2(b[e*i:])
12✔
100
                }
12✔
101
        case [][3][3]uint8:
6✔
102
                for i := range data {
18✔
103
                        data[i] = Ubyte.Mat3(b[e*i:])
12✔
104
                }
12✔
105
        case [][4][4]uint8:
6✔
106
                for i := range data {
18✔
107
                        data[i] = Ubyte.Mat4(b[e*i:])
12✔
108
                }
12✔
109
        case []int16:
12✔
110
                for i := range data {
42✔
111
                        data[i] = Short.Scalar(b[e*i:])
30✔
112
                }
30✔
113
        case [][2]int16:
6✔
114
                for i := range data {
18✔
115
                        data[i] = Short.Vec2(b[e*i:])
12✔
116
                }
12✔
117
        case [][3]int16:
6✔
118
                for i := range data {
18✔
119
                        data[i] = Short.Vec3(b[e*i:])
12✔
120
                }
12✔
121
        case [][4]int16:
6✔
122
                for i := range data {
18✔
123
                        data[i] = Short.Vec4(b[e*i:])
12✔
124
                }
12✔
125
        case [][2][2]int16:
6✔
126
                for i := range data {
18✔
127
                        data[i] = Short.Mat2(b[e*i:])
12✔
128
                }
12✔
129
        case [][3][3]int16:
6✔
130
                for i := range data {
18✔
131
                        data[i] = Short.Mat3(b[e*i:])
12✔
132
                }
12✔
133
        case [][4][4]int16:
6✔
134
                for i := range data {
18✔
135
                        data[i] = Short.Mat4(b[e*i:])
12✔
136
                }
12✔
137
        case []uint16:
12✔
138
                for i := range data {
42✔
139
                        data[i] = Ushort.Scalar(b[e*i:])
30✔
140
                }
30✔
141
        case [][2]uint16:
6✔
142
                for i := range data {
18✔
143
                        data[i] = Ushort.Vec2(b[e*i:])
12✔
144
                }
12✔
145
        case [][3]uint16:
6✔
146
                for i := range data {
18✔
147
                        data[i] = Ushort.Vec3(b[e*i:])
12✔
148
                }
12✔
149
        case [][4]uint16:
6✔
150
                for i := range data {
18✔
151
                        data[i] = Ushort.Vec4(b[e*i:])
12✔
152
                }
12✔
153
        case [][2][2]uint16:
6✔
154
                for i := range data {
18✔
155
                        data[i] = Ushort.Mat2(b[e*i:])
12✔
156
                }
12✔
157
        case [][3][3]uint16:
6✔
158
                for i := range data {
18✔
159
                        data[i] = Ushort.Mat3(b[e*i:])
12✔
160
                }
12✔
161
        case [][4][4]uint16:
6✔
162
                for i := range data {
18✔
163
                        data[i] = Ushort.Mat4(b[e*i:])
12✔
164
                }
12✔
165
        case []float32:
12✔
166
                for i := range data {
42✔
167
                        data[i] = Float.Scalar(b[e*i:])
30✔
168
                }
30✔
169
        case [][2]float32:
6✔
170
                for i := range data {
18✔
171
                        data[i] = Float.Vec2(b[e*i:])
12✔
172
                }
12✔
173
        case [][3]float32:
12✔
174
                for i := range data {
54✔
175
                        data[i] = Float.Vec3(b[e*i:])
42✔
176
                }
42✔
177
        case [][4]float32:
6✔
178
                for i := range data {
18✔
179
                        data[i] = Float.Vec4(b[e*i:])
12✔
180
                }
12✔
181
        case [][2][2]float32:
6✔
182
                for i := range data {
18✔
183
                        data[i] = Float.Mat2(b[e*i:])
12✔
184
                }
12✔
185
        case [][3][3]float32:
6✔
186
                for i := range data {
18✔
187
                        data[i] = Float.Mat3(b[e*i:])
12✔
188
                }
12✔
189
        case [][4][4]float32:
6✔
190
                for i := range data {
18✔
191
                        data[i] = Float.Mat4(b[e*i:])
12✔
192
                }
12✔
193
        case []uint32:
12✔
194
                for i := range data {
42✔
195
                        data[i] = Uint.Scalar(b[e*i:])
30✔
196
                }
30✔
197
        case [][2]uint32:
6✔
198
                for i := range data {
18✔
199
                        data[i] = Uint.Vec2(b[e*i:])
12✔
200
                }
12✔
201
        case [][3]uint32:
6✔
202
                for i := range data {
18✔
203
                        data[i] = Uint.Vec3(b[e*i:])
12✔
204
                }
12✔
205
        case [][4]uint32:
6✔
206
                for i := range data {
18✔
207
                        data[i] = Uint.Vec4(b[e*i:])
12✔
208
                }
12✔
209
        case [][2][2]uint32:
6✔
210
                for i := range data {
18✔
211
                        data[i] = Uint.Mat2(b[e*i:])
12✔
212
                }
12✔
213
        case [][3][3]uint32:
6✔
214
                for i := range data {
18✔
215
                        data[i] = Uint.Mat3(b[e*i:])
12✔
216
                }
12✔
217
        case [][4][4]uint32:
6✔
218
                for i := range data {
18✔
219
                        data[i] = Uint.Mat4(b[e*i:])
12✔
220
                }
12✔
221
        default:
×
222
                panic("unsupported type")
×
223
        }
224
        return nil
312✔
225
}
226

227
// Write writes the binary representation of data into b.
228
// If stride is diferent than zero data will be interleaved.
229
//
230
// Data must be a slice of glTF predefined fixed-size types,
231
// else it fallbacks to `encoding/binary.Write`.
232
func Write(b []byte, stride int, data any) error {
324✔
233
        c, t, n := Type(data)
324✔
234
        if n == 0 {
330✔
235
                return binary.Write(bytes.NewBuffer(b), binary.LittleEndian, data)
6✔
236
        }
6✔
237
        e := int(stride)
318✔
238
        sizeOfElement := int(gltf.SizeOfElement(c, t))
318✔
239
        if stride == 0 {
636✔
240
                e = sizeOfElement
318✔
241
        }
318✔
242
        if len(b) < e*(int(n)-1)+sizeOfElement {
324✔
243
                return io.ErrShortBuffer
6✔
244
        }
6✔
245
        switch data := data.(type) {
312✔
246
        case []color.RGBA:
6✔
247
                for i, x := range data {
18✔
248
                        Ubyte.PutVec4(b[e*i:], [4]uint8{x.R, x.G, x.B, x.A})
12✔
249
                }
12✔
250
        case []color.RGBA64:
6✔
251
                for i, x := range data {
18✔
252
                        Ushort.PutVec4(b[e*i:], [4]uint16{x.R, x.G, x.B, x.A})
12✔
253
                }
12✔
254
        case []int8:
12✔
255
                for i, x := range data {
42✔
256
                        b[e*i] = byte(x)
30✔
257
                }
30✔
258
        case [][2]int8:
6✔
259
                for i := range data {
18✔
260
                        Byte.PutVec2(b[e*i:], data[i])
12✔
261
                }
12✔
262
        case [][3]int8:
6✔
263
                for i := range data {
18✔
264
                        Byte.PutVec3(b[e*i:], data[i])
12✔
265
                }
12✔
266
        case [][4]int8:
6✔
267
                for i := range data {
18✔
268
                        Byte.PutVec4(b[e*i:], data[i])
12✔
269
                }
12✔
270
        case [][2][2]int8:
6✔
271
                for i := range data {
18✔
272
                        Byte.PutMat2(b[e*i:], data[i])
12✔
273
                }
12✔
274
        case [][3][3]int8:
6✔
275
                for i := range data {
18✔
276
                        Byte.PutMat3(b[e*i:], data[i])
12✔
277
                }
12✔
278
        case [][4][4]int8:
6✔
279
                for i := range data {
18✔
280
                        Byte.PutMat4(b[e*i:], data[i])
12✔
281
                }
12✔
282
        case []uint8:
18✔
283
                if e == 1 {
36✔
284
                        copy(b, data)
18✔
285
                } else {
18✔
286
                        for i, x := range data {
×
287
                                Ubyte.PutScalar(b[e*i:], x)
×
288
                        }
×
289
                }
290
        case [][2]uint8:
6✔
291
                for i := range data {
18✔
292
                        Ubyte.PutVec2(b[e*i:], data[i])
12✔
293
                }
12✔
294
        case [][3]uint8:
6✔
295
                for i := range data {
18✔
296
                        Ubyte.PutVec3(b[e*i:], data[i])
12✔
297
                }
12✔
298
        case [][4]uint8:
6✔
299
                for i := range data {
18✔
300
                        Ubyte.PutVec4(b[e*i:], data[i])
12✔
301
                }
12✔
302
        case [][2][2]uint8:
6✔
303
                for i := range data {
18✔
304
                        Ubyte.PutMat2(b[e*i:], data[i])
12✔
305
                }
12✔
306
        case [][3][3]uint8:
6✔
307
                for i := range data {
18✔
308
                        Ubyte.PutMat3(b[e*i:], data[i])
12✔
309
                }
12✔
310
        case [][4][4]uint8:
6✔
311
                for i := range data {
18✔
312
                        Ubyte.PutMat4(b[e*i:], data[i])
12✔
313
                }
12✔
314
        case []int16:
12✔
315
                for i := range data {
42✔
316
                        Short.PutScalar(b[e*i:], data[i])
30✔
317
                }
30✔
318
        case [][2]int16:
6✔
319
                for i := range data {
18✔
320
                        Short.PutVec2(b[e*i:], data[i])
12✔
321
                }
12✔
322
        case [][3]int16:
6✔
323
                for i := range data {
18✔
324
                        Short.PutVec3(b[e*i:], data[i])
12✔
325
                }
12✔
326
        case [][4]int16:
6✔
327
                for i := range data {
18✔
328
                        Short.PutVec4(b[e*i:], data[i])
12✔
329
                }
12✔
330
        case [][2][2]int16:
6✔
331
                for i := range data {
18✔
332
                        Short.PutMat2(b[e*i:], data[i])
12✔
333
                }
12✔
334
        case [][3][3]int16:
6✔
335
                for i := range data {
18✔
336
                        Short.PutMat3(b[e*i:], data[i])
12✔
337
                }
12✔
338
        case [][4][4]int16:
6✔
339
                for i := range data {
18✔
340
                        Short.PutMat4(b[e*i:], data[i])
12✔
341
                }
12✔
342
        case []uint16:
12✔
343
                for i := range data {
42✔
344
                        Ushort.PutScalar(b[e*i:], data[i])
30✔
345
                }
30✔
346
        case [][2]uint16:
6✔
347
                for i := range data {
18✔
348
                        Ushort.PutVec2(b[e*i:], data[i])
12✔
349
                }
12✔
350
        case [][3]uint16:
6✔
351
                for i := range data {
18✔
352
                        Ushort.PutVec3(b[e*i:], data[i])
12✔
353
                }
12✔
354
        case [][4]uint16:
6✔
355
                for i := range data {
18✔
356
                        Ushort.PutVec4(b[e*i:], data[i])
12✔
357
                }
12✔
358
        case [][2][2]uint16:
6✔
359
                for i := range data {
18✔
360
                        Ushort.PutMat2(b[e*i:], data[i])
12✔
361
                }
12✔
362
        case [][3][3]uint16:
6✔
363
                for i := range data {
18✔
364
                        Ushort.PutMat3(b[e*i:], data[i])
12✔
365
                }
12✔
366
        case [][4][4]uint16:
6✔
367
                for i := range data {
18✔
368
                        Ushort.PutMat4(b[e*i:], data[i])
12✔
369
                }
12✔
370
        case []float32:
12✔
371
                for i := range data {
42✔
372
                        Float.PutScalar(b[e*i:], data[i])
30✔
373
                }
30✔
374
        case [][2]float32:
6✔
375
                for i := range data {
18✔
376
                        Float.PutVec2(b[e*i:], data[i])
12✔
377
                }
12✔
378
        case [][3]float32:
12✔
379
                for i := range data {
54✔
380
                        Float.PutVec3(b[e*i:], data[i])
42✔
381
                }
42✔
382
        case [][4]float32:
6✔
383
                for i := range data {
18✔
384
                        Float.PutVec4(b[e*i:], data[i])
12✔
385
                }
12✔
386
        case [][2][2]float32:
6✔
387
                for i := range data {
18✔
388
                        Float.PutMat2(b[e*i:], data[i])
12✔
389
                }
12✔
390
        case [][3][3]float32:
6✔
391
                for i := range data {
18✔
392
                        Float.PutMat3(b[e*i:], data[i])
12✔
393
                }
12✔
394
        case [][4][4]float32:
6✔
395
                for i := range data {
18✔
396
                        Float.PutMat4(b[e*i:], data[i])
12✔
397
                }
12✔
398
        case []uint32:
12✔
399
                for i := range data {
42✔
400
                        Uint.PutScalar(b[e*i:], data[i])
30✔
401
                }
30✔
402
        case [][2]uint32:
6✔
403
                for i := range data {
18✔
404
                        Uint.PutVec2(b[e*i:], data[i])
12✔
405
                }
12✔
406
        case [][3]uint32:
6✔
407
                for i := range data {
18✔
408
                        Uint.PutVec3(b[e*i:], data[i])
12✔
409
                }
12✔
410
        case [][4]uint32:
6✔
411
                for i := range data {
18✔
412
                        Uint.PutVec4(b[e*i:], data[i])
12✔
413
                }
12✔
414
        case [][2][2]uint32:
6✔
415
                for i := range data {
18✔
416
                        Uint.PutMat2(b[e*i:], data[i])
12✔
417
                }
12✔
418
        case [][3][3]uint32:
6✔
419
                for i := range data {
18✔
420
                        Uint.PutMat3(b[e*i:], data[i])
12✔
421
                }
12✔
422
        case [][4][4]uint32:
6✔
423
                for i := range data {
18✔
424
                        Uint.PutMat4(b[e*i:], data[i])
12✔
425
                }
12✔
426
        }
427
        return nil
312✔
428
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc