Ejemplo n.º 1
0
 public WorkbookStream InsertRecord(BiffRecord recordToInsert, BiffRecord insertAfterRecord = null)
 {
     return(InsertRecords(new List <BiffRecord>()
     {
         recordToInsert
     }, insertAfterRecord));
 }
Ejemplo n.º 2
0
        public long GetRecordByteOffset(BiffRecord record)
        {
            int listOffset = GetRecordOffset(record);

            //Size of BiffRecord is 4 (header) + Length
            return(_biffRecords.Take(listOffset).Sum(r => r.Length + 4));
        }
        public static string ToHexDumpString(this BiffRecord record, int maxLength = 0x10, bool showAttrInfo = false)
        {
            string biffString = record.ToString();

            //Skip the 4 byte header
            byte[] bytes         = record.GetBytes().Skip(4).ToArray();
            string hexDumpString = HexDump(bytes);

            if (record is Formula)
            {
                biffString = ((Formula)record).ToFormulaString(showAttrInfo);
            }
            else if (record.Id == RecordType.Dimensions)
            {
                biffString = record.AsRecordType <Dimensions>().ToString();
            }
            else if (record.Id == RecordType.Lbl)
            {
                biffString = ((Lbl)record).ToString();
            }


            if ((bytes.Length <= maxLength && bytes.Length > 0) ||
                record.Id == RecordType.Obj)
            {
                biffString += "\n" + hexDumpString;
            }

            return(biffString);
        }
Ejemplo n.º 4
0
        public WorkbookStream InitializeGlobalStreamLabels()
        {
            List <BoundSheet8> sheets = WbStream.GetAllRecordsByType <BoundSheet8>();

            BiffRecord lastCountryRecord = WbStream.GetAllRecordsByType <Country>().Last();

            SupBook     supBookRecord     = new SupBook(sheets.Count, 0x401);
            int         macroOffset       = sheets.TakeWhile(s => s.dt != BoundSheet8.SheetType.Macrosheet).Count();
            ExternSheet externSheetRecord = new ExternSheet(1, new List <XTI>()
            {
                new XTI(0, macroOffset, macroOffset)
            });

            if (WbStream.GetAllRecordsByType <SupBook>().Count > 0)
            {
                WbStream = WbStream.ReplaceRecord(WbStream.GetAllRecordsByType <SupBook>().First(), supBookRecord);
            }
            else
            {
                WbStream = WbStream.InsertRecord(supBookRecord, lastCountryRecord);
            }

            if (WbStream.GetAllRecordsByType <ExternSheet>().Count > 0)
            {
                WbStream = WbStream.InsertRecord(externSheetRecord, WbStream.GetAllRecordsByType <ExternSheet>().Last());
            }
            else
            {
                WbStream = WbStream.InsertRecord(externSheetRecord, supBookRecord);
            }

            return(WbStream);
        }
Ejemplo n.º 5
0
        public WorkbookStream InsertRecords(List <BiffRecord> recordsToInsert, BiffRecord insertAfterRecord = null)
        {
            if (insertAfterRecord == null)
            {
                List <BiffRecord> recordsWithAppendedRecord = _biffRecords.Concat(recordsToInsert).ToList();
                return(new WorkbookStream(recordsWithAppendedRecord));
            }

            if (ContainsRecord(insertAfterRecord) == false)
            {
                throw new ArgumentException("Could not find insertAfterRecord");
            }

            var insertRecordOffset = GetRecordOffset(insertAfterRecord) + 1;

            //records [r1, TARGET, r2, r3, r4, r5]
            //records.count = 6
            //insertRecordOffset = 2
            //records.Take(2) = [r1, TARGET]
            //records.TakeLast(4) = [r2, r3, r4, r5]
            //output = [r1, TARGET, INSERT, r2, r3, r4, r5]

            var newRecords = _biffRecords.Take(insertRecordOffset).Concat(recordsToInsert)
                             .Concat(_biffRecords.TakeLast(_biffRecords.Count - insertRecordOffset)).ToList();

            return(new WorkbookStream(newRecords));
        }
