1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 13:22:58 +03:00

Merge pull request #557 from wader/mp3-max-unknown-opt

mp3: Add max_unknown option to fail decode if too much unknown bits
This commit is contained in:
Mattias Wadman 2023-01-25 16:00:49 +01:00 committed by GitHub
commit 0d1fdb5edf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 642 additions and 608 deletions

View File

@ -695,17 +695,18 @@ $ fq 'grep_by(.id == "Tracks") | matroska_path' file.mkv
|- |- |-|
|`max_sync_seek` |32768 |Max byte distance to next sync|
|`max_unique_header_configs`|5 |Max number of unique frame header configs allowed|
|`max_unknown` |50 |Max percent (0-100) unknown bits|
### Examples
Decode file using mp3 options
```
$ fq -d mp3 -o max_sync_seek=32768 -o max_unique_header_configs=5 . file
$ fq -d mp3 -o max_sync_seek=32768 -o max_unique_header_configs=5 -o max_unknown=50 . file
```
Decode value as mp3
```
... | mp3({max_sync_seek:32768,max_unique_header_configs:5})
... | mp3({max_sync_seek:32768,max_unique_header_configs:5,max_unknown:50})
```
## mp4

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 141 KiB

After

Width:  |  Height:  |  Size: 140 KiB

View File

@ -224,6 +224,7 @@ type AACFrameIn struct {
type Mp3In struct {
MaxUniqueHeaderConfigs int `doc:"Max number of unique frame header configs allowed"`
MaxUnknown int `doc:"Max percent (0-100) unknown bits"`
MaxSyncSeek int `doc:"Max byte distance to next sync"`
}

View File

@ -23,6 +23,7 @@ func init() {
DecodeFn: mp3Decode,
DecodeInArg: format.Mp3In{
MaxUniqueHeaderConfigs: 5,
MaxUnknown: 50,
MaxSyncSeek: 4 * 1024 * 8,
},
Dependencies: []decode.Dependency{
@ -53,13 +54,16 @@ func mp3Decode(d *decode.D, in any) any {
ChannelModeIndex int
}
uniqueHeaderConfigs := map[headerConfig]struct{}{}
knownSize := int64(0)
// there are mp3s files in the wild with multiple headers, two id3v2 tags etc
d.FieldArray("headers", func(d *decode.D) {
for d.NotEnd() {
headerStart := d.Pos()
if dv, _, _ := d.TryFieldFormat("header", headerFormat, nil); dv == nil {
return
}
knownSize += d.Pos() - headerStart
}
})
@ -80,6 +84,7 @@ func mp3Decode(d *decode.D, in any) any {
d.SeekRel(syncLen)
}
frameStart := d.Pos()
dv, v, _ := d.TryFieldFormat("frame", mp3Frame, nil)
if dv == nil {
decodeFailures++
@ -90,6 +95,7 @@ func mp3Decode(d *decode.D, in any) any {
if !ok {
panic(fmt.Sprintf("expected MP3FrameOut got %#+v", v))
}
knownSize += d.Pos() - frameStart
uniqueHeaderConfigs[headerConfig{
MPEGVersion: mfo.MPEGVersion,
ProtectionAbsent: mfo.ProtectionAbsent,
@ -115,11 +121,18 @@ func mp3Decode(d *decode.D, in any) any {
d.FieldArray("footers", func(d *decode.D) {
for d.NotEnd() {
footerStart := d.Pos()
if dv, _, _ := d.TryFieldFormat("footer", footerFormat, nil); dv == nil {
return
}
knownSize += d.Pos() - footerStart
}
})
unknownPercent := int(float64((d.Len() - knownSize)) / float64(d.Len()) * 100.0)
if unknownPercent > mi.MaxUnknown {
d.Errorf(fmt.Sprintf("exceeds max precent unknown bits, %d > %d", unknownPercent, mi.MaxUnknown))
}
return nil
}

View File

@ -6,6 +6,7 @@ Options
max_sync_seek=32768 Max byte distance to next sync
max_unique_header_configs=5 Max number of unique frame header configs allowed
max_unknown=50 Max percent (0-100) unknown bits
Decode examples
===============
@ -15,7 +16,7 @@ Decode examples
# Decode value as mp3
... | mp3
# Decode file using mp3 options
$ fq -d mp3 -o max_sync_seek=32768 -o max_unique_header_configs=5 . file
$ fq -d mp3 -o max_sync_seek=32768 -o max_unique_header_configs=5 -o max_unknown=50 . file
# Decode value as mp3
... | mp3({max_sync_seek:32768,max_unique_header_configs:5})
... | mp3({max_sync_seek:32768,max_unique_header_configs:5,max_unknown:50})

View File

@ -1,11 +1,29 @@
# fq '"aaaa", .frames[0], "bbbb", .frames[0], "ccccc" | tobytes' test.mp3 > unknown.mp3
# ffmpeg -f lavfi -i sine -t 10ms test.mp3
# fq '"aaaaa"*100, .frames[0], "bbbbb", .frames[0], "ccccc"*100 | tobytes' test.mp3 > unknown.mp3
$ fq -d mp3 . unknown.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: unknown.mp3 (mp3)
| | | error: mp3: error at position 0x365: exceeds max precent unknown bits, 73 > 50
| | | headers[0:0]:
0x000|61 61 61 61 |aaaa | gap0: raw bits
0x000| ff fb 90 64 00 00 02 6b 0b ce 9d 60| ...d...k...`| frames[0:2]:
0x010|60 00 00 00 0d 20 a0 00 01 18 c9 99 51 b9 a7 80|`.... ......Q...|
* |until 0x349.7 (838) | |
0x1a0| 62 62 62 62 | bbbb | gap1: raw bits
0x000|61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|aaaaaaaaaaaaaaaa| gap0: raw bits
* |until 0x1f3.7 (500) | |
0x1f0| ff fb 40 c0 00 00 00 00 00 00 00 00| ..@.........| frames[0:2]:
0x200|00 00 00 00 00 00 00 00 00 49 6e 66 6f 00 00 00|.........Info...|
* |until 0x364.7 (369) | |
0x2a0| 62 62 62 62 62 | bbbbb | gap1: raw bits
| | | footers[0:0]:
0x340| 63 63 63 63 63| | ccccc|| gap2: raw bits
0x360| 63 63 63 63 63 63 63 63 63 63 63| ccccccccccc| gap2: raw bits
0x370|63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63|cccccccccccccccc|
* |until 0x558.7 (end) (500) | |
$ fq -o max_unknown=73 -d mp3 . unknown.mp3
|00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.{}: unknown.mp3 (mp3)
| | | headers[0:0]:
0x000|61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|aaaaaaaaaaaaaaaa| gap0: raw bits
* |until 0x1f3.7 (500) | |
0x1f0| ff fb 40 c0 00 00 00 00 00 00 00 00| ..@.........| frames[0:2]:
0x200|00 00 00 00 00 00 00 00 00 49 6e 66 6f 00 00 00|.........Info...|
* |until 0x364.7 (369) | |
0x2a0| 62 62 62 62 62 | bbbbb | gap1: raw bits
| | | footers[0:0]:
0x360| 63 63 63 63 63 63 63 63 63 63 63| ccccccccccc| gap2: raw bits
0x370|63 63 63 63 63 63 63 63 63 63 63 63 63 63 63 63|cccccccccccccccc|
* |until 0x558.7 (end) (500) | |

Binary file not shown.