Changeset 003c413 in mainline


Ignore:
Timestamp:
2020-09-19T18:55:28Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d145ecb
Parents:
0ee3157
Message:

RIFF reader should heed parent chunk bounds when starting child chunk

Location:
uspace/lib/riff
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/riff/include/riff/chunk.h

    r0ee3157 r003c413  
    4848extern errno_t riff_write_uint32(riffw_t *, uint32_t);
    4949
    50 extern errno_t riff_ropen(const char *, riffr_t **);
     50extern errno_t riff_ropen(const char *, riff_rchunk_t *, riffr_t **);
    5151extern errno_t riff_rclose(riffr_t *);
    52 extern errno_t riff_read_uint32(riffr_t *, uint32_t *);
    53 extern errno_t riff_rchunk_start(riffr_t *, riff_rchunk_t *);
    54 extern errno_t riff_rchunk_end(riffr_t *, riff_rchunk_t *);
    55 extern errno_t riff_rchunk_read(riffr_t *, riff_rchunk_t *, void *, size_t,
    56     size_t *);
     52extern errno_t riff_read_uint32(riff_rchunk_t *, uint32_t *);
     53extern errno_t riff_rchunk_start(riff_rchunk_t *, riff_rchunk_t *);
     54extern errno_t riff_rchunk_end(riff_rchunk_t *);
     55extern errno_t riff_read(riff_rchunk_t *, void *, size_t, size_t *);
    5756
    5857#endif
  • uspace/lib/riff/include/types/riff/chunk.h

    r0ee3157 r003c413  
    4343typedef uint32_t riff_cksize_t;
    4444
     45/** RIFF writer */
     46typedef struct {
     47        FILE *f;
     48        /** Chunk start offset */
     49        long ckstart;
     50} riffw_t;
     51
     52/** RIFF reader */
     53typedef struct {
     54        FILE *f;
     55} riffr_t;
     56
    4557/** RIFF chunk for reading */
    4658typedef struct {
     59        riffr_t *riffr;
    4760        long ckstart;
    4861        riff_ckid_t ckid;
     
    6174        riff_cksize_t cksize;
    6275} riff_ckinfo_t;
    63 
    64 /** RIFF writer */
    65 typedef struct {
    66         FILE *f;
    67         /** Chunk start offset */
    68         long ckstart;
    69 } riffw_t;
    70 
    71 /** RIFF reader */
    72 typedef struct {
    73         FILE *f;
    74 } riffr_t;
    7576
    7677enum {
  • uspace/lib/riff/src/chunk.c

    r0ee3157 r003c413  
    117117                return EIO;
    118118
    119         wchunk->ckstart = pos;
     119        wchunk->ckstart = pos + 2 * sizeof(uint32_t);
    120120
    121121        rc = riff_write_uint32(rw, ckid);
     
    151151                return EIO;
    152152
    153         cksize = pos - wchunk->ckstart - 8;
    154 
    155         if (fseek(rw->f, wchunk->ckstart + 4, SEEK_SET) < 0)
     153        cksize = pos - wchunk->ckstart;
     154
     155        if (fseek(rw->f, wchunk->ckstart - 4, SEEK_SET) < 0)
    156156                return EIO;
    157157
     
    190190 *
    191191 * @param fname File name
     192 * @param riffck Place to store root (RIFF) chunk
    192193 * @param rrr   Place to store pointer to RIFF reader
    193194 *
     
    195196 *         file..
    196197 */
    197 errno_t riff_ropen(const char *fname, riffr_t **rrr)
     198errno_t riff_ropen(const char *fname, riff_rchunk_t *riffck, riffr_t **rrr)
    198199{
    199200        riffr_t *rr;
    200         errno_t rc;
     201        riff_rchunk_t fchunk;
     202        long fsize;
     203        errno_t rc;
     204        int rv;
    201205
    202206        rr = calloc(1, sizeof(riffr_t));
     
    211215                goto error;
    212216        }
     217
     218        rv = fseek(rr->f, 0, SEEK_END);
     219        if (rv < 0) {
     220                rc = EIO;
     221                goto error;
     222        }
     223
     224        fsize = ftell(rr->f);
     225        if (fsize < 0) {
     226                rc = EIO;
     227                goto error;
     228        }
     229
     230        rv = fseek(rr->f, 0, SEEK_SET);
     231        if (rv < 0) {
     232                rc = EIO;
     233                goto error;
     234        }
     235
     236        fchunk.riffr = rr;
     237        fchunk.ckstart = 0;
     238        fchunk.cksize = fsize;
     239
     240        rc = riff_rchunk_start(&fchunk, riffck);
     241        if (rc != EOK)
     242                goto error;
    213243
    214244        *rrr = rr;
     
    237267/** Read uint32_t from RIFF file.
    238268 *
    239  * @param rr RIFF reader
     269 * @param rchunk RIFF chunk
    240270 * @param v  Place to store value
    241271 * @return EOK on success, EIO on error.
    242272 */
    243 errno_t riff_read_uint32(riffr_t *rr, uint32_t *v)
     273errno_t riff_read_uint32(riff_rchunk_t *rchunk, uint32_t *v)
    244274{
    245275        uint32_t vle;
    246 
    247         if (fread(&vle, 1, sizeof(vle), rr->f) < sizeof(vle))
    248                 return EIO;
     276        errno_t rc;
     277        size_t nread;
     278
     279        rc = riff_read(rchunk, &vle, sizeof(vle), &nread);
     280        if (rc != EOK)
     281                return rc;
    249282
    250283        *v = uint32_t_le2host(vle);
     
    254287/** Start reading RIFF chunk.
    255288 *
    256  * @param rr     RIFF reader
     289 * @param parent Parent chunk
    257290 * @param rchunk Pointer to chunk structure to fill in
    258291 *
    259292 * @return EOK on success, EIO on error.
    260293 */
    261 errno_t riff_rchunk_start(riffr_t *rr, riff_rchunk_t *rchunk)
     294errno_t riff_rchunk_start(riff_rchunk_t *parent, riff_rchunk_t *rchunk)
    262295{
    263296        errno_t rc;
    264297        long pos;
    265298
    266         pos = ftell(rr->f);
     299        pos = ftell(parent->riffr->f);
    267300        if (pos < 0) {
    268301                rc = EIO;
     
    270303        }
    271304
    272         rchunk->ckstart = pos;
    273         rc = riff_read_uint32(rr, &rchunk->ckid);
     305        rchunk->riffr = parent->riffr;
     306        rchunk->ckstart = pos + 8;
     307        rc = riff_read_uint32(parent, &rchunk->ckid);
    274308        if (rc != EOK)
    275309                goto error;
    276         rc = riff_read_uint32(rr, &rchunk->cksize);
     310        rc = riff_read_uint32(parent, &rchunk->cksize);
    277311        if (rc != EOK)
    278312                goto error;
     
    290324static long riff_rchunk_get_end(riff_rchunk_t *rchunk)
    291325{
    292         return rchunk->ckstart + 8 + rchunk->cksize;
     326        return rchunk->ckstart + rchunk->cksize;
    293327}
    294328
     
    313347 * Seek to the first byte after end of chunk.
    314348 *
    315  * @param rr     RIFF reader
    316349 * @param rchunk Chunk structure
    317350 * @return EOK on success, EIO on error.
    318351 */
    319 errno_t riff_rchunk_end(riffr_t *rr, riff_rchunk_t *rchunk)
     352errno_t riff_rchunk_end(riff_rchunk_t *rchunk)
    320353{
    321354        long ckend;
    322355
    323356        ckend = riff_rchunk_get_ndpos(rchunk);
    324         if (fseek(rr->f, ckend, SEEK_SET) < 0)
    325                 return EIO;
    326 
     357        if (fseek(rchunk->riffr->f, ckend, SEEK_SET) < 0)
     358                return EIO;
     359
     360        rchunk->riffr = NULL;
    327361        return EOK;
    328362}
     
    334368 * of bytes read is returned in @a *nbytes (can even be 0).
    335369 *
    336  * @param rr RIFF reader
    337  * @param rchunk RIFF chunk
     370 * @param rchunk RIFF chunk for reading
    338371 * @param buf Buffer to read to
    339372 * @param bytes Number of bytes to read
     
    343376 *         EIO on I/O error.
    344377 */
    345 errno_t riff_rchunk_read(riffr_t *rr, riff_rchunk_t *rchunk, void *buf,
    346     size_t bytes, size_t *nread)
     378errno_t riff_read(riff_rchunk_t *rchunk, void *buf, size_t bytes,
     379    size_t *nread)
    347380{
    348381        long pos;
     
    350383        long toread;
    351384
    352         pos = ftell(rr->f);
     385        pos = ftell(rchunk->riffr->f);
    353386        if (pos < 0)
    354387                return EIO;
     
    364397        }
    365398
    366         *nread = fread(buf, 1, toread, rr->f);
     399        *nread = fread(buf, 1, toread, rchunk->riffr->f);
    367400        if (*nread == 0)
    368401                return EIO;
  • uspace/lib/riff/src/rwave.c

    r0ee3157 r003c413  
    255255        }
    256256
    257         rc = riff_ropen(fname, &wr->rr);
     257        rc = riff_ropen(fname, &wr->wave, &wr->rr);
    258258        if (rc != EOK) {
    259259                assert(rc == EIO || rc == ENOMEM);
     
    261261        }
    262262
    263         rc = riff_rchunk_start(wr->rr, &wr->wave);
    264         if (rc != EOK) {
    265                 assert(rc == EIO);
    266                 goto error;
    267         }
    268 
    269         rc = riff_read_uint32(wr->rr, &form_id);
     263        if (wr->wave.ckid != CKID_RIFF) {
     264                printf("Not RIFF file\n");
     265                rc = ENOMEM;
     266                goto error;
     267        }
     268
     269        rc = riff_read_uint32(&wr->wave, &form_id);
    270270        if (rc != EOK) {
    271271                assert(rc == EIO);
     
    279279        }
    280280
    281         rc = riff_rchunk_start(wr->rr, &fmt);
     281        rc = riff_rchunk_start(&wr->wave, &fmt);
    282282        if (rc != EOK) {
    283283                assert(rc == EIO);
     
    291291        }
    292292
    293         rc = riff_rchunk_read(wr->rr, &fmt, &wfmt, sizeof(rwave_fmt_t), &nread);
     293        rc = riff_read(&fmt, &wfmt, sizeof(rwave_fmt_t), &nread);
    294294        if (rc != EOK) {
    295295                printf("error reading fmt chunk\n");
     
    304304        }
    305305
    306         rc = riff_rchunk_end(wr->rr, &fmt);
     306        rc = riff_rchunk_end(&fmt);
    307307        if (rc != EOK) {
    308308                assert(rc == EIO);
     
    318318        }
    319319
    320         rc = riff_rchunk_start(wr->rr, &wr->data);
     320        rc = riff_rchunk_start(&wr->wave, &wr->data);
    321321        if (rc != EOK) {
    322322                assert(rc == EIO);
     
    353353        errno_t rc;
    354354
    355         rc = riff_rchunk_read(wr->rr, &wr->data, buf, bytes, nread);
     355        rc = riff_read(&wr->data, buf, bytes, nread);
    356356        if (rc != EOK) {
    357357                assert(rc == EIO || rc == ELIMIT);
     
    373373        errno_t rc;
    374374
    375         rc = riff_rchunk_end(wr->rr, &wr->wave);
     375        rc = riff_rchunk_end(&wr->wave);
    376376        if (rc != EOK) {
    377377                assert(rc == EIO);
Note: See TracChangeset for help on using the changeset viewer.