Ejemplo n.º 6
0
        public static List <BiffRecord> ParseBiffStreamBytes(byte[] bytes)
        {
            List <BiffRecord>   records = new List <BiffRecord>();
            MemoryStream        ms      = new MemoryStream(bytes);
            VirtualStreamReader vsr     = new VirtualStreamReader(ms);

            while (vsr.BaseStream.Position < vsr.BaseStream.Length)
            {
                RecordType id = (RecordType)vsr.ReadUInt16();

                if (id == 0)
                {
                    // Console.WriteLine("RecordID == 0 - stopping");
                    break;
                }


                UInt16 length = vsr.ReadUInt16();

                BiffRecord br = new BiffRecord(vsr, id, length);

                vsr.ReadBytes(length);
                records.Add(br);
            }

            return(records);
        }
Ejemplo n.º 7
0
        public WorkbookStream AddLabel(string label, Stack <AbstractPtg> rgce, bool isMacroStack = false)
        {
            /*
             * Labels require a reference to an XTI index which is used to say which
             * BoundSheet8 record maps to the appropriate tab. In order to make this
             * record we need a SupBook record, and ExternSheet record to specify
             * which BoundSheet8 record to use.
             *
             * Currently this assumes there are no SupBook or ExternSheet records in
             * use, handling of these cases for complex decoy docs is coming
             * in the future.
             *
             * TODO handle existing SupBook/ExternSheet records when adding Lbl entries
             */

            List <BoundSheet8> sheets               = WbStream.GetAllRecordsByType <BoundSheet8>();
            List <SupBook>     supBooksExisting     = WbStream.GetAllRecordsByType <SupBook>();
            List <ExternSheet> externSheetsExisting = WbStream.GetAllRecordsByType <ExternSheet>();

            ExternSheet lastExternSheet;

            if (supBooksExisting.Count > 0 || externSheetsExisting.Count > 0)
            {
                lastExternSheet = externSheetsExisting.Last();
            }
            else
            {
                BiffRecord lastCountryRecord = WbStream.GetAllRecordsByType <Country>().Last();

                SupBook     supBookRecord     = new SupBook(sheets.Count, 0x401);
                int         macroOffset       = sheets.TakeWhile(s => s.dt != BoundSheet8.SheetType.Macrosheet).Count();
                ExternSheet externSheetRecord = new ExternSheet(1, new List <XTI>()
                {
                    new XTI(0, macroOffset, macroOffset)
                });

                WbStream        = WbStream.InsertRecord(supBookRecord, lastCountryRecord);
                WbStream        = WbStream.InsertRecord(externSheetRecord, supBookRecord);
                lastExternSheet = externSheetRecord;
            }

            Lbl newLbl = new Lbl(label, 0);

            if (isMacroStack)
            {
                newLbl.fProc = true;
                newLbl.fFunc = true;
            }

            newLbl.SetRgce(rgce);

            WbStream = WbStream.InsertRecord(newLbl, lastExternSheet);
            WbStream = WbStream.FixBoundSheetOffsets();

            return(WbStream);
        }
Ejemplo n.º 8
0
        public FrtWrapper(IStreamReader reader, RecordType id, UInt16 length)
            : base(reader, id, length)
        {
            this.frtHeaderOld = new FrtHeaderOld(reader);

            this.wrappedRecord = BiffRecord.ReadRecord(reader);

            // skip padding bytes
            this.Reader.BaseStream.Position = this.Offset + this.Length;
        }
Ejemplo n.º 9
0
        private int GetRecordOffset(BiffRecord record)
        {
            if (ContainsRecord(record) == false)
            {
                throw new ArgumentException(string.Format("Could not find record {0}", record));
            }

            var recordOffset =
                _biffRecords.TakeWhile(r => r.Equals(record) == false).Count();

            return(recordOffset);
        }
