@@ -8,16 +8,17 @@ import (
88 "os"
99)
1010
11- // 算术编码 Go 实现。
12- // 文件格式与 C++ 实现完全一致,支持交叉编解码验证。
11+ // Arithmetic coding Go implementation.
12+ // File format is fully compatible with C++ implementation, supports cross-language encode/decode verification.
1313// Magic: AENC (4 bytes)
14- // 频率表 : count(4 bytes LE) + count × freq(4 bytes LE)
15- // 算术编码比特流
14+ // Frequency table : count(4 bytes LE) + count × freq(4 bytes LE)
15+ // Arithmetic coding bitstream
1616
1717const (
18- SymbolLimit = 257
19- EOFSymbol = SymbolLimit - 1
20- MaxTotal = uint32 (1 ) << 24
18+ SymbolLimit = 257
19+ EOFSymbol = SymbolLimit - 1
20+ MaxTotal = uint32 (1 ) << 24
21+ MaxInputSize = 4 * 1024 * 1024 * 1024 // 4 GiB max to prevent frequency overflow
2122
2223 stateBits = 32
2324 fullRange = uint64 (1 ) << stateBits
@@ -240,7 +241,7 @@ func (d *ArithmeticDecoder) DecodeSymbol(cumulative []uint32) uint32 {
240241}
241242
242243// ---------------------------------------------------------------------------
243- // 频率表处理
244+ // Frequency table processing
244245// ---------------------------------------------------------------------------
245246
246247func scaleFrequencies (freq []uint32 ) {
@@ -284,9 +285,19 @@ func buildFrequenciesFromFile(path string) ([]uint32, error) {
284285 freq := make ([]uint32 , SymbolLimit )
285286 f , err := os .Open (path )
286287 if err != nil {
287- return nil , fmt .Errorf ("无法打开输入文件用于读取 : %s: %w" , path , err )
288+ return nil , fmt .Errorf ("cannot open input file for reading : %s: %w" , path , err )
288289 }
289290 defer f .Close ()
291+
292+ // Check file size to prevent frequency overflow
293+ stat , err := f .Stat ()
294+ if err != nil {
295+ return nil , fmt .Errorf ("cannot stat input file: %w" , err )
296+ }
297+ if stat .Size () > MaxInputSize {
298+ return nil , fmt .Errorf ("input file too large (max %d bytes)" , MaxInputSize )
299+ }
300+
290301 r := bufio .NewReader (f )
291302 for {
292303 b , err := r .ReadByte ()
@@ -329,20 +340,20 @@ func writeFrequencies(w io.Writer, freq []uint32) error {
329340func readFrequencies (r io.Reader ) ([]uint32 , error ) {
330341 var count uint32
331342 if err := binary .Read (r , binary .LittleEndian , & count ); err != nil {
332- return nil , fmt .Errorf ("读取频率表失败 : %w" , err )
343+ return nil , fmt .Errorf ("failed to read frequency table : %w" , err )
333344 }
334345 if count != uint32 (SymbolLimit ) {
335- return nil , fmt .Errorf ("频率表大小异常 : %d" , count )
346+ return nil , fmt .Errorf ("invalid frequency table size : %d" , count )
336347 }
337348 freq := make ([]uint32 , count )
338349 if err := binary .Read (r , binary .LittleEndian , freq ); err != nil {
339- return nil , fmt .Errorf ("读取频率表失败 : %w" , err )
350+ return nil , fmt .Errorf ("failed to read frequency table : %w" , err )
340351 }
341352 return freq , nil
342353}
343354
344355// ---------------------------------------------------------------------------
345- // 压缩 / 解压
356+ // Compression / Decompression
346357// ---------------------------------------------------------------------------
347358
348359func compressFile (inputPath , outputPath string ) error {
@@ -354,13 +365,13 @@ func compressFile(inputPath, outputPath string) error {
354365
355366 inFile , err := os .Open (inputPath )
356367 if err != nil {
357- return fmt .Errorf ("无法打开输入文件用于读取 : %s: %w" , inputPath , err )
368+ return fmt .Errorf ("cannot open input file for reading : %s: %w" , inputPath , err )
358369 }
359370 defer inFile .Close ()
360371
361372 outFile , err := os .Create (outputPath )
362373 if err != nil {
363- return fmt .Errorf ("无法打开输出文件用于写入 : %s: %w" , outputPath , err )
374+ return fmt .Errorf ("cannot open output file for writing : %s: %w" , outputPath , err )
364375 }
365376 defer outFile .Close ()
366377
@@ -381,7 +392,7 @@ func compressFile(inputPath, outputPath string) error {
381392 break
382393 }
383394 if err != nil {
384- return fmt .Errorf ("读取输入文件失败 : %w" , err )
395+ return fmt .Errorf ("failed to read input file : %w" , err )
385396 }
386397 if err := encoder .EncodeSymbol (uint32 (b ), cumulative ); err != nil {
387398 return err
@@ -396,14 +407,14 @@ func compressFile(inputPath, outputPath string) error {
396407func decompressFile (inputPath , outputPath string ) error {
397408 inFile , err := os .Open (inputPath )
398409 if err != nil {
399- return fmt .Errorf ("无法打开输入文件用于读取 : %s: %w" , inputPath , err )
410+ return fmt .Errorf ("cannot open input file for reading : %s: %w" , inputPath , err )
400411 }
401412 defer inFile .Close ()
402413 r := bufio .NewReader (inFile )
403414
404415 magic := make ([]byte , 4 )
405416 if _ , err := io .ReadFull (r , magic ); err != nil || magic [0 ] != 'A' || magic [1 ] != 'E' || magic [2 ] != 'N' || magic [3 ] != 'C' {
406- return fmt .Errorf ("输入文件格式非法 " )
417+ return fmt .Errorf ("invalid input file format " )
407418 }
408419
409420 freq , err := readFrequencies (r )
@@ -414,7 +425,7 @@ func decompressFile(inputPath, outputPath string) error {
414425
415426 outFile , err := os .Create (outputPath )
416427 if err != nil {
417- return fmt .Errorf ("无法打开输出文件用于写入 : %s: %w" , outputPath , err )
428+ return fmt .Errorf ("cannot open output file for writing : %s: %w" , outputPath , err )
418429 }
419430 defer outFile .Close ()
420431 w := bufio .NewWriter (outFile )
@@ -451,7 +462,7 @@ func main() {
451462 } else if mode == "decode" {
452463 err = decompressFile (inputPath , outputPath )
453464 } else {
454- fmt .Fprintln (os .Stderr , "未知模式,应为 encode 或 decode" )
465+ fmt .Fprintln (os .Stderr , "unknown mode, expected encode or decode" )
455466 os .Exit (1 )
456467 }
457468 if err != nil {
0 commit comments