mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
stream.[ch], ass_mp: new stream function for whole-file reads
Add new stream_read_complete() function which reads the complete contents of file. Use that in ass_mp.c which had custom code to do the same.
This commit is contained in:
@@ -29,6 +29,8 @@
|
||||
#include <fcntl.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "talloc.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if HAVE_WINSOCK2_H
|
||||
@@ -658,3 +660,35 @@ unsigned char* stream_read_line(stream_t *s,unsigned char* mem, int max, int utf
|
||||
if(s->eof && ptr == mem) return NULL;
|
||||
return mem;
|
||||
}
|
||||
|
||||
struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
|
||||
int max_size, int padding_bytes)
|
||||
{
|
||||
if (max_size > 1000000000)
|
||||
abort();
|
||||
|
||||
int bufsize;
|
||||
int total_read = 0;
|
||||
int padding = FFMAX(padding_bytes, 1);
|
||||
char *buf = NULL;
|
||||
if (s->end_pos > max_size)
|
||||
return (struct bstr){NULL, 0};
|
||||
if (s->end_pos > 0)
|
||||
bufsize = s->end_pos + padding;
|
||||
else
|
||||
bufsize = 1000;
|
||||
while (1) {
|
||||
buf = talloc_realloc_size(talloc_ctx, buf, bufsize);
|
||||
int readsize = stream_read(s, buf + total_read, bufsize - total_read);
|
||||
total_read += readsize;
|
||||
if (total_read < bufsize)
|
||||
break;
|
||||
if (bufsize > max_size) {
|
||||
talloc_free(buf);
|
||||
return (struct bstr){NULL, 0};
|
||||
}
|
||||
bufsize = FFMIN(bufsize + (bufsize >> 1), max_size + padding);
|
||||
}
|
||||
buf = talloc_realloc_size(talloc_ctx, buf, total_read + padding);
|
||||
return (struct bstr){buf, total_read};
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "bstr.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
@@ -331,6 +333,14 @@ inline static int stream_skip(stream_t *s,off_t len){
|
||||
}
|
||||
|
||||
struct MPOpts;
|
||||
/*
|
||||
* Return allocated buffer for all data until EOF.
|
||||
* If amount of data would be more than max_size return NULL as data ptr.
|
||||
* Make the allocated buffer padding_bytes larger than the data read.
|
||||
* Write number of bytes read at *amount_read.
|
||||
*/
|
||||
struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
|
||||
int max_size, int padding_bytes);
|
||||
void stream_reset(stream_t *s);
|
||||
int stream_control(stream_t *s, int cmd, void *arg);
|
||||
stream_t* new_stream(int fd,int type);
|
||||
|
||||
46
sub/ass_mp.c
46
sub/ass_mp.c
@@ -233,50 +233,28 @@ ASS_Track *mp_ass_read_subdata(ASS_Library *library, sub_data *subdata,
|
||||
ASS_Track *mp_ass_read_stream(ASS_Library *library, const char *fname,
|
||||
char *charset)
|
||||
{
|
||||
int i;
|
||||
char *buf = NULL;
|
||||
ASS_Track *track;
|
||||
size_t sz = 0;
|
||||
size_t buf_alloc = 0;
|
||||
stream_t *fd;
|
||||
|
||||
fd = open_stream(fname, NULL, NULL);
|
||||
if (!fd)
|
||||
struct stream *s = open_stream(fname, NULL, NULL);
|
||||
if (!s)
|
||||
// Stream code should have printed an error already
|
||||
return NULL;
|
||||
if (fd->end_pos > STREAM_BUFFER_SIZE)
|
||||
/* read entire file if size is known */
|
||||
buf_alloc = fd->end_pos;
|
||||
else
|
||||
buf_alloc = 1000;
|
||||
for (;;) {
|
||||
if (sz > 100000000) {
|
||||
mp_tmsg(MSGT_ASS, MSGL_ERR, "Refusing to load subtitle file "
|
||||
"larger than 100 MB: %s\n", fname);
|
||||
sz = 0;
|
||||
break;
|
||||
}
|
||||
buf_alloc = FFMAX(buf_alloc, sz + (sz >> 1));
|
||||
buf_alloc = FFMIN(buf_alloc, 100000001);
|
||||
buf = realloc(buf, buf_alloc + 1);
|
||||
i = stream_read(fd, buf + sz, buf_alloc - sz);
|
||||
if (i <= 0)
|
||||
break;
|
||||
sz += i;
|
||||
}
|
||||
free_stream(fd);
|
||||
if (!sz) {
|
||||
free(buf);
|
||||
struct bstr content = stream_read_complete(s, NULL, 100000000, 1);
|
||||
if (content.start == NULL)
|
||||
mp_tmsg(MSGT_ASS, MSGL_ERR, "Refusing to load subtitle file "
|
||||
"larger than 100 MB: %s\n", fname);
|
||||
free_stream(s);
|
||||
if (content.len == 0) {
|
||||
talloc_free(content.start);
|
||||
return NULL;
|
||||
}
|
||||
buf[sz] = 0;
|
||||
buf = realloc(buf, sz + 1);
|
||||
track = ass_read_memory(library, buf, sz, charset);
|
||||
content.start[content.len] = 0;
|
||||
track = ass_read_memory(library, content.start, content.len, charset);
|
||||
if (track) {
|
||||
free(track->name);
|
||||
track->name = strdup(fname);
|
||||
}
|
||||
free(buf);
|
||||
talloc_free(content.start);
|
||||
return track;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user