Ejemplo n.º 10
0
        public static string ToHexDumpString(this BiffRecord record, int maxLength = 0x10, bool showAttrInfo = false, bool includeHeader = false)
        {
            string biffString = record.ToString();

            byte[] bytes = record.GetBytes();

            //Skip the 4 byte header if we aren't including the header
            if (includeHeader == false)
            {
                bytes = bytes.Skip(4).ToArray();
            }

            string hexDumpString = HexDump(bytes);

            if (record is Formula)
            {
                Formula f = (Formula)record;
                if (f.cce == 0 && f.RawBytesValue.Length != bytes.Length + 4)
                {
                    biffString = "!Error Parsing Formula!";
                }
                else
                {
                    biffString = f.ToFormulaString(showAttrInfo);
                }
            }
            else if (record.Id == RecordType.Dimensions)
            {
                biffString = record.AsRecordType <Dimensions>().ToString();
            }
            else if (record.Id == RecordType.Lbl)
            {
                try
                {
                    biffString = record.AsRecordType <Lbl>().ToString();
                }
                catch (Exception e)
                {
                    biffString = record.ToString();
                }
            }


            if ((bytes.Length <= maxLength && bytes.Length > 0) ||
                record.Id == RecordType.Obj)
            {
                biffString += "\n" + hexDumpString;
            }

            return(biffString);
        }
Ejemplo n.º 11
0
        public WorkbookStream RemoveRecord(BiffRecord recordToRemove)
        {
            if (ContainsRecord(recordToRemove) == false)
            {
                throw new ArgumentException("Could not find recordToRemove");
            }

            var removeRecordOffset = GetRecordOffset(recordToRemove);

            var newRecords = _biffRecords.Take(removeRecordOffset).Concat(
                _biffRecords.TakeLast(_biffRecords.Count - removeRecordOffset - 1)).ToList();

            return(new WorkbookStream(newRecords));
        }
Ejemplo n.º 12
0
        public void TestBiffRecordCloneAndGetBytes()
        {
            BoundSheet8 bs8 = new BoundSheet8(BoundSheet8.HiddenState.Visible, BoundSheet8.SheetType.Worksheet, "MySheetName");

            byte[]     bs8bytes       = bs8.GetBytes();
            BiffRecord bs8CloneRecord = (BiffRecord)bs8.Clone();

            byte[] bs8cloneBytes = bs8CloneRecord.GetBytes();
            Assert.AreEqual(bs8bytes, bs8cloneBytes);
            BoundSheet8 bs8Clone = bs8CloneRecord.AsRecordType <BoundSheet8>();

            byte[] bs8asRecordBytes = bs8Clone.GetBytes();
            Assert.AreEqual(bs8bytes, bs8asRecordBytes);
        }
Ejemplo n.º 13
0
        public static string ToHexDumpString(this BiffRecord record, int maxLength = 0x10)
        {
            string biffString = record.ToString();

            //Skip the 4 byte header
            byte[] bytes         = record.GetBytes().Skip(4).ToArray();
            string hexDumpString = HexDump(bytes);

            if ((bytes.Length <= maxLength && bytes.Length > 0) ||
                record.Id == RecordType.Obj)
            {
                biffString += "\n" + hexDumpString;
            }

            return(biffString);
        }
Ejemplo n.º 14
0
        public WorkbookStream AddLabel(string label, int rw, int col)
        {
            /*
             * Labels require a reference to an XTI index which is used to say which
             * BoundSheet8 record maps to the appropriate tab. In order to make this
             * record we need a SupBook record, and ExternSheet record to specify
             * which BoundSheet8 record to use.
             *
             * Currently this assumes there are no SupBook or ExternSheet records in
             * use, handling of these cases for complex decoy docs is coming
             * in the future.
             *
             * TODO handle existing SupBook/ExternSheet records when adding Lbl entries
             */

            List <BoundSheet8> sheets               = WbStream.GetAllRecordsByType <BoundSheet8>();
            List <SupBook>     supBooksExisting     = WbStream.GetAllRecordsByType <SupBook>();
            List <ExternSheet> externSheetsExisting = WbStream.GetAllRecordsByType <ExternSheet>();

            if (supBooksExisting.Count > 0 || externSheetsExisting.Count > 0)
            {
                throw new NotImplementedException("Use a Decoy Document with no Labels");
            }

            BiffRecord lastCountryRecord = WbStream.GetAllRecordsByType <Country>().Last();

            SupBook     supBookRecord     = new SupBook(sheets.Count, 0x401);
            int         macroOffset       = sheets.TakeWhile(s => s.dt != BoundSheet8.SheetType.Macrosheet).Count();
            ExternSheet externSheetRecord = new ExternSheet(1, new List <XTI>()
            {
                new XTI(0, macroOffset, macroOffset)
            });

            Stack <AbstractPtg> ptgStack = new Stack <AbstractPtg>();

            ptgStack.Push(new PtgRef3d(rw, col, 0));
            Lbl newLbl = new Lbl(label, 0);

            newLbl.SetRgce(ptgStack);

            WbStream = WbStream.InsertRecord(supBookRecord, lastCountryRecord);
            WbStream = WbStream.InsertRecord(externSheetRecord, supBookRecord);
            WbStream = WbStream.InsertRecord(newLbl, externSheetRecord);
            WbStream = WbStream.FixBoundSheetOffsets();

            return(WbStream);
        }
