Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | diff --git a/EbmlBufferWriter.c b/EbmlBufferWriter.c |
michael@0 | 2 | index 574e478..8c26e80 100644 |
michael@0 | 3 | --- a/EbmlBufferWriter.c |
michael@0 | 4 | +++ b/EbmlBufferWriter.c |
michael@0 | 5 | @@ -8,6 +8,31 @@ |
michael@0 | 6 | #include <wchar.h> |
michael@0 | 7 | #include <string.h> |
michael@0 | 8 | |
michael@0 | 9 | +void |
michael@0 | 10 | +Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, int buffer_size, unsigned long len) |
michael@0 | 11 | +{ |
michael@0 | 12 | + /* buffer_size: |
michael@0 | 13 | + * 1 - int8_t; |
michael@0 | 14 | + * 2 - int16_t; |
michael@0 | 15 | + * 3 - int32_t; |
michael@0 | 16 | + * 4 - int64_t; |
michael@0 | 17 | + */ |
michael@0 | 18 | + long i; |
michael@0 | 19 | + for(i = len-1; i >= 0; i--) { |
michael@0 | 20 | + unsigned char x; |
michael@0 | 21 | + if (buffer_size == 1) { |
michael@0 | 22 | + x = (char)(*(const int8_t *)buffer_in >> (i * 8)); |
michael@0 | 23 | + } else if (buffer_size == 2) { |
michael@0 | 24 | + x = (char)(*(const int16_t *)buffer_in >> (i * 8)); |
michael@0 | 25 | + } else if (buffer_size == 4) { |
michael@0 | 26 | + x = (char)(*(const int32_t *)buffer_in >> (i * 8)); |
michael@0 | 27 | + } else if (buffer_size == 8) { |
michael@0 | 28 | + x = (char)(*(const int64_t *)buffer_in >> (i * 8)); |
michael@0 | 29 | + } |
michael@0 | 30 | + Ebml_Write(glob, &x, 1); |
michael@0 | 31 | + } |
michael@0 | 32 | +} |
michael@0 | 33 | + |
michael@0 | 34 | void Ebml_Write(EbmlGlobal *glob, const void *buffer_in, unsigned long len) { |
michael@0 | 35 | unsigned char *src = glob->buf; |
michael@0 | 36 | src += glob->offset; |
michael@0 | 37 | @@ -19,12 +44,12 @@ static void _Serialize(EbmlGlobal *glob, const unsigned char *p, const unsigned |
michael@0 | 38 | while (q != p) { |
michael@0 | 39 | --q; |
michael@0 | 40 | |
michael@0 | 41 | - unsigned long cbWritten; |
michael@0 | 42 | memcpy(&(glob->buf[glob->offset]), q, 1); |
michael@0 | 43 | glob->offset++; |
michael@0 | 44 | } |
michael@0 | 45 | } |
michael@0 | 46 | |
michael@0 | 47 | +/* |
michael@0 | 48 | void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len) { |
michael@0 | 49 | // assert(buf); |
michael@0 | 50 | |
michael@0 | 51 | @@ -33,22 +58,22 @@ void Ebml_Serialize(EbmlGlobal *glob, const void *buffer_in, unsigned long len) |
michael@0 | 52 | |
michael@0 | 53 | _Serialize(glob, p, q); |
michael@0 | 54 | } |
michael@0 | 55 | - |
michael@0 | 56 | +*/ |
michael@0 | 57 | |
michael@0 | 58 | void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id) { |
michael@0 | 59 | + unsigned long long unknownLen = 0x01FFFFFFFFFFFFFFLL; |
michael@0 | 60 | Ebml_WriteID(glob, class_id); |
michael@0 | 61 | ebmlLoc->offset = glob->offset; |
michael@0 | 62 | // todo this is always taking 8 bytes, this may need later optimization |
michael@0 | 63 | - unsigned long long unknownLen = 0x01FFFFFFFFFFFFFFLLU; |
michael@0 | 64 | - Ebml_Serialize(glob, (void *)&unknownLen, 8); // this is a key that says lenght unknown |
michael@0 | 65 | + Ebml_Serialize(glob, (void *)&unknownLen,sizeof(unknownLen), 8); // this is a key that says lenght unknown |
michael@0 | 66 | } |
michael@0 | 67 | |
michael@0 | 68 | void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc) { |
michael@0 | 69 | unsigned long long size = glob->offset - ebmlLoc->offset - 8; |
michael@0 | 70 | unsigned long long curOffset = glob->offset; |
michael@0 | 71 | glob->offset = ebmlLoc->offset; |
michael@0 | 72 | - size |= 0x0100000000000000LLU; |
michael@0 | 73 | - Ebml_Serialize(glob, &size, 8); |
michael@0 | 74 | + size |= 0x0100000000000000LL; |
michael@0 | 75 | + Ebml_Serialize(glob, &size,sizeof(size), 8); |
michael@0 | 76 | glob->offset = curOffset; |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | diff --git a/EbmlBufferWriter.h b/EbmlBufferWriter.h |
michael@0 | 80 | index acd5c2a..c135f29 100644 |
michael@0 | 81 | --- a/EbmlBufferWriter.h |
michael@0 | 82 | +++ b/EbmlBufferWriter.h |
michael@0 | 83 | @@ -11,9 +11,7 @@ typedef struct { |
michael@0 | 84 | unsigned int offset; |
michael@0 | 85 | } EbmlGlobal; |
michael@0 | 86 | |
michael@0 | 87 | - |
michael@0 | 88 | void Ebml_StartSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc, unsigned long class_id); |
michael@0 | 89 | void Ebml_EndSubElement(EbmlGlobal *glob, EbmlLoc *ebmlLoc); |
michael@0 | 90 | |
michael@0 | 91 | - |
michael@0 | 92 | #endif |
michael@0 | 93 | diff --git a/EbmlWriter.c b/EbmlWriter.c |
michael@0 | 94 | index 27cfe86..ebefc1a 100644 |
michael@0 | 95 | --- a/EbmlWriter.c |
michael@0 | 96 | +++ b/EbmlWriter.c |
michael@0 | 97 | @@ -74,6 +74,13 @@ void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id) { |
michael@0 | 98 | Ebml_Serialize(glob, (void *)&class_id, sizeof(class_id), len); |
michael@0 | 99 | } |
michael@0 | 100 | |
michael@0 | 101 | +void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, uint32_t ui) { |
michael@0 | 102 | + unsigned char sizeSerialized = 8 | 0x80; |
michael@0 | 103 | + Ebml_WriteID(glob, class_id); |
michael@0 | 104 | + Ebml_Serialize(glob, &sizeSerialized, sizeof(sizeSerialized), 1); |
michael@0 | 105 | + Ebml_Serialize(glob, &ui, sizeof(ui), 4); |
michael@0 | 106 | +} |
michael@0 | 107 | + |
michael@0 | 108 | void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui) { |
michael@0 | 109 | unsigned char sizeSerialized = 8 | 0x80; |
michael@0 | 110 | Ebml_WriteID(glob, class_id); |
michael@0 | 111 | diff --git a/EbmlWriter.h b/EbmlWriter.h |
michael@0 | 112 | index b94f757..a0a848b 100644 |
michael@0 | 113 | --- a/EbmlWriter.h |
michael@0 | 114 | +++ b/EbmlWriter.h |
michael@0 | 115 | @@ -28,6 +28,7 @@ void Ebml_WriteLen(EbmlGlobal *glob, int64_t val); |
michael@0 | 116 | void Ebml_WriteString(EbmlGlobal *glob, const char *str); |
michael@0 | 117 | void Ebml_WriteUTF8(EbmlGlobal *glob, const wchar_t *wstr); |
michael@0 | 118 | void Ebml_WriteID(EbmlGlobal *glob, unsigned long class_id); |
michael@0 | 119 | +void Ebml_SerializeUnsigned32(EbmlGlobal *glob, unsigned long class_id, uint32_t ui); |
michael@0 | 120 | void Ebml_SerializeUnsigned64(EbmlGlobal *glob, unsigned long class_id, uint64_t ui); |
michael@0 | 121 | void Ebml_SerializeUnsigned(EbmlGlobal *glob, unsigned long class_id, unsigned long ui); |
michael@0 | 122 | void Ebml_SerializeBinary(EbmlGlobal *glob, unsigned long class_id, unsigned long ui); |
michael@0 | 123 | diff --git a/WebMElement.c b/WebMElement.c |
michael@0 | 124 | index 2f79a3c..02eefa4 100644 |
michael@0 | 125 | --- a/WebMElement.c |
michael@0 | 126 | +++ b/WebMElement.c |
michael@0 | 127 | @@ -11,8 +11,12 @@ |
michael@0 | 128 | #include "EbmlIDs.h" |
michael@0 | 129 | #include "WebMElement.h" |
michael@0 | 130 | #include <stdio.h> |
michael@0 | 131 | +#include <stdint.h> |
michael@0 | 132 | +#include <stdlib.h> |
michael@0 | 133 | +#include <time.h> |
michael@0 | 134 | |
michael@0 | 135 | #define kVorbisPrivateMaxSize 4000 |
michael@0 | 136 | +#define UInt64 uint64_t |
michael@0 | 137 | |
michael@0 | 138 | void writeHeader(EbmlGlobal *glob) { |
michael@0 | 139 | EbmlLoc start; |
michael@0 | 140 | @@ -30,15 +34,16 @@ void writeHeader(EbmlGlobal *glob) { |
michael@0 | 141 | void writeSimpleBlock(EbmlGlobal *glob, unsigned char trackNumber, short timeCode, |
michael@0 | 142 | int isKeyframe, unsigned char lacingFlag, int discardable, |
michael@0 | 143 | unsigned char *data, unsigned long dataLength) { |
michael@0 | 144 | - Ebml_WriteID(glob, SimpleBlock); |
michael@0 | 145 | unsigned long blockLength = 4 + dataLength; |
michael@0 | 146 | + unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable; |
michael@0 | 147 | + Ebml_WriteID(glob, SimpleBlock); |
michael@0 | 148 | blockLength |= 0x10000000; // TODO check length < 0x0FFFFFFFF |
michael@0 | 149 | Ebml_Serialize(glob, &blockLength, sizeof(blockLength), 4); |
michael@0 | 150 | trackNumber |= 0x80; // TODO check track nubmer < 128 |
michael@0 | 151 | Ebml_Write(glob, &trackNumber, 1); |
michael@0 | 152 | // Ebml_WriteSigned16(glob, timeCode,2); //this is 3 bytes |
michael@0 | 153 | Ebml_Serialize(glob, &timeCode, sizeof(timeCode), 2); |
michael@0 | 154 | - unsigned char flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable; |
michael@0 | 155 | + flags = 0x00 | (isKeyframe ? 0x80 : 0x00) | (lacingFlag << 1) | discardable; |
michael@0 | 156 | Ebml_Write(glob, &flags, 1); |
michael@0 | 157 | Ebml_Write(glob, data, dataLength); |
michael@0 | 158 | } |
michael@0 | 159 | @@ -48,17 +53,18 @@ static UInt64 generateTrackID(unsigned int trackNumber) { |
michael@0 | 160 | UInt64 r = rand(); |
michael@0 | 161 | r = r << 32; |
michael@0 | 162 | r += rand(); |
michael@0 | 163 | - UInt64 rval = t ^ r; |
michael@0 | 164 | - return rval; |
michael@0 | 165 | +// UInt64 rval = t ^ r; |
michael@0 | 166 | + return t ^ r; |
michael@0 | 167 | } |
michael@0 | 168 | |
michael@0 | 169 | void writeVideoTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, |
michael@0 | 170 | char *codecId, unsigned int pixelWidth, unsigned int pixelHeight, |
michael@0 | 171 | double frameRate) { |
michael@0 | 172 | EbmlLoc start; |
michael@0 | 173 | + UInt64 trackID; |
michael@0 | 174 | Ebml_StartSubElement(glob, &start, TrackEntry); |
michael@0 | 175 | Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber); |
michael@0 | 176 | - UInt64 trackID = generateTrackID(trackNumber); |
michael@0 | 177 | + trackID = generateTrackID(trackNumber); |
michael@0 | 178 | Ebml_SerializeUnsigned(glob, TrackUID, trackID); |
michael@0 | 179 | Ebml_SerializeString(glob, CodecName, "VP8"); // TODO shouldn't be fixed |
michael@0 | 180 | |
michael@0 | 181 | @@ -78,9 +84,10 @@ void writeAudioTrack(EbmlGlobal *glob, unsigned int trackNumber, int flagLacing, |
michael@0 | 182 | char *codecId, double samplingFrequency, unsigned int channels, |
michael@0 | 183 | unsigned char *private, unsigned long privateSize) { |
michael@0 | 184 | EbmlLoc start; |
michael@0 | 185 | + UInt64 trackID; |
michael@0 | 186 | Ebml_StartSubElement(glob, &start, TrackEntry); |
michael@0 | 187 | Ebml_SerializeUnsigned(glob, TrackNumber, trackNumber); |
michael@0 | 188 | - UInt64 trackID = generateTrackID(trackNumber); |
michael@0 | 189 | + trackID = generateTrackID(trackNumber); |
michael@0 | 190 | Ebml_SerializeUnsigned(glob, TrackUID, trackID); |
michael@0 | 191 | Ebml_SerializeUnsigned(glob, TrackType, 2); // audio is always 2 |
michael@0 | 192 | // I am using defaults for thesed required fields |
michael@0 | 193 |