frameworks/av
Revision | 7e354f50d3017c8b392c8e10ed940984473e5af1 (tree) |
---|---|
Time | 2015-09-29 08:27:08 |
Author | Wonsik Kim <wonsik@goog...> |
Commiter | The Android Automerger |
Ogg: avoid size_t overflow in base64 decoding
Bug: 23707088
Change-Id: I8d32841fee3213c721cdcc57788807ea64d19d74
@@ -893,11 +893,14 @@ static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) { | ||
893 | 893 | } |
894 | 894 | } |
895 | 895 | |
896 | - size_t outLen = 3 * size / 4 - padding; | |
897 | - | |
898 | - *outSize = outLen; | |
896 | + // We divide first to avoid overflow. It's OK to do this because we | |
897 | + // already made sure that size % 4 == 0. | |
898 | + size_t outLen = (size / 4) * 3 - padding; | |
899 | 899 | |
900 | 900 | void *buffer = malloc(outLen); |
901 | + if (buffer == NULL) { | |
902 | + return NULL; | |
903 | + } | |
901 | 904 | |
902 | 905 | uint8_t *out = (uint8_t *)buffer; |
903 | 906 | size_t j = 0; |
@@ -916,10 +919,10 @@ static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) { | ||
916 | 919 | } else if (c == '/') { |
917 | 920 | value = 63; |
918 | 921 | } else if (c != '=') { |
919 | - return NULL; | |
922 | + break; | |
920 | 923 | } else { |
921 | 924 | if (i < n - padding) { |
922 | - return NULL; | |
925 | + break; | |
923 | 926 | } |
924 | 927 | |
925 | 928 | value = 0; |
@@ -937,6 +940,13 @@ static uint8_t *DecodeBase64(const char *s, size_t size, size_t *outSize) { | ||
937 | 940 | } |
938 | 941 | } |
939 | 942 | |
943 | + // Check if we exited the loop early. | |
944 | + if (j < outLen) { | |
945 | + free(buffer); | |
946 | + return NULL; | |
947 | + } | |
948 | + | |
949 | + *outSize = outLen; | |
940 | 950 | return (uint8_t *)buffer; |
941 | 951 | } |
942 | 952 |