Ejemplo n.º 15
0
        public WorkbookStream SetMacroBinaryContent(byte[] payload, int rwStart, int colStart, int dstRwStart,
                                                    int dstColStart, SheetPackingMethod packingMethod = SheetPackingMethod.ObfuscatedCharFunc,
                                                    PayloadPackingMethod payloadPackingMethod         = PayloadPackingMethod.MatchSheetPackingMethod)
        {
            List <string>     payloadMacros;
            List <BiffRecord> formulasToAdd = new List <BiffRecord>();

            if (payloadPackingMethod == PayloadPackingMethod.MatchSheetPackingMethod)
            {
                payloadMacros = FormulaHelper.BuildPayloadMacros(payload);
                formulasToAdd.AddRange(FormulaHelper.ConvertStringsToRecords(payloadMacros, rwStart, colStart,
                                                                             dstRwStart, dstColStart, 15, packingMethod));
            }
            else if (payloadPackingMethod == PayloadPackingMethod.Base64)
            {
                payloadMacros = FormulaHelper.BuildBase64PayloadMacros(payload);
                formulasToAdd = FormulaHelper.ConvertBase64StringsToRecords(payloadMacros, rwStart, colStart);
            }

            WorkbookStream macroStream = GetMacroStream();

            try
            {
                BiffRecord lastFormulaInSheet = macroStream.GetAllRecordsByType <Formula>().Last();
                // If we are using base64 packing, we write STRING entries after our formulas, so check for that first
                if (payloadPackingMethod == PayloadPackingMethod.Base64)
                {
                    try
                    {
                        lastFormulaInSheet = macroStream.GetAllRecordsByType <STRING>().Last();
                    }
                    catch
                    {
                        lastFormulaInSheet = macroStream.GetAllRecordsByType <Formula>().Last();
                    }
                }
                WorkbookStream modifiedStream = WbStream.InsertRecords(formulasToAdd, lastFormulaInSheet);
                WbStream = modifiedStream;
                return(modifiedStream);
            }
            catch (Exception)
            {
                throw new ArgumentException(
                          "SetMacroBinaryContent must be called on a stream with at least 1 existing Formula Record");
            }
        }
Ejemplo n.º 16
0
        public GelFrame(IStreamReader reader, RecordType id, UInt16 length)
            : base(reader, id, length)
        {
            // assert that the correct record type is instantiated
            Debug.Assert(this.Id == ID);

            // copy data to a memory stream to cope with Continue records
            using (MemoryStream ms = new MemoryStream())
            {
                byte[] buffer = reader.ReadBytes(length);
                ms.Write(buffer, 0, length);

                if (BiffRecord.GetNextRecordType(reader) == RecordType.GelFrame)
                {
                    RecordType nextId     = (RecordType)reader.ReadUInt16();
                    UInt16     nextLength = reader.ReadUInt16();

                    buffer = reader.ReadBytes(nextLength);
                    ms.Write(buffer, 0, nextLength);
                }

                while (BiffRecord.GetNextRecordType(reader) == RecordType.Continue)
                {
                    RecordType nextId     = (RecordType)reader.ReadUInt16();
                    UInt16     nextLength = reader.ReadUInt16();

                    buffer = reader.ReadBytes(nextLength);
                    ms.Write(buffer, 0, nextLength);
                }

                ms.Position = 0;

                // initialize class members from stream
                this.OPT1 = Record.ReadRecord(ms);

                if (ms.Position < ms.Length)
                {
                    this.OPT2 = Record.ReadRecord(ms);
                }
            }

            // assert that the correct number of bytes has been read from the stream
            //Debug.Assert(this.Offset + this.Length == this.Reader.BaseStream.Position);
        }
