Beispiel #1
0
static void
test_resolve_metrolyrics (void)
{
  GrlSource *source;
  guint i;

  struct {
    gchar *title;
    gchar *artist;
    gchar *lyrics_file;
  } audios[] = {
   { "ring of fire", "johnny cash", LYRICS_RING_OF_FIRE },
   { "back it up", "caro emerald", LYRICS_BACK_IT_UP },
   { "bohemian rhapsody", "queen", LYRICS_BOHEMIAN_RHAPSODY },
   { "nobodys perfect", "jessie j", LYRICS_NOBODYS_PERFECT },
   { "100% pure love", "crystal waters", NULL },
  };

  source = test_lua_factory_get_source (METROLYRICS_ID, METROLYRICS_OPS);

  for (i = 0; i < G_N_ELEMENTS (audios); i++) {
    gchar *lyrics, *data;
    GFile *file;
    gsize size;
    GError *error = NULL;

    lyrics = get_lyrics (source, audios[i].artist, audios[i].title);
    if (audios[i].lyrics_file == NULL) {
        /* We are not interested in comparing this lyrics */
        g_clear_pointer (&lyrics, g_free);
        continue;
    }
    g_assert_nonnull (lyrics);

    file = g_file_new_for_uri (audios[i].lyrics_file);
    g_file_load_contents (file, NULL, &data, &size, NULL, &error);
    g_assert_no_error (error);
    g_clear_pointer (&file, g_object_unref);

    if (g_ascii_strncasecmp (lyrics, data, size - 1) != 0) {
      g_warning ("Lyrics of '%s' from '%s' changed. Check if metrolyrics.com changed",
                  audios[i].title, audios[i].artist);
    }
    g_clear_pointer (&lyrics, g_free);
    g_clear_pointer (&data, g_free);
  }
}
Beispiel #2
0
static void
test_resolve_metrolyrics_bad_request (void)
{
  GrlSource *source;
  guint i;

  struct {
    gchar *title;
    gchar *artist;
    gchar *lyrics_file;
  } audios[] = {
   { "GNOME", "grilo framework", NULL },
  };

  source = test_lua_factory_get_source (METROLYRICS_ID, METROLYRICS_OPS);

  for (i = 0; i < G_N_ELEMENTS (audios); i++) {
    gchar *lyrics;

    g_test_expect_message("Grilo", G_LOG_LEVEL_WARNING, "*Can't fetch element*");
    lyrics = get_lyrics (source, audios[i].artist, audios[i].title);
    g_assert_null (lyrics);
  }
}
Beispiel #3
0
int main(int argc, char **argv)
{
    FILE *file;
    char instruction;
    char* filename;
    struct vector instruction_stream;

    if(argc != 2)
    {
        /* wrong number of args */
        fprintf(stderr, "Error: exactly 1 HQ9+ source file as arg required\n");
        exit(EXIT_FAILURE);
    }

    /* open file */
    filename = argv[1];
    file = fopen(filename, "r");
    if (file == NULL)
    {
        /* could not open file */
        perror("Error opening file");
        exit(EXIT_FAILURE);
    }


    /*** prologue ***/
    vector_create(&instruction_stream, 100);
    char prologue [] = {
        0x55, // push %rbp
        0x48, 0x89, 0xE5, // mov %rsp, %rbp

        // backup %r12 (callee saved register)
        0x41, 0x54, // pushq %r12
        // store %rdi content (putchar) in %r12 as callee saved
        0x49, 0x89, 0xFC, // movq %rdi, %r12

        // push accumulator on stack
        0x6a, 0x00, // pushq $0
    };
    vector_push(&instruction_stream, prologue, sizeof(prologue));

    int stack_offset = -0x10; // offset from %rbp
    int offset_accumulator = stack_offset; // accumulator address: -0x10(%rbp)

    // hello world
    write_to_stack(&instruction_stream, "Hello World\n", &stack_offset);
    int offset_hello_world = stack_offset;

    // source code
    char* source_code = get_source_code(filename);
    write_to_stack(&instruction_stream, source_code, &stack_offset);
    free(source_code);
    int offset_source = stack_offset;

    // lyrics
    char* lyrics = get_lyrics(99);
    write_to_stack(&instruction_stream, lyrics, &stack_offset);
    free(lyrics);
    int offset_bottles = stack_offset;

    // everything after accumulator is text bytes
    int text_bytes_on_stack = -(stack_offset - offset_accumulator);


    /*** parse file ***/
    while((instruction = fgetc(file)) != EOF)
    {
        switch (instruction)
        {
            case 'H':
                {
                    // access single chars of int
                    char *hw = (char*) &offset_hello_world;
                    char opcodes [] = {
                        0xB0, 00, // movb $0, %al
                        0x48, 0x8D, 0xBD, hw[0], hw[1], hw[2], hw[3], // leaq -0x<offset>(%rbp),%rdi
                        0x41, 0xFF, 0xD4 // callq *%r12
                    };
                    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
                }
                break;

            case 'Q':
                {
                    // access single chars of int
                    char *s = (char*) &offset_source;
                    char opcodes [] = {
                        0xB0, 00, // movb $0, %al
                        0x48, 0x8D, 0xBD, s[0], s[1], s[2], s[3], // leaq -0x<offset>(%rbp),%rdi
                        0x41, 0xFF, 0xD4 // callq *%r12
                    };
                    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
                }
                break;

            case '9':
                {
                    // access single chars of int
                    char *b = (char*) &offset_bottles;
                    char opcodes [] = {
                        0xB0, 00, // movb $0, %al
                        0x48, 0x8D, 0xBD, b[0], b[1], b[2], b[3], // leaq -0x<offset>(%rbp),%rdi
                        // 0xBF, 0x39, 0x00, 0x00, 0x00, // mov $0x39, %edi
                        0x41, 0xFF, 0xD4 // callq *%r12
                    };
                    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
                }
                break;

            case '+':
                {
                    char *acc = (char*) &offset_accumulator;
                    char opcodes [] = {
                        // increment the accumulator
                        // TODO from variable instead of constant offset
                        0x48, 0xFF, 0x45, 0xF0, // incq -0x10(%rbp)
                    };
                    vector_push(&instruction_stream, opcodes, sizeof(opcodes));
                }
                break;
        }
    }
    if (!feof(file)) {
        perror("Error reading file");
    }
    fclose(file);


    /*** epilogue ***/
    // access single chars of long
    char *t = (char*) &text_bytes_on_stack;
    char epilogue [] = {
        // free strings
        0x48, 0x81, 0xC4, t[0], t[1], t[2], t[3], // addq $<x>, %rsp

        // free accumulator
        0x48, 0x83, 0xC4, 0x08, // addq $8, %rsp

        // restore callee saved register
        0x41, 0x5C, // popq %r12

        0x5d, // pop rbp
        0xC3 // ret
    };
    vector_push(&instruction_stream, epilogue, sizeof(epilogue));


    /*** invoke generated code ***/
    /* allocate and copy instruction stream into executable memory */
    void* mem = mmap(NULL, instruction_stream.size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    memcpy(mem, instruction_stream.data, instruction_stream.size);

    /* typecast memory to a function pointer and call the dynamically created executable code */
    void (*hq9p_program) (fn_printf) = mem;
    hq9p_program(printf);

    /* clear up */
    munmap(mem, instruction_stream.size);
    vector_destroy(&instruction_stream);

    exit(EXIT_SUCCESS);
}