@@ -12,12 +12,19 @@ import (
1212// XMLFile is an XML file expressed in binary format.
1313type XMLFile struct {
1414 stringPool * ResStringPool
15- resourceMap []uint32
1615 notPrecessedNS map [ResStringPoolRef ]ResStringPoolRef
1716 namespaces xmlNamespaces
1817 xmlBuffer bytes.Buffer
1918}
2019
20+ type InvalidReferenceError struct {
21+ Ref ResStringPoolRef
22+ }
23+
24+ func (e * InvalidReferenceError ) Error () string {
25+ return fmt .Sprintf ("androidbinary: invalid reference: 0x%08X" , e .Ref )
26+ }
27+
2128type (
2229 xmlNamespaces struct {
2330 l []namespaceVal
3037
3138func (x * xmlNamespaces ) add (key ResStringPoolRef , value ResStringPoolRef ) {
3239 x .l = append (x .l , namespaceVal {key : key , value : value })
33- return
3440}
3541
3642func (x * xmlNamespaces ) remove (key ResStringPoolRef ) {
@@ -41,7 +47,6 @@ func (x *xmlNamespaces) remove(key ResStringPoolRef) {
4147 return
4248 }
4349 }
44- return
4550}
4651
4752func (x * xmlNamespaces ) get (key ResStringPoolRef ) ResStringPoolRef {
@@ -164,10 +169,15 @@ func (f *XMLFile) readChunk(r io.ReaderAt, offset int64) (*ResChunkHeader, error
164169}
165170
166171// GetString returns a string referenced by ref.
172+ // It panics if the pool doesn't contain ref.
167173func (f * XMLFile ) GetString (ref ResStringPoolRef ) string {
168174 return f .stringPool .GetString (ref )
169175}
170176
177+ func (f * XMLFile ) HasString (ref ResStringPoolRef ) bool {
178+ return f .stringPool .HasString (ref )
179+ }
180+
171181func (f * XMLFile ) readStartNamespace (sr * io.SectionReader ) error {
172182 header := new (ResXMLTreeNode )
173183 if err := binary .Read (sr , binary .LittleEndian , header ); err != nil {
@@ -207,12 +217,24 @@ func (f *XMLFile) readEndNamespace(sr *io.SectionReader) error {
207217 return nil
208218}
209219
210- func (f * XMLFile ) addNamespacePrefix (ns , name ResStringPoolRef ) string {
220+ func (f * XMLFile ) addNamespacePrefix (ns , name ResStringPoolRef ) (string , error ) {
221+ if ! f .HasString (name ) {
222+ return "" , & InvalidReferenceError {Ref : name }
223+ }
224+
211225 if ns != NilResStringPoolRef {
212- prefix := f .GetString (f .namespaces .get (ns ))
213- return fmt .Sprintf ("%s:%s" , prefix , f .GetString (name ))
226+ ref := f .namespaces .get (ns )
227+ if ref == 0 {
228+ return "" , & InvalidReferenceError {Ref : ns }
229+ }
230+ if ! f .HasString (ref ) {
231+ return "" , & InvalidReferenceError {Ref : ref }
232+ }
233+ prefix := f .GetString (ref )
234+
235+ return fmt .Sprintf ("%s:%s" , prefix , f .GetString (name )), nil
214236 }
215- return f .GetString (name )
237+ return f .GetString (name ), nil
216238}
217239
218240func (f * XMLFile ) readStartElement (sr * io.SectionReader ) error {
@@ -229,7 +251,12 @@ func (f *XMLFile) readStartElement(sr *io.SectionReader) error {
229251 return nil
230252 }
231253
232- fmt .Fprintf (& f .xmlBuffer , "<%s" , f .addNamespacePrefix (ext .NS , ext .Name ))
254+ tag , err := f .addNamespacePrefix (ext .NS , ext .Name )
255+ if err != nil {
256+ return err
257+ }
258+ f .xmlBuffer .WriteString ("<" )
259+ f .xmlBuffer .WriteString (tag )
233260
234261 // output XML namespaces
235262 if f .notPrecessedNS != nil {
@@ -275,7 +302,11 @@ func (f *XMLFile) readStartElement(sr *io.SectionReader) error {
275302 }
276303 }
277304
278- fmt .Fprintf (& f .xmlBuffer , " %s=\" " , f .addNamespacePrefix (attr .NS , attr .Name ))
305+ name , err := f .addNamespacePrefix (attr .NS , attr .Name )
306+ if err != nil {
307+ return err
308+ }
309+ fmt .Fprintf (& f .xmlBuffer , " %s=\" " , name )
279310 xml .Escape (& f .xmlBuffer , []byte (value ))
280311 fmt .Fprint (& f .xmlBuffer , "\" " )
281312 offset += int64 (ext .AttributeSize )
@@ -296,6 +327,10 @@ func (f *XMLFile) readEndElement(sr *io.SectionReader) error {
296327 if err := binary .Read (sr , binary .LittleEndian , ext ); err != nil {
297328 return err
298329 }
299- fmt .Fprintf (& f .xmlBuffer , "</%s>" , f .addNamespacePrefix (ext .NS , ext .Name ))
330+ tag , err := f .addNamespacePrefix (ext .NS , ext .Name )
331+ if err != nil {
332+ return err
333+ }
334+ fmt .Fprintf (& f .xmlBuffer , "</%s>" , tag )
300335 return nil
301336}
0 commit comments