@@ -77,34 +77,62 @@ std::string CgBinaryDisasm::GetCgParamValue(u32 offset, u32 end_offset) const
7777 return fmt::format (" num %d " , num) + offsets;
7878}
7979
80- void CgBinaryDisasm::ConvertToLE (CgBinaryProgram& prog)
80+ bool CgBinaryDisasm::ConvertToLE (CgBinaryProgram& prog)
8181{
8282 // BE payload, requires that data be swapped
8383 const auto be_profile = prog.profile ;
8484
8585 auto swap_be32 = [&](u32 start_offset, size_t size_bytes)
8686 {
87+ if (static_cast <usz>(start_offset) > m_buffer.size ()
88+ || size_bytes > m_buffer.size () - start_offset
89+ || start_offset % alignof (u32 )
90+ || size_bytes % sizeof (u32 ))
91+ {
92+ return false ;
93+ }
94+
8795 auto start = reinterpret_cast <u32 *>(m_buffer.data () + start_offset);
8896 auto end = reinterpret_cast <u32 *>(m_buffer.data () + start_offset + size_bytes);
8997
9098 for (auto data = start; data < end; ++data)
9199 {
92100 *data = std::bit_cast<be_t <u32 >>(*data);
93101 }
102+
103+ return true ;
94104 };
95105
96106 // 1. Swap the header
97- swap_be32 (0 , sizeof (CgBinaryProgram));
107+ if (!swap_be32 (0 , sizeof (CgBinaryProgram)))
108+ {
109+ return false ;
110+ }
98111
99112 // 2. Swap parameters
100- swap_be32 (prog.parameterArray , sizeof (CgBinaryParameter) * prog.parameterCount );
113+ if (static_cast <usz>(prog.parameterCount ) > static_cast <usz>(umax) / sizeof (CgBinaryParameter)
114+ || !swap_be32 (prog.parameterArray , sizeof (CgBinaryParameter) * prog.parameterCount ))
115+ {
116+ return false ;
117+ }
101118
102119 // 3. Swap the ucode
103- swap_be32 (prog.ucode , m_buffer.size () - prog.ucode );
120+ if (static_cast <usz>(prog.ucode ) > m_buffer.size ()
121+ || !swap_be32 (prog.ucode , m_buffer.size () - prog.ucode ))
122+ {
123+ return false ;
124+ }
104125
105126 // 4. Swap the domain header
106127 if (be_profile == 7004u )
107128 {
129+ if (static_cast <usz>(prog.program ) > m_buffer.size ()
130+ || sizeof (CgBinaryFragmentProgram) > m_buffer.size () - prog.program
131+ || prog.program % alignof (u32 ))
132+ {
133+ return false ;
134+ }
135+
108136 // Need to swap each field individually
109137 auto & fprog = GetCgRef<CgBinaryFragmentProgram>(prog.program );
110138 fprog.instructionCount = std::bit_cast<be_t <u32 >>(fprog.instructionCount );
@@ -117,20 +145,34 @@ void CgBinaryDisasm::ConvertToLE(CgBinaryProgram& prog)
117145 else
118146 {
119147 // Swap entire header block as all fields are u32
120- swap_be32 (prog.program , sizeof (CgBinaryVertexProgram));
148+ if (!swap_be32 (prog.program , sizeof (CgBinaryVertexProgram)))
149+ {
150+ return false ;
151+ }
121152 }
153+
154+ return true ;
122155}
123156
124157void CgBinaryDisasm::BuildShaderBody (bool include_glsl)
125158{
126159 ParamArray param_array;
127160
161+ if (m_buffer.size () < sizeof (CgBinaryProgram))
162+ {
163+ return ;
164+ }
165+
128166 auto & prog = GetCgRef<CgBinaryProgram>(0 );
129167
130168 if (const u32 be_profile = std::bit_cast<be_t <u32 >>(prog.profile );
131169 be_profile == 7003u || be_profile == 7004u )
132170 {
133- ConvertToLE (prog);
171+ if (!ConvertToLE (prog))
172+ {
173+ return ;
174+ }
175+
134176 ensure (be_profile == prog.profile );
135177 }
136178
0 commit comments