Ejemplo n.º 17
0
        public TxORuns(IStreamReader reader, ushort cbRuns)
        {
            int noOfRuns = (cbRuns / 8) - 1;

            this.rgTxoRuns = new Run[noOfRuns];

            for (int i = 0; i < noOfRuns; i++)
            {
                if (i == 1028 && BiffRecord.GetNextRecordType(reader) == RecordType.Continue)
                {
                    // yet another Continue record to be parsed -> skip record header
                    ushort id   = reader.ReadUInt16();
                    ushort size = reader.ReadUInt16();
                }
                this.rgTxoRuns[i] = new Run(reader);
            }

            this.lastRun = new TxOLastRun(reader);
        }
Ejemplo n.º 18
0
        public static List <BiffRecord> ParseBiffStreamBytes(byte[] bytes)
        {
            List <BiffRecord>   records = new List <BiffRecord>();
            MemoryStream        ms      = new MemoryStream(bytes);
            VirtualStreamReader vsr     = new VirtualStreamReader(ms);

            while (vsr.BaseStream.Position < vsr.BaseStream.Length)
            {
                RecordType id     = (RecordType)vsr.ReadUInt16();
                UInt16     length = vsr.ReadUInt16();

                BiffRecord br = new BiffRecord(vsr, id, length);

                vsr.ReadBytes(length);
                records.Add(br);
            }

            return(records);
        }
Ejemplo n.º 19
0
        public static T AsRecordType <T>(this BiffRecord record) where T : BiffRecord
        {
            byte[] recordBytes = record.GetBytes();
            using (MemoryStream ms = new MemoryStream(recordBytes))
            {
                VirtualStreamReader vsr = new VirtualStreamReader(ms);
                RecordType          id  = (RecordType)vsr.ReadUInt16();
                ushort len             = vsr.ReadUInt16();
                var    typeConstructor = typeof(T).GetConstructor(new Type[]
                                                                  { typeof(IStreamReader), typeof(RecordType), typeof(ushort) });

                if (typeConstructor == null)
                {
                    throw new ArgumentException(string.Format("Could not find appropriate constructor for type {0}", typeof(T).FullName));
                }

                return((T)typeConstructor.Invoke(new object[] { vsr, id, len }));
            }
        }
Ejemplo n.º 20
0
        public static List <BiffRecord> UpdateGlobalsStreamReferences(List <BiffRecord> records)
        {
            List <Lbl>         labelRecords = records.Where(r => r.Id == RecordType.Lbl).Select(r => r.AsRecordType <Lbl>()).ToList();
            List <BoundSheet8> sheetRecords = records.Where(r => r.Id == RecordType.BoundSheet8).Select(r => r.AsRecordType <BoundSheet8>()).ToList();
            //Incorrect way to do this, but works for simpler cases - just pull the first ExternSheet record in the XLS file.
            BiffRecord firstExternSheet = records.FirstOrDefault(r => r.Id == RecordType.ExternSheet);

            List <BiffRecord> updatedRecords = new List <BiffRecord>();

            foreach (var record in records)
            {
                switch (record)
                {
                case Formula formulaRecord:
                    Stack <AbstractPtg> modifiedFormulaStack = UpdateNameRecords(formulaRecord.ptgStack, labelRecords);
                    if (firstExternSheet != null)
                    {
                        modifiedFormulaStack = UpdateSheetReferences(modifiedFormulaStack, sheetRecords,
                                                                     firstExternSheet.AsRecordType <ExternSheet>());
                    }
                    formulaRecord.SetCellParsedFormula(new CellParsedFormula(modifiedFormulaStack));
                    updatedRecords.Add(formulaRecord);
                    continue;

                case Lbl lblRecord:
                    Stack <AbstractPtg> modifiedLabelStack = UpdateNameRecords(lblRecord.rgce, labelRecords);
                    if (firstExternSheet != null)
                    {
                        modifiedLabelStack = UpdateSheetReferences(modifiedLabelStack, sheetRecords,
                                                                   firstExternSheet.AsRecordType <ExternSheet>());
                    }
                    lblRecord.SetRgce(modifiedLabelStack);
                    updatedRecords.Add(lblRecord);
                    continue;

                default:
                    updatedRecords.Add(record);
                    continue;
                }
            }
            return(updatedRecords);
        }
