int oggz_comments_decode (OGGZ * oggz, long serialno, unsigned char * comments, long length) { oggz_stream_t * stream; char *c= (char *)comments; int len, i, nb_fields, n; char *end; char * name, * value, * nvalue = NULL; OggzComment * comment; if (length<8) return -1; end = c+length; len=readint(c, 0); c+=4; if (c+len>end) return -1; stream = oggz_get_stream (oggz, serialno); if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO; /* Vendor */ nvalue = oggz_strdup_len (c, len); if (!nvalue) return -1; _oggz_comment_set_vendor (oggz, serialno, nvalue); if (nvalue) oggz_free (nvalue); #ifdef DEBUG fwrite(c, 1, len, stderr); fputc ('\n', stderr); #endif c+=len; if (c+4>end) return -1; nb_fields=readint(c, 0); c+=4; for (i=0; i<nb_fields; i++) { if (c+4>end) return -1; len=readint(c, 0); c+=4; if (c+len>end) return -1; name = c; value = oggz_index_len (c, '=', len); if (value) { *value = '\0'; value++; n = c+len - value; nvalue = oggz_strdup_len (value, n); #ifdef DEBUG printf ("oggz_comments_decode: %s -> %s (length %d)\n", name, nvalue, n); #endif comment = oggz_comment_new (name, nvalue); _oggz_comment_add (stream, comment); oggz_free (nvalue); } else { nvalue = oggz_strdup_len (name, len); comment = oggz_comment_new (nvalue, NULL); _oggz_comment_add (stream, comment); oggz_free (nvalue); } c+=len; } #ifdef DEBUG printf ("oggz_comments_decode: done\n"); #endif return 0; }
int oggz_comments_decode (OGGZ * oggz, long serialno, unsigned char * comments, long length) { oggz_stream_t * stream; char *c= (char *)comments; int i, nb_fields, n; size_t len; char *end; char * name, * value, * nvalue = NULL; OggzComment * comment; if (length<8) return -1; end = c+length; len=readint(c, 0); c+=4; if (len>(size_t)(end-c)) return -1; stream = oggz_get_stream (oggz, serialno); if (stream == NULL) return OGGZ_ERR_BAD_SERIALNO; /* Vendor */ if (len > 0) { if ((nvalue = oggz_strdup_len (c, len)) == NULL) return OGGZ_ERR_OUT_OF_MEMORY; if (_oggz_comment_set_vendor (oggz, serialno, nvalue) == OGGZ_ERR_OUT_OF_MEMORY) { oggz_free (nvalue); return OGGZ_ERR_OUT_OF_MEMORY; } oggz_free (nvalue); } #ifdef DEBUG fwrite(c, 1, len, stderr); fputc ('\n', stderr); #endif c+=len; if (c+4>end) return -1; /* This value gets checked effectively by the 'for' condition and the checks within the loop for c running off the end. */ nb_fields=readint(c, 0); c+=4; for (i=0;i<nb_fields;i++) { if (c+4>end) return -1; len=readint(c, 0); c+=4; if (len>(size_t)(end-c)) return -1; n = 0; name = c; value = oggz_index_len (c, '=', len); if (value) { *value = '\0'; value++; n = c+len - value; } if (n != 0) { if ((nvalue = oggz_strdup_len (value, n)) == NULL) return OGGZ_ERR_OUT_OF_MEMORY; #ifdef DEBUG printf ("oggz_comments_decode: [%d] %s -> %s (length %d)\n", i, name, nvalue, n); #endif if (_oggz_comment_add_byname (stream, name, nvalue) == NULL) { oggz_free (nvalue); return OGGZ_ERR_OUT_OF_MEMORY; } oggz_free (nvalue); } else { /* For the case of a comment which is not in key=value form, * duplicate exactly the length of the comment, as it is * not NUL-terminated. In the case of the last comment of the * packet, it will be followed immediately by a framing bit. */ if ((nvalue = oggz_strdup_len (name, len)) == NULL) return OGGZ_ERR_OUT_OF_MEMORY; #ifdef DEBUG printf ("oggz_comments_decode: [%d] %s (no value) (length %d)\n", i, nvalue, len); #endif if (_oggz_comment_add_byname (stream, nvalue, NULL) == NULL) { oggz_free (nvalue); return OGGZ_ERR_OUT_OF_MEMORY; } oggz_free (nvalue); } c+=len; } #ifdef DEBUG printf ("oggz_comments_decode: done\n"); #endif return 0; }