tlsa / libcyaml

C library for reading and writing YAML.
ISC License
258 stars 56 forks source link

Long string causing `malloc(): invalid next size (unsorted)` #223

Closed freeze-dolphin closed 9 months ago

freeze-dolphin commented 9 months ago

Here is my schema:

```c #ifndef ETOILE_SCHEM_PROJ_H #define ETOILE_SCHEM_PROJ_H #include "utils.h" #include typedef enum side { CONFLICT = 0, LIGHT = 1, COLORLESS = 2 } side_t; typedef struct skin { side_t side; } skin_t; typedef struct arcpkg_chart { const char *chart_path; const char *audio_path; const char *jacket_path; const char *bpm_text; const char *bg; const char *title; const char *charter; const char *artist; const char *illustrator; unsigned int base_bpm; skin_t skin; unsigned long preview; unsigned long preview_end; float chart_constant; } arcpkg_chart_t; typedef struct arcpkg_proj_setting { arcpkg_chart_t *charts; uint64_t charts_count; } arcpkg_proj_setting_t; static const cyaml_strval_t side_strings[] = { {"conflict", CONFLICT}, {"light", LIGHT}, {"colorless", COLORLESS}, }; static const cyaml_schema_field_t skin_fields_schema[] = { CYAML_FIELD_ENUM( "side", CYAML_FLAG_OPTIONAL, skin_t, side, side_strings, CYAML_ARRAY_LEN(side_strings)), CYAML_FIELD_END }; static const cyaml_schema_field_t chart_fields_schema[] = { CYAML_FIELD_STRING_PTR( "chartPath", CYAML_FLAG_POINTER, arcpkg_chart_t, chart_path, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "audioPath", CYAML_FLAG_POINTER, arcpkg_chart_t, audio_path, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "jacketPath", CYAML_FLAG_POINTER, arcpkg_chart_t, jacket_path, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "bpmText", CYAML_FLAG_POINTER, arcpkg_chart_t, bpm_text, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "backgroundPath", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, arcpkg_chart_t, bg, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "title", CYAML_FLAG_POINTER, arcpkg_chart_t, title, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "alias", CYAML_FLAG_POINTER, arcpkg_chart_t, charter, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "composer", CYAML_FLAG_POINTER, arcpkg_chart_t, artist, 0, CYAML_UNLIMITED), CYAML_FIELD_STRING_PTR( "illustrator", CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL, arcpkg_chart_t, illustrator, 0, CYAML_UNLIMITED), CYAML_FIELD_UINT("baseBpm", CYAML_FLAG_DEFAULT, arcpkg_chart_t, base_bpm), CYAML_FIELD_MAPPING("skin", CYAML_FLAG_OPTIONAL, arcpkg_chart_t, skin, skin_fields_schema), CYAML_FIELD_UINT("previewStart", CYAML_FLAG_DEFAULT, arcpkg_chart_t, preview), CYAML_FIELD_UINT("previewEnd", CYAML_FLAG_DEFAULT, arcpkg_chart_t, preview_end), CYAML_FIELD_FLOAT("chartConstant", CYAML_FLAG_DEFAULT, arcpkg_chart_t, chart_constant), CYAML_FIELD_END }; static const cyaml_schema_value_t chart_schema = { CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT, arcpkg_chart_t, chart_fields_schema), }; static const cyaml_schema_field_t proj_fields_schema[] = { CYAML_FIELD_IGNORE("lastOpenedChartPath", CYAML_FLAG_OPTIONAL), CYAML_FIELD_SEQUENCE("charts", CYAML_FLAG_POINTER, arcpkg_proj_setting_t, charts, &chart_schema, 0, 4), CYAML_FIELD_END }; static const cyaml_schema_value_t proj_schema = { CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER, arcpkg_proj_setting_t, proj_fields_schema), }; #endif //ETOILE_SCHEM_PROJ_H ```

And when I was processing this yaml:

lastOpenedChartPath: 2.aff
charts:
- chartPath: 2.aff
  audioPath: base.ogg
  jacketPath: base.jpg
  baseBpm: 180
  bpmText: 180
  syncBaseBpm: true
  backgroundPath: arccreate_vs_conflict (3).jpg
  title: Anti the EuphoriaHOLiC
  composer: cosMo@暴走P
  charter: Arcthesia
  alias: ∞I CAN'T FUCKING MAKE STREAMS∞
  illustrator: syuri22
  difficulty: Future 10
  chartConstant: 10.5
  difficultyColor: '#482B54FF'
  skin:
    side: conflict
  lastWorkingTiming: 74647
  previewStart: 50480
  previewEnd: 76467
  searchTags: ''

I found that the program kept crashing with malloc(): invalid next size (unsorted).

I tried shorten the string field alias (it looks very suspicious...).

After cutting it in half like this:

  alias: ∞I CAN'T FUCKING

Then the program ran normally.

And I'm just wondering why... I have set the CYAML_UNLIMITED for this field.


Here is the output with the log level debug:

``` libcyaml: DEBUG: Load: POP[0]: start libcyaml: DEBUG: Load: PUSH[0]: start libcyaml: DEBUG: Load: Event: STREAM_START libcyaml: DEBUG: Load: Handle state start libcyaml: DEBUG: Load: PUSH[1]: in stream libcyaml: DEBUG: Load: Event: DOC_START libcyaml: DEBUG: Load: Handle state in stream libcyaml: DEBUG: Load: PUSH[2]: in doc libcyaml: DEBUG: Load: Event: MAPPING_START libcyaml: DEBUG: Load: Handle state in doc libcyaml: DEBUG: Load: Reading value of type 'MAPPING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e716020 (0 + 16 bytes) libcyaml: DEBUG: Load: PUSH[3]: in mapping (key) libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [lastOpenedChartPath] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'IGNORE' libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [charts] libcyaml: DEBUG: Load: Event: SEQUENCE_START libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'SEQUENCE' (pointer) libcyaml: DEBUG: Load: PUSH[4]: in sequence libcyaml: DEBUG: Load: Event: MAPPING_START libcyaml: DEBUG: Load: Handle state in sequence libcyaml: DEBUG: Load: Allocation: 0x55846e71a5c0 (0 + 104 bytes) libcyaml: DEBUG: Load: Sequence entry: 0 (104 bytes) libcyaml: DEBUG: Load: Reading value of type 'MAPPING' libcyaml: DEBUG: Load: PUSH[5]: in mapping (key) libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [chartPath] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e716180 (0 + 6 bytes) libcyaml: INFO: Load: <2.aff> libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [audioPath] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e716240 (0 + 9 bytes) libcyaml: INFO: Load: libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [jacketPath] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e715fd0 (0 + 9 bytes) libcyaml: INFO: Load: libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [baseBpm] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'UINT' libcyaml: INFO: Load: <180> libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [bpmText] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e715f10 (0 + 4 bytes) libcyaml: INFO: Load: <180> libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [syncBaseBpm] libcyaml: DEBUG: Load: Ignoring key: syncBaseBpm libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [backgroundPath] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e71a590 (0 + 30 bytes) libcyaml: INFO: Load: libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [title] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e71a570 (0 + 23 bytes) libcyaml: INFO: Load: libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [composer] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e716090 (0 + 14 bytes) libcyaml: INFO: Load: libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [charter] libcyaml: DEBUG: Load: Ignoring key: charter libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [alias] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e71a330 (0 + 35 bytes) libcyaml: INFO: Load: <∞I CAN'T FUCKING MAKE STREAMS∞> libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [illustrator] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'STRING' (pointer) libcyaml: DEBUG: Load: Allocation: 0x55846e715530 (0 + 8 bytes) libcyaml: INFO: Load: libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [difficulty] libcyaml: DEBUG: Load: Ignoring key: difficulty libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [chartConstant] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'FLOAT' libcyaml: INFO: Load: <10.5> libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [difficultyColor] libcyaml: DEBUG: Load: Ignoring key: difficultyColor libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [skin] libcyaml: DEBUG: Load: Event: MAPPING_START libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'MAPPING' libcyaml: DEBUG: Load: PUSH[6]: in mapping (key) libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [side] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'ENUM' libcyaml: INFO: Load: libcyaml: DEBUG: Load: Event: MAPPING_END libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: DEBUG: Load: POP[6]: in mapping (key) libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [lastWorkingTiming] libcyaml: DEBUG: Load: Ignoring key: lastWorkingTiming libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [previewStart] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'UINT' libcyaml: INFO: Load: <50480> libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [previewEnd] libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (value) libcyaml: DEBUG: Load: Reading value of type 'UINT' libcyaml: INFO: Load: <76467> libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: INFO: Load: [searchTags] libcyaml: DEBUG: Load: Ignoring key: searchTags libcyaml: DEBUG: Load: Event: SCALAR libcyaml: DEBUG: Load: Event: MAPPING_END libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: DEBUG: Load: POP[5]: in mapping (key) libcyaml: DEBUG: Load: Event: SEQUENCE_END libcyaml: DEBUG: Load: Handle state in sequence libcyaml: DEBUG: Load: Sequence count: 1 libcyaml: DEBUG: Load: POP[4]: in sequence libcyaml: DEBUG: Load: Event: MAPPING_END libcyaml: DEBUG: Load: Handle state in mapping (key) libcyaml: DEBUG: Load: POP[3]: in mapping (key) libcyaml: DEBUG: Load: Event: DOC_END libcyaml: DEBUG: Load: Handle state in doc libcyaml: DEBUG: Load: POP[2]: in doc libcyaml: DEBUG: Load: Event: STREAM_END libcyaml: DEBUG: Load: Handle state in stream libcyaml: DEBUG: Load: POP[1]: in stream libcyaml: DEBUG: Load: POP[0]: start malloc(): invalid next size (unsorted) ```
freeze-dolphin commented 9 months ago

I think the length of the string may not be to blame for the problem.
As we could see the debug log has contained the whole string.

libcyaml:   DEBUG: Load: Event: SCALAR
libcyaml:   DEBUG: Load: Handle state in mapping (value)
libcyaml:   DEBUG: Load: Reading value of type 'STRING' (pointer)
libcyaml:   DEBUG: Load: Allocation: 0x55846e71a330 (0 + 35 bytes)
libcyaml:    INFO: Load:   <∞I CAN'T FUCKING MAKE STREAMS∞>

But why? Why does it work when the string was cut?

freeze-dolphin commented 9 months ago

image

I found out that this is not the duty of libcyaml, it's another lib: zip