Ejemplo n.º 21
0
        public WorkbookStream AddFormula(Formula formula, PayloadPackingMethod payloadPackingMethod = PayloadPackingMethod.MatchSheetPackingMethod)
        {
            BiffRecord lastFormula = WbStream.GetAllRecordsByType <Formula>().Last();

            // If we are using base64 packing, we write STRING entries after our formulas, so check for that first
            if (payloadPackingMethod == PayloadPackingMethod.Base64)
            {
                try
                {
                    lastFormula = WbStream.GetAllRecordsByType <STRING>().Last();
                }
                catch
                {
                    lastFormula = WbStream.GetAllRecordsByType <Formula>().Last();
                }
            }

            WbStream = WbStream.InsertRecord(formula, lastFormula);
            WbStream = WbStream.FixBoundSheetOffsets();
            return(WbStream);
        }
Ejemplo n.º 22
0
        private bool IsEncryptedWorkbookStream(Stream stream)
        {
            bool flag = false;

            if ((stream != null) && (stream.Length != 0L))
            {
                BiffRecord record  = new BiffRecord();
                BiffRecord record2 = new BiffRecord();
                stream.Seek(20L, (SeekOrigin)SeekOrigin.Begin);
                BinaryReader reader = new BinaryReader(stream);
                record.Read(reader);
                stream.Seek(0x18L, (SeekOrigin)SeekOrigin.Begin);
                record2.Read(reader);
                if ((record.RecordType == BiffRecordNumber.FILEPASS) || (record2.RecordType == BiffRecordNumber.FILEPASS))
                {
                    flag = true;
                }
                stream.Seek(0L, (SeekOrigin)SeekOrigin.Begin);
            }
            return(flag);
        }
Ejemplo n.º 23
0
        public WorkbookStream ReplaceRecord(BiffRecord oldRecord, BiffRecord newRecord)
        {
            if (ContainsRecord(oldRecord) == false)
            {
                throw new ArgumentException("Could not find oldRecord");
            }

            //records [r1, OLD, r2, r3, r4, r5]
            //records.count = 6
            //replaceRecordOffset = 1
            //records.Take(1) = [r1]
            //records.TakeLast(4) = [r2, r3, r4, r5]
            //output = [r1, NEW, r2, r3, r4, r5]

            var replaceRecordOffset = GetRecordOffset(oldRecord);

            var newRecords = _biffRecords.Take(replaceRecordOffset).Append(newRecord)
                             .Concat(_biffRecords.TakeLast(_biffRecords.Count - (replaceRecordOffset + 1))).ToList();

            return(new WorkbookStream(newRecords));
        }
Ejemplo n.º 24
0
        public void TestRemoveRecord()
        {
            byte[]         wbBytes = TestHelpers.GetMacroTestBytes();
            WorkbookStream wbs     = new WorkbookStream(wbBytes);

            BiffRecord     haltRecord = wbs.GetAllRecordsByType <Formula>().Last();
            List <Formula> formulas   = wbs.GetAllRecordsByType <Formula>();

            Assert.AreEqual(3, formulas.Count);
            wbs = wbs.RemoveRecord(haltRecord);

            formulas = wbs.GetAllRecordsByType <Formula>();
            Assert.AreEqual(2, formulas.Count);

            foreach (var formula in formulas)
            {
                List <AbstractPtg> ptgs  = formula.ptgStack.ToList();
                List <PtgFunc>     funcs = ptgs.Where(p => p.Id == PtgNumber.PtgFunc).Cast <PtgFunc>().ToList();
                bool haltFunctionExists  = funcs.Any(func => func.Ftab == FtabValues.HALT);
                Assert.AreEqual(false, haltFunctionExists);
            }
        }
