You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.7 KiB

  1. // Copyright (c) 2016 Marty Schoch
  2. // Licensed under the Apache License, Version 2.0 (the "License");
  3. // you may not use this file except in compliance with the
  4. // License. You may obtain a copy of the License at
  5. // http://www.apache.org/licenses/LICENSE-2.0
  6. // Unless required by applicable law or agreed to in writing,
  7. // software distributed under the License is distributed on an "AS
  8. // IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  9. // express or implied. See the License for the specific language
  10. // governing permissions and limitations under the License.
  11. package smat
  12. // ActionSeq represents a sequence of actions, used for populating a corpus
  13. // of byte sequences for the corresponding fuzz tests
  14. type ActionSeq []ActionID
  15. // ByteEncoding runs the FSM to produce a byte sequence to trigger the
  16. // desired action
  17. func (a ActionSeq) ByteEncoding(ctx Context, setup, teardown ActionID, actionMap ActionMap) ([]byte, error) {
  18. setupFunc, teardownFunc, err := actionMap.findSetupTeardown(setup, teardown)
  19. if err != nil {
  20. return nil, err
  21. }
  22. state, err := setupFunc(ctx)
  23. if err != nil {
  24. return nil, err
  25. }
  26. defer func() {
  27. _, _ = teardownFunc(ctx)
  28. }()
  29. var rv []byte
  30. for _, actionID := range a {
  31. b, err := probeStateForAction(state, actionID)
  32. if err != nil {
  33. return nil, err
  34. }
  35. rv = append(rv, b)
  36. action, ok := actionMap[actionID]
  37. if !ok {
  38. continue
  39. }
  40. state, err = action(ctx)
  41. if err != nil {
  42. return nil, err
  43. }
  44. }
  45. return rv, nil
  46. }
  47. func probeStateForAction(state State, actionID ActionID) (byte, error) {
  48. for i := 0; i < 256; i++ {
  49. nextActionID := state(byte(i))
  50. if nextActionID == actionID {
  51. return byte(i), nil
  52. }
  53. }
  54. return 0, ErrActionNotPossible
  55. }