Ejemplo n.º 25
0
        public Pls(IStreamReader reader, RecordType id, ushort length)
            : base(reader, id, length)
        {
            // assert that the correct record type is instantiated
            Debug.Assert(this.Id == ID);

            using (var ms = new MemoryStream())
            {
                var buffer = reader.ReadBytes(length);
                ms.Write(buffer, 0, length);

                while (BiffRecord.GetNextRecordType(reader) == RecordType.Pls)
                {
                    var    nextId     = (RecordType)reader.ReadUInt16();
                    ushort nextLength = reader.ReadUInt16();

                    buffer = reader.ReadBytes(nextLength);
                    ms.Write(buffer, 0, nextLength);
                }

                while (BiffRecord.GetNextRecordType(reader) == RecordType.Continue)
                {
                    var    nextId     = (RecordType)reader.ReadUInt16();
                    ushort nextLength = reader.ReadUInt16();

                    buffer = reader.ReadBytes(nextLength);
                    ms.Write(buffer, 0, nextLength);
                }

                ms.Position = 0;

                // initialize class members from stream
                this.rgb = new byte[ms.Length];
                ms.Read(this.rgb, 0, (int)ms.Length);

                // assert that the correct number of bytes has been read from the stream
                //Debug.Assert(this.Offset + this.Length == this.Reader.BaseStream.Position);
            }
        }
Ejemplo n.º 26
0
        public void TestLongMacroImport()
        {
            List <String> simpleMacros = new List <string>();

            for (int cell = 0; cell < 50; cell += 1)
            {
                string cellContent = "";
                for (int i = 0; i < 0x1000; i += 1)
                {
                    cellContent += "A";
                }
                simpleMacros.Add(cellContent);
            }


            List <BiffRecord> records = FormulaHelper.ConvertStringsToRecords(simpleMacros, 0, 0xA0, 0, 0);

            BiffRecord firstGoto        = records.Cast <Formula>().Last(f => f.col == 0xa0);
            BiffRecord secondColRecord1 = records.Cast <Formula>().First(f => f.col == 0xa1);

            Assert.IsNotNull(firstGoto);
            Assert.IsNotNull(secondColRecord1);
        }
Ejemplo n.º 27
0
        public WorkbookStream SetMacroBinaryContent(byte[] payload, int rwStart, int colStart, int dstRwStart,
                                                    int dstColStart, SheetPackingMethod packingMethod = SheetPackingMethod.ObfuscatedCharFunc)
        {
            List <string>     payloadMacros = FormulaHelper.BuildPayloadMacros(payload);
            List <BiffRecord> formulasToAdd = new List <BiffRecord>();

            formulasToAdd.AddRange(FormulaHelper.ConvertStringsToRecords(payloadMacros, rwStart, colStart, dstRwStart, dstColStart, 15, packingMethod));

            WorkbookStream macroStream = GetMacroStream();

            try
            {
                BiffRecord     lastFormulaInSheet = macroStream.GetAllRecordsByType <Formula>().Last();
                WorkbookStream modifiedStream     = WbStream.InsertRecords(formulasToAdd, lastFormulaInSheet);
                WbStream = modifiedStream;
                return(modifiedStream);
            }
            catch (Exception)
            {
                throw new ArgumentException(
                          "SetMacroBinaryContent must be called on a stream with at least 1 existing Formula Record");
            }
        }
Ejemplo n.º 28
0
        public void TestGetDefaultMacroSheetInternationalized()
        {
            Intl manuallyCreatedIntlRecord = new Intl();

            byte[] intlBytes = manuallyCreatedIntlRecord.GetBytes();

            BiffRecord rec = new BiffRecord(intlBytes);

            Intl convertedRecord = rec.AsRecordType <Intl>();

            Assert.AreEqual(convertedRecord.GetBytes(), manuallyCreatedIntlRecord.GetBytes());

            WorkbookStream    wbs          = TestHelpers.GetDefaultMacroTemplate();
            List <BiffRecord> sheetRecords = wbs.GetRecordsForBOFRecord(wbs.GetAllRecordsByType <BOF>().Last());

            WorkbookStream internationalWbs = new WorkbookStream(sheetRecords);
            var            intlRecord       = new Intl();

            internationalWbs = internationalWbs.InsertRecord(intlRecord, internationalWbs.GetAllRecordsByType <b2xtranslator.Spreadsheet.XlsFileFormat.Records.Index>().First());
            Assert.IsTrue(internationalWbs.ContainsRecord(intlRecord));
            var nextRecord = internationalWbs.Records.SkipWhile(r => r.Id != RecordType.Intl).Skip(1).Take(1).First();

            Assert.IsTrue(nextRecord.Id == RecordType.CalcMode);
        }
Ejemplo n.º 29
0
        public bool ContainsRecord(BiffRecord record)
        {
            var matchingRecordTypes = _biffRecords.Where(r => r.Id == record.Id).ToList();

            return(matchingRecordTypes.Any(r => r.Equals(record)));
        }
Ejemplo n.º 30
0
        public TxO(IStreamReader reader, RecordType id, UInt16 length)
            : base(reader, id, length)
        {
            // assert that the correct record type is instantiated
            Debug.Assert(this.Id == ID);

            long startPosition = this.Reader.BaseStream.Position;

            // NOTE: controlInfo is an option field that exists if and only if the value of
            //   cmo.ot in the preceding Obj record is 0, 5, 7, 11, 12 or 14.
            //   However, the current parser implementation does not allow us to see the preceding
            //   record(s) witout an enormous recactoring. Therefore we're a little bit hacky here
            //   and try to read the record first without the optional field. If we didn't succeed
            //   we start a second try, this time including the optional field.
            //
            for (int noOfTries = 1; noOfTries < 3; noOfTries++)
            {
                // initialize class members from stream
                UInt16 flags = reader.ReadUInt16();
                this.hAlignment = (HorizontalAlignment)Utils.BitmaskToInt(flags, 0xE);
                this.vAlignment = (VerticalAlignment)Utils.BitmaskToInt(flags, 0x70);
                this.rot        = (TextRotation)reader.ReadUInt16();
                reader.ReadBytes(6); // reserved

                // read optional field controlInfo on second try
                if (noOfTries == 2)
                {
                    this.controlInfo = new ControlInfo(reader);
                }

                this.cchText   = reader.ReadUInt16();
                this.cbRuns    = reader.ReadUInt16();
                this.ifntEmpty = reader.ReadUInt16();
                this.fmla      = new ObjFmla(reader);

                if (this.Offset + this.Length == this.Reader.BaseStream.Position)
                {
                    break;
                }
                else if (noOfTries == 1)
                {
                    // re-read record, this time including the optional controlInfo field
                    this.Reader.BaseStream.Position = startPosition;
                }
            }

            // assert that the correct number of bytes has been read from the stream
            Debug.Assert(this.Offset + this.Length == this.Reader.BaseStream.Position);

            // NOTE: If the field cchText is not zero, this record doesn‘t fully specify the text.
            //  The rest of the data that MUST be specified is the text string and the formatting runs
            //  information.
            //
            if (this.cchText > 0 && BiffRecord.GetNextRecordType(reader) == RecordType.Continue)
            {
                // skip record header
                reader.ReadUInt16();
                reader.ReadUInt16();

                this.text = new XLUnicodeStringNoCch(reader, this.cchText);
                if (BiffRecord.GetNextRecordType(reader) == RecordType.Continue)
                {
                    // skip record header
                    reader.ReadUInt16();
                    reader.ReadUInt16();

                    this.runs = new TxORuns(reader, this.cbRuns);
                }
            }
        }